diff options
author | Jacek <52388493+jacek-poreda-sonarsource@users.noreply.github.com> | 2019-07-19 10:59:07 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-07-19 20:21:15 +0200 |
commit | 7d8052837730ed748a0dd48f647395a81e2a8d1e (patch) | |
tree | 1676547a19c68ccddc98dca78e4a94b9cb63fe67 /server/sonar-db-dao | |
parent | bd954c8e77d79eaf23d7c8d3b681fa9af634004c (diff) | |
download | sonarqube-7d8052837730ed748a0dd48f647395a81e2a8d1e.tar.gz sonarqube-7d8052837730ed748a0dd48f647395a81e2a8d1e.zip |
SONAR-8115 Storing default qgate in table (blue green deploy safety) (#1925)
* add DDL for project_qgate table
* support saving/update/delete to project quality gate and properties
* add db migration tests
Diffstat (limited to 'server/sonar-db-dao')
9 files changed, 186 insertions, 12 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java index 1cd23ae5d46..9e9152935fe 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java @@ -40,8 +40,32 @@ public class ProjectQgateAssociationDao implements Dao { return id == null ? Optional.empty() : Optional.of(Long.valueOf(id)); } + /** + * @return quality gate uuid if a specific Quality Gate has been defined for the given component uuid. <br> + * Returns <code>{@link Optional#empty()}</code> otherwise (ex: default quality gate applies) + */ + public Optional<String> selectQGateUuidByComponentUuid(DbSession dbSession, String componentUuid) { + String uuid = mapper(dbSession).selectQGateUuidByComponentUuid(componentUuid); + return Optional.ofNullable(uuid); + } + private static ProjectQgateAssociationMapper mapper(DbSession session) { return session.getMapper(ProjectQgateAssociationMapper.class); } + public void deleteByProjectUuid(DbSession dbSession, String projectUuid) { + mapper(dbSession).deleteByProjectUuid(projectUuid); + } + + public void deleteByQGateUuid(DbSession dbSession, String qGateUuid) { + mapper(dbSession).deleteByQGateUuid(qGateUuid); + } + + public void insertProjectQGateAssociation(DbSession dbSession, String projectUuid, String qGateUuid) { + mapper(dbSession).insertProjectQGateAssociation(projectUuid, qGateUuid); + } + + public void updateProjectQGateAssociation(DbSession dbSession, String projectUuid, String qGateUuid) { + mapper(dbSession).updateProjectQGateAssociation(projectUuid, qGateUuid); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java index d1f8ab689f5..4d282c6a091 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java @@ -29,4 +29,16 @@ public interface ProjectQgateAssociationMapper { @CheckForNull String selectQGateIdByComponentId(long componentId); + + @CheckForNull + String selectQGateUuidByComponentUuid(String componentUuid); + + void deleteByProjectUuid(String projectUuid); + + void insertProjectQGateAssociation(@Param("projectUuid") String projectUuid, @Param("qGateUuid") String qGateUuid); + + void deleteByQGateUuid(String qGateUuid); + + void updateProjectQGateAssociation(@Param("projectUuid") String projectUuid, @Param("qGateUuid") String qGateUuid); + } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java index b73dd5ceb96..cc9e7a2b415 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java @@ -101,4 +101,8 @@ public class QualityGateDao implements Dao { private static QualityGateMapper mapper(DbSession session) { return session.getMapper(QualityGateMapper.class); } + + public QualityGateDto selectByProjectUuid(DbSession dbSession, String uuid) { + return mapper(dbSession).selectByProjectUuid(uuid); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java index bdcc9c121f4..490f3bbbadc 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java @@ -56,4 +56,6 @@ public interface QualityGateMapper { void update(QualityGateDto qGate); void ensureOneBuiltInQualityGate(String builtInQualityName); + + QualityGateDto selectByProjectUuid(@Param("projectUuid") String projectUuid); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml index 5d9239182ed..ac1a2960ac8 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml @@ -36,4 +36,46 @@ </where> </select> + <select id="selectQGateUuidByComponentUuid" parameterType="String" resultType="string"> + SELECT quality_gate_uuid + FROM project_qgates + <where> + AND project_uuid=#{componentUuid} + </where> + </select> + + <delete id="deleteByProjectUuid" parameterType="String"> + DELETE + FROM project_qgates + WHERE + project_uuid=#{uuid,jdbcType=VARCHAR} + </delete> + + <delete id="deleteByQGateUuid" parameterType="String"> + DELETE + FROM project_qgates + WHERE + quality_gate_uuid=#{uuid,jdbcType=VARCHAR} + </delete> + + <insert id="insertProjectQGateAssociation" parameterType="map"> + INSERT into project_qgates + ( + project_uuid, + quality_gate_uuid + ) + VALUES ( + #{projectUuid,jdbcType=VARCHAR}, + #{qGateUuid,jdbcType=VARCHAR} + ) + </insert> + + <update id="updateProjectQGateAssociation" parameterType="map"> + UPDATE project_qgates + SET + quality_gate_uuid=#{qGateUuid,jdbcType=VARCHAR} + WHERE + project_uuid = #{projectUuid,jdbcType=VARCHAR} + </update> + </mapper> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml index f7ea50278a6..4d46494c2ff 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/QualityGateMapper.xml @@ -76,6 +76,15 @@ qg.id = #{id, jdbcType=BIGINT} </select> + <select id="selectByProjectUuid" parameterType="Map" resultType="org.sonar.db.qualitygate.QualityGateDto"> + SELECT + <include refid="gateColumns"/> + FROM + quality_gates qg + INNER JOIN + project_qgates pqg ON pqg.quality_gate_uuid = qg.uuid AND pqg.project_uuid = #{projectUuid, jdbcType=VARCHAR} + </select> + <select id="selectById" parameterType="long" resultType="QualityGate"> select <include refid="gateColumns"/> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java index 2f0a99162fa..77dae851284 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java @@ -77,17 +77,17 @@ public class ProjectQgateAssociationDaoTest { .qualityGate(qualityGate) .membership(ProjectQgateAssociationQuery.IN) .build())) - .extracting(ProjectQgateAssociationDto::getId, ProjectQgateAssociationDto::getName, ProjectQgateAssociationDto::getGateId) - .containsExactlyInAnyOrder( - tuple(project1.getId(), project1.name(), qualityGate.getId().toString()), - tuple(project2.getId(), project2.name(), qualityGate.getId().toString())); + .extracting(ProjectQgateAssociationDto::getId, ProjectQgateAssociationDto::getName, ProjectQgateAssociationDto::getGateId) + .containsExactlyInAnyOrder( + tuple(project1.getId(), project1.name(), qualityGate.getId().toString()), + tuple(project2.getId(), project2.name(), qualityGate.getId().toString())); assertThat(underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder() .qualityGate(qualityGate) .membership(ProjectQgateAssociationQuery.OUT) .build())) - .extracting(ProjectQgateAssociationDto::getId, ProjectQgateAssociationDto::getName, ProjectQgateAssociationDto::getGateId) - .containsExactlyInAnyOrder(tuple(project3.getId(), project3.name(), null)); + .extracting(ProjectQgateAssociationDto::getId, ProjectQgateAssociationDto::getName, ProjectQgateAssociationDto::getGateId) + .containsExactlyInAnyOrder(tuple(project3.getId(), project3.name(), null)); } @Test @@ -104,15 +104,15 @@ public class ProjectQgateAssociationDaoTest { .qualityGate(qualityGate) .projectSearch("one") .build())) - .extracting(ProjectQgateAssociationDto::getId) - .containsExactlyInAnyOrder(project1.getId()); + .extracting(ProjectQgateAssociationDto::getId) + .containsExactlyInAnyOrder(project1.getId()); assertThat(underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder() .qualityGate(qualityGate) .projectSearch("project") .build())) - .extracting(ProjectQgateAssociationDto::getId) - .containsExactlyInAnyOrder(project1.getId(), project2.getId(), project3.getId()); + .extracting(ProjectQgateAssociationDto::getId) + .containsExactlyInAnyOrder(project1.getId(), project2.getId(), project3.getId()); } @Test @@ -126,8 +126,8 @@ public class ProjectQgateAssociationDaoTest { assertThat(underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder() .qualityGate(qualityGate) .build())) - .extracting(ProjectQgateAssociationDto::getId) - .containsExactly(project1.getId(), project3.getId(), project2.getId()); + .extracting(ProjectQgateAssociationDto::getId) + .containsExactly(project1.getId(), project3.getId(), project2.getId()); } @Test @@ -174,4 +174,63 @@ public class ProjectQgateAssociationDaoTest { assertThat(result).contains(qualityGate1.getId()); } + @Test + public void select_qgate_uuid_by_component_uuid() { + OrganizationDto organization = db.organizations().insert(); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); + ComponentDto project = db.components().insertPrivateProject(organization); + + db.qualityGates().associateProjectToQualityGate(project, qualityGate); + + Optional<String> qGateUuid = underTest.selectQGateUuidByComponentUuid(dbSession, project.uuid()); + + assertThat(qGateUuid).contains(qualityGate.getUuid()); + } + + + @Test + public void delete_by_project_uuid() { + OrganizationDto organization = db.organizations().insert(); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); + ComponentDto project = db.components().insertPrivateProject(organization); + + db.qualityGates().associateProjectToQualityGate(project, qualityGate); + + underTest.deleteByProjectUuid(dbSession, project.uuid()); + + Optional<String> deletedQualityGate = db.qualityGates().selectQGateUuidByComponentUuid(project.uuid()); + + assertThat(deletedQualityGate).isEmpty(); + } + + @Test + public void delete_by_qgate_uuid() { + OrganizationDto organization = db.organizations().insert(); + QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); + ComponentDto project = db.components().insertPrivateProject(organization); + + db.qualityGates().associateProjectToQualityGate(project, qualityGate); + + underTest.deleteByQGateUuid(dbSession, qualityGate.getUuid()); + + Optional<String> deletedQualityGate = db.qualityGates().selectQGateUuidByComponentUuid(project.uuid()); + + assertThat(deletedQualityGate).isEmpty(); + } + + @Test + public void update_project_qgate_association() { + OrganizationDto organization = db.organizations().insert(); + QGateWithOrgDto firstQualityGate = db.qualityGates().insertQualityGate(organization); + QGateWithOrgDto secondQualityGate = db.qualityGates().insertQualityGate(organization); + ComponentDto project = db.components().insertPrivateProject(organization); + + db.qualityGates().associateProjectToQualityGate(project, firstQualityGate); + + underTest.updateProjectQGateAssociation(dbSession, project.uuid(), secondQualityGate.getUuid()); + + Optional<String> updatedQualityGateUuid = db.qualityGates().selectQGateUuidByComponentUuid(project.uuid()); + + assertThat(updatedQualityGateUuid).contains(secondQualityGate.getUuid()); + } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDaoTest.java index 63e588e2249..824390141e5 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDaoTest.java @@ -27,6 +27,7 @@ import org.sonar.api.utils.System2; import org.sonar.core.util.Uuids; import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; import static java.lang.String.format; @@ -111,6 +112,19 @@ public class QualityGateDaoTest { } @Test + public void select_by_uuid() { + QGateWithOrgDto dto = qualityGateDbTester.insertQualityGate(db.getDefaultOrganization(), g -> g.setName("QG Name").setBuiltIn(false)); + QualityGateDto qualityGateToAssociate = underTest.selectById(dbSession, dto.getId()); + ComponentDto project = db.components().insertPrivateProject(); + + qualityGateDbTester.associateProjectToQualityGate(project, qualityGateToAssociate); + + QualityGateDto qualityGateFromSelect = underTest.selectByProjectUuid(dbSession, project.uuid()); + + assertThat(qualityGateFromSelect.getUuid()).isEqualTo(qualityGateToAssociate.getUuid()); + } + + @Test public void select_by_organization_and_uuid() { OrganizationDto organization = db.organizations().insert(); QGateWithOrgDto qualityGate = db.qualityGates().insertQualityGate(organization); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDbTester.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDbTester.java index 872e495e950..01727b4c215 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDbTester.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualitygate/QualityGateDbTester.java @@ -21,6 +21,7 @@ package org.sonar.db.qualitygate; import java.util.Arrays; import java.util.Date; +import java.util.Optional; import java.util.function.Consumer; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -74,6 +75,9 @@ public class QualityGateDbTester { .setKey("sonar.qualitygate") .setResourceId(component.getId()) .setValue(String.valueOf(qualityGate.getId()))); + + dbClient.projectQgateAssociationDao().insertProjectQGateAssociation(dbSession, component.uuid(), qualityGate.getUuid()); + db.commit(); } @@ -105,4 +109,8 @@ public class QualityGateDbTester { db.commit(); return condition; } + + public Optional<String> selectQGateUuidByComponentUuid(String uuid) { + return dbClient.projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, uuid); + } } |