From 7915d064a2d0740face4845dc0d8ea3732f236fb Mon Sep 17 00:00:00 2001 From: Pierre Guillot Date: Thu, 30 Jan 2020 11:46:37 +0100 Subject: [PATCH] SONAR-13001 create endpoint alm_integrations/set_pat --- .../java/org/sonar/db/version/SqTables.java | 1 + .../src/main/java/org/sonar/db/DaoModule.java | 2 + .../src/main/java/org/sonar/db/DbClient.java | 8 + .../src/main/java/org/sonar/db/MyBatis.java | 2 + .../java/org/sonar/db/alm/pat/AlmPatDao.java | 75 +++++++++ .../java/org/sonar/db/alm/pat/AlmPatDto.java | 82 ++++++++++ .../org/sonar/db/alm/pat/AlmPatMapper.java | 42 +++++ .../org/sonar/db/alm/pat/package-info.java | 24 +++ .../sonar/db/alm/setting/AlmSettingDto.java | 2 +- .../org/sonar/db/alm/pat/AlmPatMapper.xml | 75 +++++++++ server/sonar-db-dao/src/schema/schema-sq.ddl | 11 ++ .../test/java/org/sonar/db/DaoModuleTest.java | 2 +- .../org/sonar/db/alm/pat/ALMPatDaoTest.java | 152 ++++++++++++++++++ .../java/org/sonar/db/DbTester.java | 7 + .../alm/integration/pat/AlmPatsDbTester.java | 49 ++++++ .../alm/integration/pat/AlmPatsTesting.java | 36 +++++ .../version/v82/CreateAlmPatsTable.java | 98 +++++++++++ .../db/migration/version/v82/DbVersion82.java | 3 +- .../version/v82/CreateAlmPATsTableTest.java | 63 ++++++++ .../version/v82/DbVersion82Test.java | 2 +- 20 files changed, 732 insertions(+), 4 deletions(-) create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDao.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDto.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatMapper.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/package-info.java create mode 100644 server/sonar-db-dao/src/main/resources/org/sonar/db/alm/pat/AlmPatMapper.xml create mode 100644 server/sonar-db-dao/src/test/java/org/sonar/db/alm/pat/ALMPatDaoTest.java create mode 100644 server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsDbTester.java create mode 100644 server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsTesting.java create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPatsTable.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPATsTableTest.java 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 1cc30304e5d..5dd185823aa 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 @@ -54,6 +54,7 @@ public final class SqTables { "active_rule_parameters", "alm_app_installs", "alm_settings", + "alm_pats", "analysis_properties", "ce_activity", "ce_queue", 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 9cf5de73ba4..05637e31fc6 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 @@ -26,6 +26,7 @@ import org.sonar.core.platform.Module; import org.sonar.db.alm.AlmAppInstallDao; import org.sonar.db.alm.OrganizationAlmBindingDao; import org.sonar.db.alm.ProjectAlmBindingDao; +import org.sonar.db.alm.pat.AlmPatDao; import org.sonar.db.alm.setting.AlmSettingDao; import org.sonar.db.alm.setting.ProjectAlmSettingDao; import org.sonar.db.ce.CeActivityDao; @@ -119,6 +120,7 @@ public class DaoModule extends Module { GroupPermissionDao.class, AlmAppInstallDao.class, AlmSettingDao.class, + AlmPatDao.class, ProjectAlmSettingDao.class, ProjectAlmBindingDao.class, InternalComponentPropertiesDao.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 9707a025944..1ca65d852ae 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 @@ -24,6 +24,7 @@ import java.util.Map; import org.sonar.db.alm.AlmAppInstallDao; import org.sonar.db.alm.OrganizationAlmBindingDao; import org.sonar.db.alm.ProjectAlmBindingDao; +import org.sonar.db.alm.pat.AlmPatDao; import org.sonar.db.alm.setting.AlmSettingDao; import org.sonar.db.alm.setting.ProjectAlmSettingDao; import org.sonar.db.ce.CeActivityDao; @@ -103,6 +104,7 @@ public class DbClient { private final PropertiesDao propertiesDao; private final AlmAppInstallDao almAppInstallDao; private final AlmSettingDao almSettingDao; + private final AlmPatDao almPatDao; private final ProjectAlmSettingDao projectAlmSettingDao; private final ProjectAlmBindingDao projectAlmBindingDao; private final InternalComponentPropertiesDao internalComponentPropertiesDao; @@ -172,6 +174,7 @@ public class DbClient { } almAppInstallDao = getDao(map, AlmAppInstallDao.class); almSettingDao = getDao(map, AlmSettingDao.class); + almPatDao = getDao(map, AlmPatDao.class); projectAlmSettingDao = getDao(map, ProjectAlmSettingDao.class); projectAlmBindingDao = getDao(map, ProjectAlmBindingDao.class); schemaMigrationDao = getDao(map, SchemaMigrationDao.class); @@ -254,6 +257,10 @@ public class DbClient { return almSettingDao; } + public AlmPatDao almPatDao() { + return almPatDao; + } + public ProjectAlmSettingDao projectAlmSettingDao() { return projectAlmSettingDao; } @@ -519,4 +526,5 @@ public class DbClient { public NewCodePeriodDao newCodePeriodDao() { return newCodePeriodDao; } + } 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 0fc20ca8a47..a4ed208f414 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 @@ -38,6 +38,7 @@ import org.sonar.db.alm.AlmAppInstallMapper; import org.sonar.db.alm.OrganizationAlmBindingMapper; import org.sonar.db.alm.ProjectAlmBindingDto; import org.sonar.db.alm.ProjectAlmBindingMapper; +import org.sonar.db.alm.pat.AlmPatMapper; import org.sonar.db.alm.setting.AlmSettingMapper; import org.sonar.db.alm.setting.ProjectAlmSettingMapper; import org.sonar.db.ce.CeActivityMapper; @@ -229,6 +230,7 @@ public class MyBatis implements Startable { Class[] mappers = { ActiveRuleMapper.class, AlmAppInstallMapper.class, + AlmPatMapper.class, AlmSettingMapper.class, AnalysisPropertiesMapper.class, AuthorizationMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDao.java new file mode 100644 index 00000000000..44447b942a0 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDao.java @@ -0,0 +1,75 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.pat; + +import java.util.List; +import java.util.Optional; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; +import org.sonar.db.alm.setting.AlmSettingDto; + +public class AlmPatDao implements Dao { + + private final System2 system2; + private final UuidFactory uuidFactory; + + public AlmPatDao(System2 system2, UuidFactory uuidFactory) { + this.system2 = system2; + this.uuidFactory = uuidFactory; + } + + private static AlmPatMapper getMapper(DbSession dbSession) { + return dbSession.getMapper(AlmPatMapper.class); + } + + public Optional selectByUuid(DbSession dbSession, String uuid) { + return Optional.ofNullable(getMapper(dbSession).selectByUuid(uuid)); + } + + public Optional selectByAlmSetting(DbSession dbSession, String userUuid, AlmSettingDto almSettingDto) { + return Optional.ofNullable(getMapper(dbSession).selectByAlmSetting(userUuid, almSettingDto.getUuid())); + } + + public List selectAll(DbSession dbSession) { + return getMapper(dbSession).selectAll(); + } + + public void insert(DbSession dbSession, AlmPatDto almPatDto) { + String uuid = uuidFactory.create(); + long now = system2.now(); + getMapper(dbSession).insert(almPatDto, uuid, now); + almPatDto.setUuid(uuid); + almPatDto.setCreatedAt(now); + almPatDto.setUpdatedAt(now); + } + + public void update(DbSession dbSession, AlmPatDto almPatDto) { + long now = system2.now(); + getMapper(dbSession).update(almPatDto, now); + almPatDto.setUpdatedAt(now); + } + + public void delete(DbSession dbSession, AlmPatDto almPatDto) { + getMapper(dbSession).deleteByUuid(almPatDto.getUuid()); + } + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDto.java new file mode 100644 index 00000000000..4bd42cc7bd2 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDto.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.pat; + +public class AlmPatDto { + + private String uuid; + private String personalAccessToken; + private String userUuid; + private String almSettingUuid; + + private long updatedAt; + private long createdAt; + + public String getAlmSettingUuid() { + return almSettingUuid; + } + + public AlmPatDto setAlmSettingUuid(String almSettingUuid) { + this.almSettingUuid = almSettingUuid; + return this; + } + + public String getUuid() { + return uuid; + } + + void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUserUuid() { + return userUuid; + } + + public AlmPatDto setUserUuid(String userUuid) { + this.userUuid = userUuid; + return this; + } + + public String getPersonalAccessToken() { + return personalAccessToken; + } + + public AlmPatDto setPersonalAccessToken(String personalAccessToken) { + this.personalAccessToken = personalAccessToken; + return this; + } + + public long getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + } + + public long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatMapper.java new file mode 100644 index 00000000000..eaf84b038e1 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatMapper.java @@ -0,0 +1,42 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.pat; + +import java.util.List; +import javax.annotation.CheckForNull; +import org.apache.ibatis.annotations.Param; + +public interface AlmPatMapper { + + @CheckForNull + AlmPatDto selectByUuid(@Param("uuid") String uuid); + + @CheckForNull + AlmPatDto selectByAlmSetting(@Param("userUuid") String userUuid, @Param("almSettingUuid") String almSettingUuid); + + List selectAll(); + + void insert(@Param("dto") AlmPatDto almPatDto, @Param("uuid") String uuid, @Param("now") long now); + + void update(@Param("dto") AlmPatDto almPatDto, @Param("now") long now); + + void deleteByUuid(@Param("uuid") String uuid); + +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/package-info.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/package-info.java new file mode 100644 index 00000000000..7202a3d6891 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public 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.db.alm.pat; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java index 3ff78c6dc3a..a4f0badbb02 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java @@ -63,7 +63,7 @@ public class AlmSettingDto { private String privateKey; /** - * Personal access token of the Azure DevOps instance. Max size is 2000. + * Personal access token of the Azure DevOps / Bitbucket instance. Max size is 2000. * This column will only be fed when alm is Azure DevOps or Bitbucket. * It will be null when the ALM is GitHub. */ diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/pat/AlmPatMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/pat/AlmPatMapper.xml new file mode 100644 index 00000000000..248c2c03ef0 --- /dev/null +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/pat/AlmPatMapper.xml @@ -0,0 +1,75 @@ + + + + + + + a.uuid as "uuid", + a.pat as "personalAccessToken", + a.user_uuid as "userUuid", + a.alm_setting_uuid as "almSettingUuid", + a.created_at as "createdAt", + a.updated_at as "updatedAt" + + + + + + + + + + + INSERT INTO alm_pats + ( + uuid, + pat, + user_uuid, + alm_setting_uuid, + created_at, + updated_at + ) + VALUES ( + #{uuid, jdbcType=VARCHAR}, + #{dto.personalAccessToken, jdbcType=VARCHAR}, + #{dto.userUuid, jdbcType=VARCHAR}, + #{dto.almSettingUuid, jdbcType=VARCHAR}, + #{now, jdbcType=BIGINT}, + #{now, jdbcType=BIGINT} + ) + + + + UPDATE alm_pats + + pat = #{dto.personalAccessToken, jdbcType=VARCHAR}, + updated_at = #{now, jdbcType=BIGINT} + + + uuid = #{dto.uuid, jdbcType=VARCHAR} + + + + + DELETE FROM alm_pats WHERE uuid = #{uuid, jdbcType=VARCHAR} + + + + diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl index d1dba736d3b..15d5484b25e 100644 --- a/server/sonar-db-dao/src/schema/schema-sq.ddl +++ b/server/sonar-db-dao/src/schema/schema-sq.ddl @@ -50,6 +50,17 @@ CREATE UNIQUE INDEX "ALM_APP_INSTALLS_OWNER" ON "ALM_APP_INSTALLS"("ALM_ID", "OW CREATE UNIQUE INDEX "ALM_APP_INSTALLS_INSTALL" ON "ALM_APP_INSTALLS"("ALM_ID", "INSTALL_ID"); CREATE INDEX "ALM_APP_INSTALLS_EXTERNAL_ID" ON "ALM_APP_INSTALLS"("USER_EXTERNAL_ID"); +CREATE TABLE "ALM_PATS"( + "UUID" VARCHAR(40) NOT NULL, + "PAT" VARCHAR(2000) NOT NULL, + "USER_UUID" VARCHAR(40) NOT NULL, + "ALM_SETTING_UUID" VARCHAR(40) NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "CREATED_AT" BIGINT NOT NULL +); +ALTER TABLE "ALM_PATS" ADD CONSTRAINT "PK_ALM_PATS" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "UNIQ_ALM_PATS" ON "ALM_PATS"("USER_UUID", "ALM_SETTING_UUID"); + CREATE TABLE "ALM_SETTINGS"( "UUID" VARCHAR(40) NOT NULL, "ALM_ID" VARCHAR(40) NOT NULL, diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java index 20f8df29878..76e48808a8c 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java @@ -30,6 +30,6 @@ public class DaoModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new DaoModule().configure(container); - assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 66); + assertThat(container.size()).isGreaterThan(1); } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/alm/pat/ALMPatDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/pat/ALMPatDaoTest.java new file mode 100644 index 00000000000..d30ed17f5ed --- /dev/null +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/alm/pat/ALMPatDaoTest.java @@ -0,0 +1,152 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.pat; + +import java.util.List; +import org.assertj.core.api.Assertions; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.alm.pat.AlmPatDao; +import org.sonar.db.alm.pat.AlmPatDto; +import org.sonar.db.alm.setting.AlmSettingDao; +import org.sonar.db.alm.setting.AlmSettingDto; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.alm.integration.pat.AlmPatsTesting.newAlmPatDto; +import static org.sonar.db.almsettings.AlmSettingsTesting.newGithubAlmSettingDto; +import static org.sonar.db.user.UserTesting.newUserDto; + +public class ALMPatDaoTest { + + private static final long NOW = 1000000L; + private static final String A_UUID = "SOME_UUID"; + @Rule + public ExpectedException expectedException = ExpectedException.none(); + private System2 system2 = mock(System2.class); + @Rule + public DbTester db = DbTester.create(system2); + + private DbSession dbSession = db.getSession(); + private UuidFactory uuidFactory = mock(UuidFactory.class); + private AlmPatDao underTest = new AlmPatDao(system2, uuidFactory); + private AlmSettingDao almSettingDao = new AlmSettingDao(system2, uuidFactory); + + @Test + public void selectByUuid() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + + AlmPatDto almPatDto = newAlmPatDto(); + underTest.insert(dbSession, almPatDto); + + assertThat(underTest.selectByUuid(dbSession, A_UUID).get()) + .extracting(AlmPatDto::getUuid, AlmPatDto::getPersonalAccessToken, + AlmPatDto::getUserUuid, AlmPatDto::getAlmSettingUuid, + AlmPatDto::getUpdatedAt, AlmPatDto::getCreatedAt) + .containsExactly(A_UUID, almPatDto.getPersonalAccessToken(), + almPatDto.getUserUuid(), almPatDto.getAlmSettingUuid(), + NOW, NOW); + + assertThat(underTest.selectByUuid(dbSession, "foo")).isNotPresent(); + } + + @Test + public void selectByAlmSetting() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + + AlmSettingDto almSetting = newGithubAlmSettingDto(); + almSettingDao.insert(dbSession, almSetting); + AlmPatDto almPatDto = newAlmPatDto(); + almPatDto.setAlmSettingUuid(almSetting.getUuid()); + + String userUuid = randomAlphanumeric(40); + almPatDto.setUserUuid(userUuid); + underTest.insert(dbSession, almPatDto); + + assertThat(underTest.selectByAlmSetting(dbSession, userUuid, almSetting).get()) + .extracting(AlmPatDto::getUuid, AlmPatDto::getPersonalAccessToken, + AlmPatDto::getUserUuid, AlmPatDto::getAlmSettingUuid, + AlmPatDto::getCreatedAt, AlmPatDto::getUpdatedAt) + .containsExactly(A_UUID, almPatDto.getPersonalAccessToken(), + userUuid, almSetting.getUuid(), NOW, NOW); + + assertThat(underTest.selectByAlmSetting(dbSession, randomAlphanumeric(40), newGithubAlmSettingDto())).isNotPresent(); + } + + @Test + public void selectAll() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + underTest.insert(dbSession, newAlmPatDto()); + when(uuidFactory.create()).thenReturn(A_UUID + "bis"); + underTest.insert(dbSession, newAlmPatDto()); + + List almPats = underTest.selectAll(dbSession); + + Assertions.assertThat(almPats).size().isEqualTo(2); + } + + @Test + public void update() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + AlmPatDto almPatDto = newAlmPatDto(); + underTest.insert(dbSession, almPatDto); + + String updated_pat = "updated pat"; + almPatDto.setPersonalAccessToken(updated_pat); + + when(system2.now()).thenReturn(NOW + 1); + underTest.update(dbSession, almPatDto); + + AlmPatDto result = underTest.selectByUuid(dbSession, A_UUID).get(); + assertThat(result) + .extracting(AlmPatDto::getUuid, AlmPatDto::getPersonalAccessToken, + AlmPatDto::getUserUuid, AlmPatDto::getAlmSettingUuid, + AlmPatDto::getCreatedAt, AlmPatDto::getUpdatedAt) + .containsExactly(A_UUID, updated_pat, almPatDto.getUserUuid(), + almPatDto.getAlmSettingUuid(), + NOW, NOW + 1); + + } + + @Test + public void delete() { + when(uuidFactory.create()).thenReturn(A_UUID); + when(system2.now()).thenReturn(NOW); + AlmPatDto almPat = newAlmPatDto(); + underTest.insert(dbSession, almPat); + + underTest.delete(dbSession, almPat); + + assertThat(underTest.selectByUuid(dbSession, almPat.getUuid()).isPresent()).isFalse(); + + } + +} 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 e8a891e9b92..d56635b8940 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 @@ -33,6 +33,7 @@ import org.picocontainer.containers.TransientPicoContainer; import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.alm.AlmDbTester; +import org.sonar.db.alm.integration.pat.AlmPatsDbTester; import org.sonar.db.almsettings.AlmSettingsDbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ProjectLinkDbTester; @@ -98,6 +99,7 @@ public class DbTester extends AbstractDbTester { private final AlmDbTester almDbTester; private final InternalComponentPropertyDbTester internalComponentPropertyTester; private final AlmSettingsDbTester almSettingsDbTester; + private final AlmPatsDbTester almPatsDbtester; private DbTester(System2 system2, @Nullable String schemaPath, MyBatisConfExtension... confExtensions) { super(TestDbImpl.create(schemaPath, confExtensions)); @@ -127,6 +129,7 @@ public class DbTester extends AbstractDbTester { this.internalComponentPropertyTester = new InternalComponentPropertyDbTester(this); this.newCodePeriodTester = new NewCodePeriodDbTester(this); this.almSettingsDbTester = new AlmSettingsDbTester(this); + this.almPatsDbtester = new AlmPatsDbTester(this); } public static DbTester create() { @@ -301,6 +304,10 @@ public class DbTester extends AbstractDbTester { return almSettingsDbTester; } + public AlmPatsDbTester almPats(){ + return almPatsDbtester; + } + @Override protected void after() { if (session != null) { diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsDbTester.java new file mode 100644 index 00000000000..c7227fb5455 --- /dev/null +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsDbTester.java @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.integration.pat; + +import java.util.function.Consumer; +import org.sonar.db.DbTester; +import org.sonar.db.alm.pat.AlmPatDto; + +import static java.util.Arrays.stream; +import static org.sonar.db.alm.integration.pat.AlmPatsTesting.newAlmPatDto; + +public class AlmPatsDbTester { + + private final DbTester db; + + public AlmPatsDbTester(DbTester db) { + this.db = db; + } + + @SafeVarargs + public final AlmPatDto insert(Consumer... populators) { + return insert(newAlmPatDto(), populators); + } + + private AlmPatDto insert(AlmPatDto dto, Consumer[] populators) { + stream(populators).forEach(p -> p.accept(dto)); + db.getDbClient().almPatDao().insert(db.getSession(), dto); + db.commit(); + return dto; + } + +} diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsTesting.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsTesting.java new file mode 100644 index 00000000000..fc4666eba76 --- /dev/null +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsTesting.java @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with 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.alm.integration.pat; + +import org.sonar.db.alm.pat.AlmPatDto; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; + +public class AlmPatsTesting { + + public static AlmPatDto newAlmPatDto() { + AlmPatDto almPatDto = new AlmPatDto(); + almPatDto.setAlmSettingUuid(randomAlphanumeric(40)); + almPatDto.setPersonalAccessToken(randomAlphanumeric(2000)); + almPatDto.setUserUuid(randomAlphanumeric(40)); + return almPatDto; + } + +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPatsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPatsTable.java new file mode 100644 index 00000000000..cc62e43372e --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPatsTable.java @@ -0,0 +1,98 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v82; + +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.VarcharColumnDef; +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; + +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 CreateAlmPatsTable extends DdlChange { + + private static final String TABLE_NAME = "alm_pats"; + + private static final VarcharColumnDef userUuidColumn = newVarcharColumnDefBuilder() + .setColumnName("user_uuid") + .setIsNullable(false) + .setLimit(256) + .build(); + + private static final VarcharColumnDef alm_setting_uuid = newVarcharColumnDefBuilder() + .setColumnName("alm_setting_uuid") + .setIsNullable(false) + .setLimit(UUID_SIZE) + .build(); + + public CreateAlmPatsTable(Database db) { + super(db); + } + + @Override + public void execute(Context context) throws SQLException { + if (tableExists()) { + return; + } + + context.execute(new CreateTableBuilder(getDialect(), TABLE_NAME) + .addPkColumn(newVarcharColumnDefBuilder() + .setColumnName("uuid") + .setIsNullable(false) + .setLimit(UUID_SIZE) + .build()) + .addColumn(newVarcharColumnDefBuilder() + .setColumnName("pat") + .setIsNullable(false) + .setLimit(2000) + .build()) + .addColumn(userUuidColumn) + .addColumn(alm_setting_uuid) + .addColumn(newBigIntegerColumnDefBuilder() + .setColumnName("updated_at") + .setIsNullable(false) + .build()) + .addColumn(newBigIntegerColumnDefBuilder() + .setColumnName("created_at") + .setIsNullable(false) + .build()) + .build()); + + context.execute(new CreateIndexBuilder() + .setTable(TABLE_NAME) + .addColumn(userUuidColumn) + .addColumn(alm_setting_uuid) + .setName("uniq_alm_pats") + .setUnique(true) + .build()); + } + + private boolean tableExists() throws SQLException { + try (Connection connection = getDatabase().getDataSource().getConnection()) { + return DatabaseUtils.tableExists(TABLE_NAME, connection); + } + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java index f14b923bf22..6cb35a8f7c7 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java @@ -34,6 +34,7 @@ public class DbVersion82 implements DbVersion { .add(3205, "Add PROJECTS table", CreateProjectsTable.class) .add(3206, "Populate PROJECTS table", PopulateProjectsTable.class) .add(3207, "Drop 'TAGS' column from COMPONENTS table", DropTagsColumnFromComponentsTable.class) - .add(3209, "Remove old Security Review Rating measures", DeleteSecurityReviewRatingMeasures.class); + .add(3208, "Remove old Security Review Rating measures", DeleteSecurityReviewRatingMeasures.class) + .add(3209, "Create ALM_PATS table", CreateAlmPatsTable.class); } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPATsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPATsTableTest.java new file mode 100644 index 00000000000..bdffd01bb1d --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPATsTableTest.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v82; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.version.v81.CreateAlmSettingsTable; + +import static java.sql.Types.BIGINT; +import static java.sql.Types.VARCHAR; + +public class CreateAlmPATsTableTest { + + private static final String TABLE_NAME = "alm_pats"; + + @Rule + public CoreDbTester dbTester = CoreDbTester.createEmpty(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private CreateAlmPatsTable underTest = new CreateAlmPatsTable(dbTester.database()); + + @Test + public void table_has_been_created() throws SQLException { + underTest.execute(); + + dbTester.assertTableExists(TABLE_NAME); + dbTester.assertPrimaryKey(TABLE_NAME, "pk_alm_pats", "uuid"); + dbTester.assertUniqueIndex(TABLE_NAME, "uniq_alm_pats", "user_uuid", "alm_setting_uuid"); + + dbTester.assertColumnDefinition(TABLE_NAME, "uuid", VARCHAR, 40, false); + dbTester.assertColumnDefinition(TABLE_NAME, "pat", VARCHAR, 2000, false); + dbTester.assertColumnDefinition(TABLE_NAME, "user_uuid", VARCHAR, 40, false); + dbTester.assertColumnDefinition(TABLE_NAME, "alm_setting_uuid", VARCHAR, 40, false); + dbTester.assertColumnDefinition(TABLE_NAME, "updated_at", BIGINT, 20, false); + dbTester.assertColumnDefinition(TABLE_NAME, "created_at", BIGINT, 20, false); + + // script should not fail if executed twice + underTest.execute(); + } + +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java index fd3fe9956bd..a8fb4920537 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java @@ -36,7 +36,7 @@ public class DbVersion82Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 9); + verifyMigrationCount(underTest, 10); } } -- 2.39.5