* migrate properties to project_qgate table * use project_qgates table instead of property * change usage of project quality gate in CEtags/8.0
@@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.qualitygate; | |||
import java.util.Optional; | |||
import org.sonar.ce.task.projectanalysis.analysis.Organization; | |||
import org.sonar.server.project.Project; | |||
public interface QualityGateService { | |||
@@ -30,9 +31,14 @@ public interface QualityGateService { | |||
Optional<QualityGate> findById(long id); | |||
/** | |||
* Retrieve the {@link QualityGate} from the database with the specified uuid. | |||
* Retrieve the {@link QualityGate} from the database using organization. | |||
* @throws IllegalStateException if database is corrupted and default gate can't be found. | |||
*/ | |||
QualityGate findDefaultQualityGate(Organization organizationDto); | |||
/** | |||
* Retrieve the {@link QualityGate} from the database associated with project. | |||
*/ | |||
Optional<QualityGate> findQualityGate(Project project); | |||
} |
@@ -28,6 +28,7 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.qualitygate.QualityGateConditionDto; | |||
import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.server.project.Project; | |||
import static org.sonar.core.util.stream.MoreCollectors.toList; | |||
@@ -63,6 +64,17 @@ public class QualityGateServiceImpl implements QualityGateService { | |||
} | |||
} | |||
@Override | |||
public Optional<QualityGate> findQualityGate(Project project) { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
QualityGateDto qualityGateDto = dbClient.qualityGateDao().selectByProjectUuid(dbSession, project.getUuid()); | |||
if (qualityGateDto == null) { | |||
return Optional.empty(); | |||
} | |||
return Optional.of(toQualityGate(dbSession, qualityGateDto)); | |||
} | |||
} | |||
private QualityGate toQualityGate(DbSession dbSession, QualityGateDto qualityGateDto) { | |||
Collection<QualityGateConditionDto> dtos = dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGateDto.getId()); | |||
@@ -21,32 +21,26 @@ package org.sonar.ce.task.projectanalysis.step; | |||
import java.util.Optional; | |||
import java.util.stream.Collectors; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.MutableQualityGateHolder; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.QualityGate; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.QualityGateService; | |||
import org.sonar.ce.task.step.ComputationStep; | |||
import static org.apache.commons.lang.StringUtils.isBlank; | |||
import org.sonar.server.project.Project; | |||
/** | |||
* This step retrieves the QualityGate and stores it in | |||
* {@link MutableQualityGateHolder}. | |||
*/ | |||
public class LoadQualityGateStep implements ComputationStep { | |||
private static final String PROPERTY_PROJECT_QUALITY_GATE = "sonar.qualitygate"; | |||
private final ConfigurationRepository configRepository; | |||
private final QualityGateService qualityGateService; | |||
private final MutableQualityGateHolder qualityGateHolder; | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
public LoadQualityGateStep(ConfigurationRepository settingsRepository, QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder, | |||
AnalysisMetadataHolder analysisMetadataHolder) { | |||
this.configRepository = settingsRepository; | |||
public LoadQualityGateStep(QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder, | |||
AnalysisMetadataHolder analysisMetadataHolder) { | |||
this.qualityGateService = qualityGateService; | |||
this.qualityGateHolder = qualityGateHolder; | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
@@ -73,20 +67,8 @@ public class LoadQualityGateStep implements ComputationStep { | |||
} | |||
private Optional<QualityGate> getProjectQualityGate() { | |||
Configuration config = configRepository.getConfiguration(); | |||
String qualityGateSetting = config.get(PROPERTY_PROJECT_QUALITY_GATE).orElse(null); | |||
if (isBlank(qualityGateSetting)) { | |||
return Optional.empty(); | |||
} | |||
try { | |||
long qualityGateId = Long.parseLong(qualityGateSetting); | |||
return qualityGateService.findById(qualityGateId); | |||
} catch (NumberFormatException e) { | |||
throw new IllegalStateException( | |||
String.format("Unsupported value (%s) in property %s", qualityGateSetting, PROPERTY_PROJECT_QUALITY_GATE), e); | |||
} | |||
Project project = analysisMetadataHolder.getProject(); | |||
return qualityGateService.findQualityGate(project); | |||
} | |||
private QualityGate getOrganizationDefaultQualityGate() { |
@@ -24,13 +24,16 @@ import java.util.Collections; | |||
import java.util.Optional; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.ce.task.projectanalysis.analysis.Organization; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.metric.MetricRepository; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.qualitygate.QGateWithOrgDto; | |||
import org.sonar.db.qualitygate.QualityGateConditionDao; | |||
import org.sonar.db.qualitygate.QualityGateConditionDto; | |||
import org.sonar.db.qualitygate.QualityGateDao; | |||
import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.server.project.Project; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.ArgumentMatchers.any; | |||
@@ -117,4 +120,57 @@ public class QualityGateServiceImplTest { | |||
assertThat(res.get().getConditions()).containsOnly( | |||
new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold())); | |||
} | |||
@Test(expected = IllegalStateException.class) | |||
public void findDefaultQualityGate_by_organization_not_found() { | |||
when(qualityGateDao.selectByOrganizationAndUuid(any(), any(), any())).thenReturn(null); | |||
underTest.findDefaultQualityGate(mock(Organization.class)); | |||
} | |||
@Test | |||
public void findDefaultQualityGate_by_organization_found() { | |||
QGateWithOrgDto qGateWithOrgDto = new QGateWithOrgDto(); | |||
qGateWithOrgDto.setId(QUALITY_GATE_DTO.getId()); | |||
qGateWithOrgDto.setName(QUALITY_GATE_DTO.getName()); | |||
when(qualityGateDao.selectByOrganizationAndUuid(any(), any(), any())).thenReturn(qGateWithOrgDto); | |||
when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_ID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2)); | |||
when(metricRepository.getOptionalById(METRIC_ID_1)).thenReturn(Optional.empty()); | |||
when(metricRepository.getOptionalById(METRIC_ID_2)).thenReturn(Optional.of(METRIC_2)); | |||
QualityGate result = underTest.findDefaultQualityGate(mock(Organization.class)); | |||
assertThat(result).isNotNull(); | |||
assertThat(result.getId()).isEqualTo(QUALITY_GATE_DTO.getId()); | |||
assertThat(result.getName()).isNotBlank(); | |||
assertThat(result.getName()).isEqualTo(QUALITY_GATE_DTO.getName()); | |||
} | |||
@Test | |||
public void findQualityGate_by_project_not_found() { | |||
when(qualityGateDao.selectByProjectUuid(any(), any())).thenReturn(null); | |||
Optional<QualityGate> result = underTest.findQualityGate(mock(Project.class)); | |||
assertThat(result).isEmpty(); | |||
} | |||
@Test | |||
public void findQualityGate_by_project_found() { | |||
QGateWithOrgDto qGateWithOrgDto = new QGateWithOrgDto(); | |||
qGateWithOrgDto.setId(QUALITY_GATE_DTO.getId()); | |||
qGateWithOrgDto.setName(QUALITY_GATE_DTO.getName()); | |||
when(qualityGateDao.selectByProjectUuid(any(), any())).thenReturn(qGateWithOrgDto); | |||
when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_ID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2)); | |||
when(metricRepository.getOptionalById(METRIC_ID_1)).thenReturn(Optional.empty()); | |||
when(metricRepository.getOptionalById(METRIC_ID_2)).thenReturn(Optional.of(METRIC_2)); | |||
Optional<QualityGate> result = underTest.findQualityGate(mock(Project.class)); | |||
assertThat(result).isNotNull(); | |||
assertThat(result).isNotEmpty(); | |||
QualityGate resultData = result.get(); | |||
assertThat(resultData.getId()).isEqualTo(QUALITY_GATE_DTO.getId()); | |||
assertThat(resultData.getName()).isNotBlank(); | |||
assertThat(resultData.getName()).isEqualTo(QUALITY_GATE_DTO.getName()); | |||
} | |||
} |
@@ -25,9 +25,8 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.config.internal.MapSettings; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository; | |||
import org.sonar.ce.task.projectanalysis.analysis.Organization; | |||
import org.sonar.ce.task.projectanalysis.metric.Metric; | |||
import org.sonar.ce.task.projectanalysis.metric.MetricImpl; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.Condition; | |||
@@ -35,6 +34,7 @@ import org.sonar.ce.task.projectanalysis.qualitygate.MutableQualityGateHolderRul | |||
import org.sonar.ce.task.projectanalysis.qualitygate.QualityGate; | |||
import org.sonar.ce.task.projectanalysis.qualitygate.QualityGateService; | |||
import org.sonar.ce.task.step.TestComputationStepContext; | |||
import org.sonar.server.project.Project; | |||
import static java.util.Collections.emptyList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -50,19 +50,18 @@ public class LoadQualityGateStepTest { | |||
public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule(); | |||
private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class); | |||
private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class); | |||
private QualityGateService qualityGateService = mock(QualityGateService.class); | |||
private LoadQualityGateStep underTest = new LoadQualityGateStep(settingsRepository, qualityGateService, mutableQualityGateHolder, analysisMetadataHolder); | |||
private LoadQualityGateStep underTest = new LoadQualityGateStep(qualityGateService, mutableQualityGateHolder, analysisMetadataHolder); | |||
@Before | |||
public void setUp() { | |||
when(analysisMetadataHolder.isShortLivingBranch()).thenReturn(false); | |||
when(analysisMetadataHolder.getOrganization()).thenReturn(mock(Organization.class)); | |||
} | |||
@Test | |||
public void filter_conditions_on_short_living_branch() { | |||
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig()); | |||
Metric newMetric = new MetricImpl(1, "new_key", "name", Metric.MetricType.INT); | |||
Metric metric = new MetricImpl(2, "key", "name", Metric.MetricType.INT); | |||
@@ -71,7 +70,7 @@ public class LoadQualityGateStepTest { | |||
when(analysisMetadataHolder.isSLBorPR()).thenReturn(true); | |||
QualityGate defaultGate = new QualityGate(1, "qg", Arrays.asList(variation, condition)); | |||
when(qualityGateService.findDefaultQualityGate(any())).thenReturn(defaultGate); | |||
when(qualityGateService.findDefaultQualityGate(any(Organization.class))).thenReturn(defaultGate); | |||
underTest.execute(new TestComputationStepContext()); | |||
@@ -80,8 +79,6 @@ public class LoadQualityGateStepTest { | |||
@Test | |||
public void filter_conditions_on_pull_request() { | |||
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig()); | |||
Metric newMetric = new MetricImpl(1, "new_key", "name", Metric.MetricType.INT); | |||
Metric metric = new MetricImpl(2, "key", "name", Metric.MetricType.INT); | |||
Condition variation = new Condition(newMetric, Condition.Operator.GREATER_THAN.getDbValue(), "1.0"); | |||
@@ -89,7 +86,7 @@ public class LoadQualityGateStepTest { | |||
when(analysisMetadataHolder.isSLBorPR()).thenReturn(true); | |||
QualityGate defaultGate = new QualityGate(1, "qg", Arrays.asList(variation, condition)); | |||
when(qualityGateService.findDefaultQualityGate(any())).thenReturn(defaultGate); | |||
when(qualityGateService.findDefaultQualityGate(any(Organization.class))).thenReturn(defaultGate); | |||
underTest.execute(new TestComputationStepContext()); | |||
@@ -98,31 +95,20 @@ public class LoadQualityGateStepTest { | |||
@Test | |||
public void execute_sets_default_QualityGate_when_project_has_no_settings() { | |||
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig()); | |||
QualityGate defaultGate = mock(QualityGate.class); | |||
when(qualityGateService.findDefaultQualityGate(any())).thenReturn(defaultGate); | |||
when(qualityGateService.findDefaultQualityGate(any(Organization.class))).thenReturn(defaultGate); | |||
underTest.execute(new TestComputationStepContext()); | |||
assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(defaultGate); | |||
} | |||
@Test | |||
public void execute_sets_default_QualityGate_when_property_value_is_not_a_long() { | |||
expectedException.expect(IllegalStateException.class); | |||
expectedException.expectMessage("Unsupported value (10 sds) in property sonar.qualitygate"); | |||
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().setProperty("sonar.qualitygate", "10 sds").asConfig()); | |||
underTest.execute(new TestComputationStepContext()); | |||
} | |||
@Test | |||
public void execute_sets_QualityGate_if_it_can_be_found_by_service() { | |||
QualityGate qualityGate = new QualityGate(10, "name", emptyList()); | |||
when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10).asConfig()); | |||
when(qualityGateService.findById(10)).thenReturn(Optional.of(qualityGate)); | |||
when(analysisMetadataHolder.getProject()).thenReturn(mock(Project.class)); | |||
when(qualityGateService.findQualityGate(any(Project.class))).thenReturn(Optional.of(qualityGate)); | |||
underTest.execute(new TestComputationStepContext()); | |||
@@ -30,16 +30,6 @@ public class ProjectQgateAssociationDao implements Dao { | |||
return mapper(dbSession).selectProjects(query); | |||
} | |||
/** | |||
* @return quality gate id if a specific Quality Gate has been defined for the given component id. <br> | |||
* Returns <code>{@link Optional#empty()}</code> otherwise (ex: default quality gate applies) | |||
*/ | |||
public Optional<Long> selectQGateIdByComponentId(DbSession dbSession, long componentId) { | |||
String id = mapper(dbSession).selectQGateIdByComponentId(componentId); | |||
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) |
@@ -27,9 +27,6 @@ public interface ProjectQgateAssociationMapper { | |||
List<ProjectQgateAssociationDto> selectProjects(@Param("query") ProjectQgateAssociationQuery query); | |||
@CheckForNull | |||
String selectQGateIdByComponentId(long componentId); | |||
@CheckForNull | |||
String selectQGateUuidByComponentUuid(String componentUuid); | |||
@@ -39,7 +39,7 @@ public class ProjectQgateAssociationQuery { | |||
public static final String OUT = "deselected"; | |||
public static final Set<String> AVAILABLE_MEMBERSHIP = ImmutableSet.of(ANY, IN, OUT); | |||
private final String gateId; | |||
private final String gateUuid; | |||
private final String organizationUuid; | |||
private final String membership; | |||
@@ -55,7 +55,7 @@ public class ProjectQgateAssociationQuery { | |||
private final int pageIndex; | |||
private ProjectQgateAssociationQuery(Builder builder) { | |||
this.gateId = Long.toString(builder.qualityGate.getId()); | |||
this.gateUuid = builder.qualityGate.getUuid(); | |||
this.organizationUuid = builder.qualityGate.getOrganizationUuid(); | |||
this.membership = builder.membership; | |||
this.projectSearch = builder.projectSearch; | |||
@@ -69,8 +69,8 @@ public class ProjectQgateAssociationQuery { | |||
this.pageIndex = builder.pageIndex; | |||
} | |||
public String gateId() { | |||
return gateId; | |||
public String gateUuid() { | |||
return gateUuid; | |||
} | |||
public String organizationUuid() { |
@@ -53,6 +53,11 @@ public class QualityGateDao implements Dao { | |||
return mapper(session).selectById(id); | |||
} | |||
@CheckForNull | |||
public QualityGateDto selectByUuid(DbSession session, String uuid) { | |||
return mapper(session).selectByUuid(uuid); | |||
} | |||
@CheckForNull | |||
public QGateWithOrgDto selectByOrganizationAndUuid(DbSession dbSession, OrganizationDto organization, String qualityGateUuid) { | |||
return mapper(dbSession).selectByUuidAndOrganization(qualityGateUuid, organization.getUuid()); |
@@ -57,5 +57,7 @@ public interface QualityGateMapper { | |||
void ensureOneBuiltInQualityGate(String builtInQualityName); | |||
QualityGateDto selectByUuid(String uuid); | |||
QualityGateDto selectByProjectUuid(@Param("projectUuid") String projectUuid); | |||
} |
@@ -4,9 +4,10 @@ | |||
<mapper namespace="org.sonar.db.qualitygate.ProjectQgateAssociationMapper"> | |||
<select id="selectProjects" parameterType="map" resultType="ProjectQgateAssociation"> | |||
SELECT proj.id as id, proj.kee as "key", proj.name as name, prop.text_value as gateId | |||
SELECT proj.id as id, proj.kee as "key", proj.name as name, qg.id as gateId | |||
FROM projects proj | |||
LEFT JOIN properties prop ON prop.resource_id=proj.id AND prop.prop_key='sonar.qualitygate' AND prop.text_value = #{query.gateId} | |||
LEFT JOIN project_qgates prqg ON prqg.project_uuid=proj.uuid AND prqg.quality_gate_uuid = #{query.gateUuid, jdbcType=VARCHAR} | |||
LEFT JOIN quality_gates qg ON qg.uuid = prqg.quality_gate_uuid | |||
where | |||
proj.qualifier = 'TRK' | |||
and proj.enabled = ${_true} | |||
@@ -15,10 +16,10 @@ | |||
and proj.organization_uuid=#{query.organizationUuid, jdbcType=VARCHAR} | |||
<choose> | |||
<when test="query.membership() == 'selected'"> | |||
and prop.text_value IS NOT NULL | |||
and qg.id IS NOT NULL | |||
</when> | |||
<when test="query.membership() == 'deselected'"> | |||
and prop.text_value IS NULL | |||
and qg.id IS NULL | |||
</when> | |||
</choose> | |||
<if test="query.projectSearch() != null"> | |||
@@ -27,15 +28,6 @@ | |||
order by proj.name | |||
</select> | |||
<select id="selectQGateIdByComponentId" parameterType="long" resultType="string"> | |||
SELECT text_value | |||
FROM properties | |||
<where> | |||
AND resource_id=#{componentId} | |||
AND prop_key='sonar.qualitygate' | |||
</where> | |||
</select> | |||
<select id="selectQGateUuidByComponentUuid" parameterType="String" resultType="string"> | |||
SELECT quality_gate_uuid | |||
FROM project_qgates |
@@ -43,6 +43,13 @@ | |||
where name=#{name, jdbcType=VARCHAR} | |||
</select> | |||
<select id="selectByUuid" parameterType="String" resultType="QualityGate"> | |||
select | |||
<include refid="gateColumns"/> | |||
from quality_gates | |||
where uuid=#{uuid, jdbcType=VARCHAR} | |||
</select> | |||
<select id="selectByUuidAndOrganization" parameterType="Map" resultType="org.sonar.db.qualitygate.QGateWithOrgDto"> | |||
SELECT | |||
<include refid="qateWithOrgColumns"/> |
@@ -151,16 +151,16 @@ public class ProjectQgateAssociationDaoTest { | |||
} | |||
@Test | |||
public void select_qgate_id_is_absent() { | |||
public void select_qgate_uuid_is_absent() { | |||
ComponentDto project = db.components().insertPrivateProject(); | |||
Optional<Long> result = underTest.selectQGateIdByComponentId(dbSession, project.getId()); | |||
Optional<String> result = underTest.selectQGateUuidByComponentUuid(dbSession, project.uuid()); | |||
assertThat(result.isPresent()).isFalse(); | |||
} | |||
@Test | |||
public void select_qgate_id() { | |||
public void select_qgate_uuid() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
QGateWithOrgDto qualityGate1 = db.qualityGates().insertQualityGate(organization); | |||
QGateWithOrgDto qualityGate2 = db.qualityGates().insertQualityGate(organization); | |||
@@ -169,25 +169,11 @@ public class ProjectQgateAssociationDaoTest { | |||
db.qualityGates().associateProjectToQualityGate(project1, qualityGate1); | |||
db.qualityGates().associateProjectToQualityGate(project2, qualityGate2); | |||
Optional<Long> result = underTest.selectQGateIdByComponentId(dbSession, project1.getId()); | |||
Optional<String> result = underTest.selectQGateUuidByComponentUuid(dbSession, project1.uuid()); | |||
assertThat(result).contains(qualityGate1.getId()); | |||
assertThat(result).contains(qualityGate1.getUuid()); | |||
} | |||
@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(); |
@@ -112,16 +112,10 @@ 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()); | |||
public void testSelectByUuid() { | |||
insertQualityGates(); | |||
assertThat(underTest.selectByUuid(dbSession, underTest.selectByName(dbSession, "Very strict").getUuid()).getName()).isEqualTo("Very strict"); | |||
assertThat(underTest.selectByUuid(dbSession, "not-existing-uuid")).isNull(); | |||
} | |||
@Test | |||
@@ -175,6 +169,24 @@ public class QualityGateDaoTest { | |||
assertThat(underTest.selectDefault(dbSession, otherOrganization).getUuid()).isEqualTo(otherQualityGate.getUuid()); | |||
} | |||
@Test | |||
public void select_by_project_uuid() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
ComponentDto project = db.components().insertPrivateProject(organization); | |||
QGateWithOrgDto qualityGate1 = db.qualityGates().insertQualityGate(organization); | |||
QGateWithOrgDto qualityGate2 = db.qualityGates().insertQualityGate(organization); | |||
OrganizationDto otherOrganization = db.organizations().insert(); | |||
QGateWithOrgDto qualityGate3 = db.qualityGates().insertQualityGate(otherOrganization); | |||
db.qualityGates().associateProjectToQualityGate(project, qualityGate1); | |||
assertThat(underTest.selectByProjectUuid(dbSession, project.uuid()).getUuid()).isEqualTo(qualityGate1.getUuid()); | |||
assertThat(underTest.selectByProjectUuid(dbSession, "not-existing-uuid")).isNull(); | |||
} | |||
@Test | |||
public void delete() { | |||
OrganizationDto organization = db.organizations().insert(); |
@@ -30,7 +30,6 @@ import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.metric.MetricDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.property.PropertyDto; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; | |||
import static org.apache.commons.lang.RandomStringUtils.randomNumeric; | |||
@@ -71,13 +70,7 @@ public class QualityGateDbTester { | |||
} | |||
public void associateProjectToQualityGate(ComponentDto component, QualityGateDto qualityGate) { | |||
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() | |||
.setKey("sonar.qualitygate") | |||
.setResourceId(component.getId()) | |||
.setValue(String.valueOf(qualityGate.getId()))); | |||
dbClient.projectQgateAssociationDao().insertProjectQGateAssociation(dbSession, component.uuid(), qualityGate.getUuid()); | |||
db.commit(); | |||
} | |||
@@ -110,7 +103,7 @@ public class QualityGateDbTester { | |||
return condition; | |||
} | |||
public Optional<String> selectQGateUuidByComponentUuid(String uuid) { | |||
return dbClient.projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, uuid); | |||
public Optional<String> selectQGateUuidByComponentUuid(String componentUuid) { | |||
return dbClient.projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, componentUuid); | |||
} | |||
} |
@@ -28,6 +28,7 @@ public class DbVersion80 implements DbVersion { | |||
registry | |||
.add(3000, "Set Organizations#guarded column nullable", MakeOrganizationsGuardedNullable.class) | |||
.add(3001, "Create ProjectQualityGates table", CreateProjectQualityGatesTable.class) | |||
.add(3002, "Make index on DEPRECATED_RULE_KEYS.RULE_ID non unique", MakeDeprecatedRuleKeysRuleIdIndexNonUnique.class); | |||
.add(3002, "Make index on DEPRECATED_RULE_KEYS.RULE_ID non unique", MakeDeprecatedRuleKeysRuleIdIndexNonUnique.class) | |||
.add(3003, "Populate ProjectQualityGate table from Properties table", PopulateProjectQualityGatesTable.class); | |||
} | |||
} |
@@ -0,0 +1,80 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.SQLException; | |||
import java.util.List; | |||
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 PopulateProjectQualityGatesTable extends DataChange { | |||
public PopulateProjectQualityGatesTable(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
protected void execute(Context context) throws SQLException { | |||
List<ProjectQualityGate> projectQualityGates = context.prepareSelect( | |||
"select prj.uuid, qg.uuid from properties p \n" + | |||
"join projects prj on p.resource_id = prj.id\n" + | |||
"join quality_gates qg on qg.id = CAST(p.text_value AS int)\n" + | |||
"where p.prop_key = 'sonar.qualitygate'\n" + | |||
"and not exists(select pqg.project_uuid from project_qgates pqg where pqg.project_uuid = prj.uuid)") | |||
.list(row -> { | |||
String projectUuid = row.getString(1); | |||
String qualityGateUuid = row.getString(2); | |||
return new ProjectQualityGate(projectUuid, qualityGateUuid); | |||
}); | |||
if (!projectQualityGates.isEmpty()) { | |||
populateProjectQualityGates(context, projectQualityGates); | |||
} | |||
} | |||
private static void populateProjectQualityGates(Context context, List<ProjectQualityGate> projectQualityGates) throws SQLException { | |||
Upsert insertQuery = prepareInsertProjectQualityGateQuery(context); | |||
for (ProjectQualityGate projectQualityGate : projectQualityGates) { | |||
insertQuery | |||
.setString(1, projectQualityGate.projectUuid) | |||
.setString(2, projectQualityGate.qualityGateUuid) | |||
.addBatch(); | |||
} | |||
insertQuery | |||
.execute() | |||
.commit(); | |||
} | |||
private static Upsert prepareInsertProjectQualityGateQuery(Context context) throws SQLException { | |||
return context.prepareUpsert("insert into project_qgates(project_uuid, quality_gate_uuid) VALUES (?, ?)"); | |||
} | |||
private static class ProjectQualityGate { | |||
private final String projectUuid; | |||
private final String qualityGateUuid; | |||
ProjectQualityGate(String projectUuid, String qualityGateUuid) { | |||
this.projectUuid = projectUuid; | |||
this.qualityGateUuid = qualityGateUuid; | |||
} | |||
} | |||
} |
@@ -35,7 +35,7 @@ public class DbVersion80Test { | |||
@Test | |||
public void verify_migration_count() { | |||
verifyMigrationCount(underTest, 3); | |||
verifyMigrationCount(underTest, 4); | |||
} | |||
} |
@@ -0,0 +1,131 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v80; | |||
import java.sql.SQLException; | |||
import java.time.Instant; | |||
import java.util.List; | |||
import java.util.Random; | |||
import java.util.stream.Collectors; | |||
import org.junit.Assert; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.db.CoreDbTester; | |||
import static java.lang.String.valueOf; | |||
public class PopulateProjectQualityGatesTableTest { | |||
private static final String PROJECTS_TABLE_NAME = "projects"; | |||
private static final String QUALITY_GATES_TABLE_NAME = "quality_gates"; | |||
private static final String PROPERTIES_TABLE_NAME = "properties"; | |||
private static final int NUMBER_OF_PROJECTS_TO_INSERT = 5; | |||
private final Random random = new Random(); | |||
@Rule | |||
public CoreDbTester dbTester = CoreDbTester.createForSchema(PopulateProjectQualityGatesTableTest.class, "schema.sql"); | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private PopulateProjectQualityGatesTable underTest = new PopulateProjectQualityGatesTable(dbTester.database()); | |||
@Test | |||
public void copy_quality_gates_properties_to_project_qgate_table() throws SQLException { | |||
long firstQualityGateId = insertQualityGate("qg1"); | |||
long secondQualityGateId = insertQualityGate("qg2"); | |||
for (long i = 1; i <= NUMBER_OF_PROJECTS_TO_INSERT; i++) { | |||
long projectId = insertComponent("p" + i); | |||
long qualityGateId = random.nextBoolean() ? firstQualityGateId : secondQualityGateId; | |||
insertQualityGateProperty(projectId, qualityGateId); | |||
} | |||
underTest.execute(); | |||
List<ProjectQualityGate> qualityGates = getQualityGates(); | |||
Assert.assertEquals(NUMBER_OF_PROJECTS_TO_INSERT, qualityGates.size()); | |||
//must not delete properties | |||
int propertiesCount = dbTester.countRowsOfTable(PROPERTIES_TABLE_NAME); | |||
Assert.assertEquals(5, propertiesCount); | |||
//should not fail if executed twice | |||
underTest.execute(); | |||
} | |||
private long insertQualityGate(String qualityGateUuid) { | |||
dbTester.executeInsert( | |||
QUALITY_GATES_TABLE_NAME, | |||
"UUID", qualityGateUuid, | |||
"NAME", "name_" + qualityGateUuid, | |||
"IS_BUILT_IN", valueOf(true) | |||
); | |||
return (long) dbTester.selectFirst("select id as \"ID\" from quality_gates where uuid='" + qualityGateUuid + "'").get("ID"); | |||
} | |||
private long insertComponent(String uuid) { | |||
dbTester.executeInsert( | |||
PROJECTS_TABLE_NAME, | |||
"ORGANIZATION_UUID", "org_" + uuid, | |||
"SCOPE", "PRJ", | |||
"QUALIFIER", "TRK", | |||
"UUID", uuid, | |||
"UUID_PATH", "path_" + uuid, | |||
"ROOT_UUID", "root_" + uuid, | |||
"PROJECT_UUID", uuid, | |||
"PRIVATE", valueOf(false)); | |||
return (long) dbTester.selectFirst("select id as \"ID\" from projects where uuid='" + uuid + "'").get("ID"); | |||
} | |||
private void insertQualityGateProperty(Long projectId, Long qualityGateId) { | |||
dbTester.executeInsert(PROPERTIES_TABLE_NAME, | |||
"prop_key", "sonar.qualitygate", | |||
"resource_id", projectId, | |||
"is_empty", false, | |||
"text_value", Long.toString(qualityGateId), | |||
"created_at", Instant.now().toEpochMilli()); | |||
} | |||
private List<ProjectQualityGate> getQualityGates() { | |||
return dbTester.select("select pqg.project_uuid, pqg.quality_gate_uuid from project_qgates pqg " + | |||
"join projects p on pqg.project_uuid = p.uuid " + | |||
"join quality_gates qg on pqg.quality_gate_uuid = qg.uuid") | |||
.stream() | |||
.map(row -> { | |||
String projectUuid = String.valueOf(row.get("PROJECT_UUID")); | |||
String qualityGateUuid = String.valueOf(row.get("QUALITY_GATE_UUID")); | |||
return new ProjectQualityGate(projectUuid, qualityGateUuid); | |||
}) | |||
.collect(Collectors.toList()); | |||
} | |||
private static class ProjectQualityGate { | |||
final String projectUuid; | |||
final String qualityGateUuid; | |||
private ProjectQualityGate(String projectUuid, String qualityGateUuid) { | |||
this.projectUuid = projectUuid; | |||
this.qualityGateUuid = qualityGateUuid; | |||
} | |||
} | |||
} |
@@ -0,0 +1,77 @@ | |||
CREATE TABLE "PROJECTS" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL, | |||
"KEE" VARCHAR(400), | |||
"UUID" VARCHAR(50) NOT NULL, | |||
"UUID_PATH" VARCHAR(1500) NOT NULL, | |||
"ROOT_UUID" VARCHAR(50) NOT NULL, | |||
"PROJECT_UUID" VARCHAR(50) NOT NULL, | |||
"MODULE_UUID" VARCHAR(50), | |||
"MODULE_UUID_PATH" VARCHAR(1500), | |||
"MAIN_BRANCH_PROJECT_UUID" VARCHAR(50), | |||
"NAME" VARCHAR(2000), | |||
"DESCRIPTION" VARCHAR(2000), | |||
"PRIVATE" BOOLEAN NOT NULL, | |||
"TAGS" VARCHAR(500), | |||
"ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, | |||
"SCOPE" VARCHAR(3), | |||
"QUALIFIER" VARCHAR(10), | |||
"DEPRECATED_KEE" VARCHAR(400), | |||
"PATH" VARCHAR(2000), | |||
"LANGUAGE" VARCHAR(20), | |||
"COPY_COMPONENT_UUID" VARCHAR(50), | |||
"LONG_NAME" VARCHAR(2000), | |||
"DEVELOPER_UUID" VARCHAR(50), | |||
"CREATED_AT" TIMESTAMP, | |||
"AUTHORIZATION_UPDATED_AT" BIGINT, | |||
"B_CHANGED" BOOLEAN, | |||
"B_COPY_COMPONENT_UUID" VARCHAR(50), | |||
"B_DESCRIPTION" VARCHAR(2000), | |||
"B_ENABLED" BOOLEAN, | |||
"B_UUID_PATH" VARCHAR(1500), | |||
"B_LANGUAGE" VARCHAR(20), | |||
"B_LONG_NAME" VARCHAR(500), | |||
"B_MODULE_UUID" VARCHAR(50), | |||
"B_MODULE_UUID_PATH" VARCHAR(1500), | |||
"B_NAME" VARCHAR(500), | |||
"B_PATH" VARCHAR(2000), | |||
"B_QUALIFIER" VARCHAR(10) | |||
); | |||
CREATE INDEX "PROJECTS_ORGANIZATION" ON "PROJECTS" ("ORGANIZATION_UUID"); | |||
CREATE UNIQUE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE"); | |||
CREATE INDEX "PROJECTS_ROOT_UUID" ON "PROJECTS" ("ROOT_UUID"); | |||
CREATE UNIQUE INDEX "PROJECTS_UUID" ON "PROJECTS" ("UUID"); | |||
CREATE INDEX "PROJECTS_PROJECT_UUID" ON "PROJECTS" ("PROJECT_UUID"); | |||
CREATE INDEX "PROJECTS_MODULE_UUID" ON "PROJECTS" ("MODULE_UUID"); | |||
CREATE INDEX "PROJECTS_QUALIFIER" ON "PROJECTS" ("QUALIFIER"); | |||
CREATE TABLE "QUALITY_GATES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"UUID" VARCHAR(40) NOT NULL, | |||
"NAME" VARCHAR(100) NOT NULL, | |||
"IS_BUILT_IN" BOOLEAN NOT NULL, | |||
"CREATED_AT" TIMESTAMP, | |||
"UPDATED_AT" TIMESTAMP, | |||
); | |||
CREATE UNIQUE INDEX "UNIQ_QUALITY_GATES_UUID" ON "QUALITY_GATES" ("UUID"); | |||
CREATE TABLE "PROPERTIES" ( | |||
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), | |||
"PROP_KEY" VARCHAR(512) NOT NULL, | |||
"RESOURCE_ID" INTEGER, | |||
"USER_ID" INTEGER, | |||
"IS_EMPTY" BOOLEAN NOT NULL, | |||
"TEXT_VALUE" VARCHAR(4000), | |||
"CLOB_VALUE" CLOB, | |||
"CREATED_AT" BIGINT | |||
); | |||
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY"); | |||
CREATE TABLE "PROJECT_QGATES" ( | |||
"PROJECT_UUID" VARCHAR(40) NOT NULL, | |||
"QUALITY_GATE_UUID" VARCHAR(40) NOT NULL, | |||
CONSTRAINT "PK_PROJECT_QGATES" PRIMARY KEY ("PROJECT_UUID") | |||
); | |||
CREATE UNIQUE INDEX "UNIQ_PROJECT_QGATES" ON "PROJECT_QGATES" ("PROJECT_UUID", "QUALITY_GATE_UUID"); |
@@ -32,8 +32,6 @@ import static java.util.Optional.ofNullable; | |||
public class QualityGateFinder { | |||
public static final String SONAR_QUALITYGATE_PROPERTY = "sonar.qualitygate"; | |||
private final DbClient dbClient; | |||
public QualityGateFinder(DbClient dbClient) { | |||
@@ -46,8 +44,8 @@ public class QualityGateFinder { | |||
* It will first try to get the quality gate explicitly defined on a project, if none it will try to return default quality gate of the organization | |||
*/ | |||
public Optional<QualityGateData> getQualityGate(DbSession dbSession, OrganizationDto organization, ComponentDto component) { | |||
Optional<QualityGateData> res = dbClient.projectQgateAssociationDao().selectQGateIdByComponentId(dbSession, component.getId()) | |||
.map(qualityGateId -> dbClient.qualityGateDao().selectById(dbSession, qualityGateId)) | |||
Optional<QualityGateData> res = dbClient.projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, component.uuid()) | |||
.map(qualityGateUuid -> dbClient.qualityGateDao().selectByUuid(dbSession, qualityGateUuid)) | |||
.map(qualityGateDto -> new QualityGateData(qualityGateDto, false)); | |||
if (res.isPresent()) { | |||
return res; |
@@ -32,7 +32,6 @@ import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_ID; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_KEY; | |||
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; | |||
@@ -88,7 +87,6 @@ public class DeselectAction implements QualityGatesWsAction { | |||
private void dissociateProject(DbSession dbSession, OrganizationDto organization, ComponentDto project) { | |||
wsSupport.checkCanAdminProject(organization, project); | |||
dbClient.propertiesDao().deleteProjectProperty(SONAR_QUALITYGATE_PROPERTY, project.getId(), dbSession); | |||
dbClient.projectQgateAssociationDao().deleteByProjectUuid(dbSession, project.uuid()); | |||
dbSession.commit(); | |||
} |
@@ -30,7 +30,6 @@ import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.server.qualitygate.QualityGateFinder; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; | |||
public class DestroyAction implements QualityGatesWsAction { | |||
@@ -71,7 +70,6 @@ public class DestroyAction implements QualityGatesWsAction { | |||
checkArgument(!defaultQualityGate.getId().equals(qualityGate.getId()), "The default quality gate cannot be removed"); | |||
wsSupport.checkCanEdit(qualityGate); | |||
dbClient.propertiesDao().deleteByKeyAndValue(dbSession, SONAR_QUALITYGATE_PROPERTY, String.valueOf(qualityGate.getId())); | |||
dbClient.projectQgateAssociationDao().deleteByQGateUuid(dbSession, qualityGate.getUuid()); | |||
dbClient.qualityGateDao().delete(qualityGate, dbSession); | |||
dbSession.commit(); |
@@ -29,13 +29,11 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.db.qualitygate.QGateWithOrgDto; | |||
import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
import org.sonar.server.component.ComponentFinder.ParamNames; | |||
import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.ACTION_SELECT; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_GATE_ID; | |||
import static org.sonar.server.qualitygate.ws.QualityGatesWsParameters.PARAM_PROJECT_ID; | |||
@@ -57,9 +55,9 @@ public class SelectAction implements QualityGatesWsAction { | |||
public void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction(ACTION_SELECT) | |||
.setDescription("Associate a project to a quality gate.<br>" + | |||
"The '%s' or '%s' must be provided.<br>" + | |||
"Project id as a numeric value is deprecated since 6.1. Please use the id similar to '%s'.<br>" + | |||
"Requires the 'Administer Quality Gates' permission.", | |||
"The '%s' or '%s' must be provided.<br>" + | |||
"Project id as a numeric value is deprecated since 6.1. Please use the id similar to '%s'.<br>" + | |||
"Requires the 'Administer Quality Gates' permission.", | |||
PARAM_PROJECT_ID, PARAM_PROJECT_KEY, | |||
Uuids.UUID_EXAMPLE_02) | |||
.setPost(true) | |||
@@ -95,22 +93,17 @@ public class SelectAction implements QualityGatesWsAction { | |||
ComponentDto project = getProject(dbSession, organization, projectId, projectKey); | |||
wsSupport.checkCanAdminProject(organization, project); | |||
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() | |||
.setKey(SONAR_QUALITYGATE_PROPERTY) | |||
.setResourceId(project.getId()) | |||
.setValue(String.valueOf(qualityGate.getId()))); | |||
QualityGateDto currentQualityGate = dbClient.qualityGateDao().selectByProjectUuid(dbSession, project.uuid()); | |||
if (currentQualityGate == null) { | |||
// project uses the default profile | |||
dbClient.projectQgateAssociationDao() | |||
.insertProjectQGateAssociation(dbSession, project.uuid(), qualityGate.getUuid()); | |||
dbSession.commit(); | |||
} else if (!qualityGate.getUuid().equals(currentQualityGate.getUuid())) { | |||
dbClient.projectQgateAssociationDao() | |||
.updateProjectQGateAssociation(dbSession, project.uuid(), qualityGate.getUuid()); | |||
dbSession.commit(); | |||
} | |||
dbSession.commit(); | |||
} | |||
response.noContent(); | |||
} |
@@ -27,11 +27,9 @@ import org.sonar.api.server.ws.Change; | |||
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.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.organization.OrganizationDto; | |||
import org.sonar.db.property.PropertyDto; | |||
import org.sonar.db.qualitygate.QGateWithOrgDto; | |||
import org.sonar.db.qualitygate.QualityGateDto; | |||
import org.sonar.server.component.TestComponentFinder; | |||
@@ -47,7 +45,6 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.tuple; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; | |||
import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; | |||
public class DeselectActionTest { | |||
@@ -59,7 +56,6 @@ public class DeselectActionTest { | |||
public DbTester db = DbTester.create(); | |||
private DbClient dbClient = db.getDbClient(); | |||
private DbSession dbSession = db.getSession(); | |||
private TestDefaultOrganizationProvider organizationProvider = TestDefaultOrganizationProvider.from(db); | |||
private DeselectAction underTest = new DeselectAction(dbClient, TestComponentFinder.from(db), | |||
new QualityGatesWsSupport(db.getDbClient(), userSession, organizationProvider)); | |||
@@ -300,10 +296,6 @@ public class DeselectActionTest { | |||
} | |||
private void associateProjectToQualityGate(ComponentDto project, QualityGateDto qualityGate) { | |||
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() | |||
.setResourceId(project.getId()) | |||
.setValue(qualityGate.getId().toString()) | |||
.setKey(SONAR_QUALITYGATE_PROPERTY)); | |||
db.qualityGates().associateProjectToQualityGate(project, qualityGate); | |||
db.commit(); | |||
} | |||
@@ -313,8 +305,6 @@ public class DeselectActionTest { | |||
assertThat(qGateUuid) | |||
.isNotNull() | |||
.isEmpty(); | |||
assertThat(dbClient.propertiesDao().selectProjectProperty(project.getId(), SONAR_QUALITYGATE_PROPERTY)).isNull(); | |||
} | |||
private void assertSelected(QGateWithOrgDto qualityGate, ComponentDto project) { | |||
@@ -323,7 +313,5 @@ public class DeselectActionTest { | |||
.isNotNull() | |||
.isNotEmpty() | |||
.hasValue(qualityGate.getUuid()); | |||
String qGateId = dbClient.propertiesDao().selectProjectProperty(project.getId(), SONAR_QUALITYGATE_PROPERTY).getValue(); | |||
assertThat(qGateId).isEqualTo(String.valueOf(qualityGate.getId())); | |||
} | |||
} |
@@ -113,11 +113,9 @@ public class DestroyActionTest { | |||
.setParam(PARAM_ORGANIZATION, organization.getKey()) | |||
.execute(); | |||
assertThat(db.getDbClient().qualityGateDao().selectByOrganizationAndId(dbSession, organization, qualityGate.getId())) | |||
.isNull(); | |||
assertThat(db.getDbClient().propertiesDao().selectProjectProperties(prj1.getDbKey())) | |||
assertThat(db.getDbClient().projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, prj1.uuid())) | |||
.isEmpty(); | |||
assertThat(db.getDbClient().propertiesDao().selectProjectProperties(prj2.getDbKey())) | |||
assertThat(db.getDbClient().projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, prj2.uuid())) | |||
.isEmpty(); | |||
assertThat(db.getDbClient().projectQgateAssociationDao().selectQGateUuidByComponentUuid(dbSession, prj1.uuid())) |
@@ -42,7 +42,6 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_GATES; | |||
import static org.sonar.server.qualitygate.QualityGateFinder.SONAR_QUALITYGATE_PROPERTY; | |||
public class SelectActionTest { | |||
@@ -341,7 +340,6 @@ public class SelectActionTest { | |||
} | |||
private void assertSelected(QualityGateDto qualityGate, ComponentDto project) { | |||
assertThat(dbClient.propertiesDao().selectProjectProperty(project.getId(), SONAR_QUALITYGATE_PROPERTY).getValue()).isEqualTo(qualityGate.getId().toString()); | |||
Optional<String> qGateUuid = db.qualityGates().selectQGateUuidByComponentUuid(project.uuid()); | |||
assertThat(qGateUuid) | |||
.isNotNull() |