]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13001 create endpoint alm_integrations/set_pat
authorPierre Guillot <pierre.guillot@sonarsource.com>
Thu, 30 Jan 2020 10:46:37 +0000 (11:46 +0100)
committerSonarTech <sonartech@sonarsource.com>
Thu, 20 Feb 2020 19:46:16 +0000 (20:46 +0100)
20 files changed:
server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java
server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java
server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java
server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDao.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatDto.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/AlmPatMapper.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/alm/pat/package-info.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/AlmSettingDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/alm/pat/AlmPatMapper.xml [new file with mode: 0644]
server/sonar-db-dao/src/schema/schema-sq.ddl
server/sonar-db-dao/src/test/java/org/sonar/db/DaoModuleTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/alm/pat/ALMPatDaoTest.java [new file with mode: 0644]
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/DbTester.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsDbTester.java [new file with mode: 0644]
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/alm/integration/pat/AlmPatsTesting.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPatsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/CreateAlmPATsTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v82/DbVersion82Test.java

index 1cc30304e5df3037c28b818fb0529f17089dc8d2..5dd185823aa026ca88e6f9bf4e074ce1140ead60 100644 (file)
@@ -54,6 +54,7 @@ public final class SqTables {
     "active_rule_parameters",
     "alm_app_installs",
     "alm_settings",
+    "alm_pats",
     "analysis_properties",
     "ce_activity",
     "ce_queue",
index 9cf5de73ba4e1a19b454e528533bae3e34038433..05637e31fc62a582c806e5f484b3858a7b2dcac2 100644 (file)
@@ -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,
index 9707a025944734aab101f46e28e5c558ebcc441a..1ca65d852aeacce2d296544b5d5c720d5d141f4c 100644 (file)
@@ -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;
   }
+
 }
index 0fc20ca8a47aec92b467aefe77a8da746ec01b67..a4ed208f4143c15ae94c2e69f6702931edec9c18 100644 (file)
@@ -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 (file)
index 0000000..44447b9
--- /dev/null
@@ -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<AlmPatDto> selectByUuid(DbSession dbSession, String uuid) {
+    return Optional.ofNullable(getMapper(dbSession).selectByUuid(uuid));
+  }
+
+  public Optional<AlmPatDto> selectByAlmSetting(DbSession dbSession, String userUuid, AlmSettingDto almSettingDto) {
+    return Optional.ofNullable(getMapper(dbSession).selectByAlmSetting(userUuid, almSettingDto.getUuid()));
+  }
+
+  public List<AlmPatDto> 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 (file)
index 0000000..4bd42cc
--- /dev/null
@@ -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 (file)
index 0000000..eaf84b0
--- /dev/null
@@ -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<AlmPatDto> 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 (file)
index 0000000..7202a3d
--- /dev/null
@@ -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;
+
index 3ff78c6dc3afffa8b0b3c36d8e80174de9ecfe92..a4f0badbb027df5c57c001e0f43298494136435e 100644 (file)
@@ -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 (file)
index 0000000..248c2c0
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.db.alm.pat.AlmPatMapper">
+
+  <sql id="sqlColumns">
+    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"
+  </sql>
+
+  <select id="selectByUuid" parameterType="string" resultType="org.sonar.db.alm.pat.AlmPatDto">
+    select <include refid="sqlColumns"/>
+    from
+      alm_pats a
+    where
+      a.uuid = #{uuid, jdbcType=VARCHAR}
+  </select>
+
+  <select id="selectByAlmSetting" parameterType="string" resultType="org.sonar.db.alm.pat.AlmPatDto">
+    select <include refid="sqlColumns"/>
+    from
+    alm_pats a
+    where
+      a.alm_setting_uuid = #{almSettingUuid, jdbcType=VARCHAR}
+      and
+      a.user_uuid = #{userUuid, jdbcType=VARCHAR}
+  </select>
+
+  <select id="selectAll" resultType="org.sonar.db.alm.pat.AlmPatDto">
+    select <include refid="sqlColumns"/>
+    from alm_pats a
+  </select>
+
+
+  <insert id="insert" parameterType="Map" useGeneratedKeys="false">
+    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}
+    )
+  </insert>
+
+  <update id="update" parameterType="Map">
+    UPDATE alm_pats
+    <set>
+      pat = #{dto.personalAccessToken, jdbcType=VARCHAR},
+      updated_at = #{now, jdbcType=BIGINT}
+    </set>
+    <where>
+      uuid = #{dto.uuid, jdbcType=VARCHAR}
+    </where>
+  </update>
+
+  <delete id="deleteByUuid" parameterType="String">
+    DELETE FROM alm_pats WHERE uuid = #{uuid, jdbcType=VARCHAR}
+  </delete>
+
+
+</mapper>
index d1dba736d3bae4dd3ac64531107e6eb22c69d681..15d5484b25e64bea3e6c408686083abfc4cd22b7 100644 (file)
@@ -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,
index 20f8df29878d29acd0df55a21965d63339c09390..76e48808a8cc02fea5c8674f9dd625e2c0404ef5 100644 (file)
@@ -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 (file)
index 0000000..d30ed17
--- /dev/null
@@ -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<AlmPatDto> 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();
+
+  }
+
+}
index e8a891e9b923e5481d24c30cdf95f8b55beb82d9..d56635b89400abc1a231fad91862969d839251a2 100644 (file)
@@ -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<TestDbImpl> {
   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<TestDbImpl> {
     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<TestDbImpl> {
     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 (file)
index 0000000..c7227fb
--- /dev/null
@@ -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<AlmPatDto>... populators) {
+    return insert(newAlmPatDto(), populators);
+  }
+
+  private AlmPatDto insert(AlmPatDto dto, Consumer<AlmPatDto>[] 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 (file)
index 0000000..fc4666e
--- /dev/null
@@ -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 (file)
index 0000000..cc62e43
--- /dev/null
@@ -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);
+    }
+  }
+}
index f14b923bf22d720def2f5d43271d1298837cf857..6cb35a8f7c7fada482e7d1e7a0662d64e10c7773 100644 (file)
@@ -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 (file)
index 0000000..bdffd01
--- /dev/null
@@ -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();
+  }
+
+}
index fd3fe9956bd7764952cafe6b8d8f30f5a8a4b202..a8fb492053711e54c358a9b4b92118f751312ad3 100644 (file)
@@ -36,7 +36,7 @@ public class DbVersion82Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 9);
+    verifyMigrationCount(underTest, 10);
   }
 
 }