aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-07-29 11:08:56 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-07-29 14:53:13 +0200
commit3e3e4b1e16c0e5ebf8a485d3014cb7bd2577e192 (patch)
tree6cccc368df16e99ca836a7626762f75de5a62b4d
parent88c26b4030c29372e57847eed22646b259d1a9c1 (diff)
downloadsonarqube-3e3e4b1e16c0e5ebf8a485d3014cb7bd2577e192.tar.gz
sonarqube-3e3e4b1e16c0e5ebf8a485d3014cb7bd2577e192.zip
SONAR-7923 Create WS api/qualitygates/get_by_project
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java34
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java69
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java67
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java15
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java134
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java41
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java19
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java15
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/get_by_project-example.json7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java35
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java113
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java245
-rw-r--r--sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java11
-rw-r--r--sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java9
-rw-r--r--sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java2
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml9
-rw-r--r--sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java65
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java11
-rw-r--r--sonar-ws/src/main/protobuf/ws-qualitygates.proto11
31 files changed, 749 insertions, 240 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index f64df96c3e8..0a41ac2a4a2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -180,18 +180,7 @@ import org.sonar.server.plugins.ws.UpdatesAction;
import org.sonar.server.project.ws.ProjectsWsModule;
import org.sonar.server.projectlink.ws.ProjectLinksModule;
import org.sonar.server.properties.ProjectSettingsFactory;
-import org.sonar.server.qualitygate.QgateProjectFinder;
-import org.sonar.server.qualitygate.QualityGates;
-import org.sonar.server.qualitygate.ws.CreateConditionAction;
-import org.sonar.server.qualitygate.ws.DeleteConditionAction;
-import org.sonar.server.qualitygate.ws.DeselectAction;
-import org.sonar.server.qualitygate.ws.DestroyAction;
-import org.sonar.server.qualitygate.ws.ProjectStatusAction;
-import org.sonar.server.qualitygate.ws.QualityGatesWs;
-import org.sonar.server.qualitygate.ws.SelectAction;
-import org.sonar.server.qualitygate.ws.SetAsDefaultAction;
-import org.sonar.server.qualitygate.ws.UnsetDefaultAction;
-import org.sonar.server.qualitygate.ws.UpdateConditionAction;
+import org.sonar.server.qualitygate.QualityGateModule;
import org.sonar.server.qualityprofile.BuiltInProfiles;
import org.sonar.server.qualityprofile.QProfileBackuper;
import org.sonar.server.qualityprofile.QProfileComparison;
@@ -462,26 +451,7 @@ public class PlatformLevel4 extends PlatformLevel {
DefaultMetricFinder.class,
TimeMachineWs.class,
- // quality gates
- QualityGates.class,
- QgateProjectFinder.class,
- org.sonar.server.qualitygate.ws.ListAction.class,
- org.sonar.server.qualitygate.ws.SearchAction.class,
- org.sonar.server.qualitygate.ws.ShowAction.class,
- org.sonar.server.qualitygate.ws.CreateAction.class,
- org.sonar.server.qualitygate.ws.RenameAction.class,
- org.sonar.server.qualitygate.ws.CopyAction.class,
- DestroyAction.class,
- SetAsDefaultAction.class,
- UnsetDefaultAction.class,
- SelectAction.class,
- DeselectAction.class,
- CreateConditionAction.class,
- DeleteConditionAction.class,
- UpdateConditionAction.class,
- org.sonar.server.qualitygate.ws.AppAction.class,
- ProjectStatusAction.class,
- QualityGatesWs.class,
+ QualityGateModule.class,
// web services
WebServiceEngine.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
new file mode 100644
index 00000000000..4999167b855
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
@@ -0,0 +1,69 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.qualitygate;
+
+import org.sonar.core.platform.Module;
+import org.sonar.server.qualitygate.ws.AppAction;
+import org.sonar.server.qualitygate.ws.CopyAction;
+import org.sonar.server.qualitygate.ws.CreateAction;
+import org.sonar.server.qualitygate.ws.CreateConditionAction;
+import org.sonar.server.qualitygate.ws.DeleteConditionAction;
+import org.sonar.server.qualitygate.ws.DeselectAction;
+import org.sonar.server.qualitygate.ws.DestroyAction;
+import org.sonar.server.qualitygate.ws.GetByProjectAction;
+import org.sonar.server.qualitygate.ws.ListAction;
+import org.sonar.server.qualitygate.ws.ProjectStatusAction;
+import org.sonar.server.qualitygate.ws.QualityGatesWs;
+import org.sonar.server.qualitygate.ws.RenameAction;
+import org.sonar.server.qualitygate.ws.SearchAction;
+import org.sonar.server.qualitygate.ws.SelectAction;
+import org.sonar.server.qualitygate.ws.SetAsDefaultAction;
+import org.sonar.server.qualitygate.ws.ShowAction;
+import org.sonar.server.qualitygate.ws.UnsetDefaultAction;
+import org.sonar.server.qualitygate.ws.UpdateConditionAction;
+
+public class QualityGateModule extends Module {
+ @Override
+ protected void configureModule() {
+ add(
+ QualityGates.class,
+ QgateProjectFinder.class,
+ // WS
+ QualityGatesWs.class,
+ ListAction.class,
+ SearchAction.class,
+ ShowAction.class,
+ CreateAction.class,
+ RenameAction.class,
+ CopyAction.class,
+ DestroyAction.class,
+ SetAsDefaultAction.class,
+ UnsetDefaultAction.class,
+ SelectAction.class,
+ DeselectAction.class,
+ CreateConditionAction.class,
+ DeleteConditionAction.class,
+ UpdateConditionAction.class,
+ AppAction.class,
+ ProjectStatusAction.class,
+ GetByProjectAction.class);
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java
index 9925fb6eb5e..786f38ed803 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java
@@ -21,15 +21,14 @@ package org.sonar.server.qualitygate;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
import java.util.Collection;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.ibatis.session.SqlSession;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
@@ -37,6 +36,7 @@ import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
import org.sonar.db.component.ComponentDao;
@@ -56,7 +56,6 @@ import org.sonar.server.exceptions.ServerException;
import org.sonar.server.user.UserSession;
import org.sonar.server.util.Validation;
-import static com.google.common.collect.FluentIterable.from;
import static java.lang.String.format;
/**
@@ -66,23 +65,22 @@ public class QualityGates {
public static final String SONAR_QUALITYGATE_PROPERTY = "sonar.qualitygate";
+ private final DbClient dbClient;
private final QualityGateDao dao;
private final QualityGateConditionDao conditionDao;
private final MetricFinder metricFinder;
private final PropertiesDao propertiesDao;
private final ComponentDao componentDao;
- private final MyBatis myBatis;
private final UserSession userSession;
private final Settings settings;
- public QualityGates(QualityGateDao dao, QualityGateConditionDao conditionDao, MetricFinder metricFinder, PropertiesDao propertiesDao, ComponentDao componentDao,
- MyBatis myBatis, UserSession userSession, Settings settings) {
- this.dao = dao;
- this.conditionDao = conditionDao;
+ public QualityGates(DbClient dbClient, MetricFinder metricFinder, UserSession userSession, Settings settings) {
+ this.dbClient = dbClient;
+ this.dao = dbClient.qualityGateDao();
+ this.conditionDao = dbClient.gateConditionDao();
this.metricFinder = metricFinder;
- this.propertiesDao = propertiesDao;
- this.componentDao = componentDao;
- this.myBatis = myBatis;
+ this.propertiesDao = dbClient.propertiesDao();
+ this.componentDao = dbClient.componentDao();
this.userSession = userSession;
this.settings = settings;
}
@@ -117,18 +115,18 @@ public class QualityGates {
getNonNullQgate(sourceId);
validateQualityGate(null, destinationName);
QualityGateDto destinationGate = new QualityGateDto().setName(destinationName);
- SqlSession session = myBatis.openSession(false);
+ DbSession dbSession = dbClient.openSession(false);
try {
- dao.insert(destinationGate, session);
- for (QualityGateConditionDto sourceCondition : conditionDao.selectForQualityGate(sourceId, session)) {
+ dao.insert(dbSession, destinationGate);
+ for (QualityGateConditionDto sourceCondition : conditionDao.selectForQualityGate(sourceId, dbSession)) {
conditionDao.insert(new QualityGateConditionDto().setQualityGateId(destinationGate.getId())
.setMetricId(sourceCondition.getMetricId()).setOperator(sourceCondition.getOperator())
.setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()).setPeriod(sourceCondition.getPeriod()),
- session);
+ dbSession);
}
- session.commit();
+ dbSession.commit();
} finally {
- MyBatis.closeQuietly(session);
+ MyBatis.closeQuietly(dbSession);
}
return destinationGate;
}
@@ -140,7 +138,7 @@ public class QualityGates {
public void delete(long idToDelete) {
checkPermission();
QualityGateDto qGate = getNonNullQgate(idToDelete);
- DbSession session = myBatis.openSession(false);
+ DbSession session = dbClient.openSession(false);
try {
if (isDefault(qGate)) {
propertiesDao.deleteGlobalProperty(SONAR_QUALITYGATE_PROPERTY, session);
@@ -228,7 +226,7 @@ public class QualityGates {
}
public void associateProject(Long qGateId, Long projectId) {
- DbSession session = myBatis.openSession(false);
+ DbSession session = dbClient.openSession(false);
try {
getNonNullQgate(qGateId);
checkPermission(projectId, session);
@@ -239,7 +237,7 @@ public class QualityGates {
}
public void dissociateProject(Long qGateId, Long projectId) {
- DbSession session = myBatis.openSession(false);
+ DbSession session = dbClient.openSession(false);
try {
getNonNullQgate(qGateId);
checkPermission(projectId, session);
@@ -250,12 +248,9 @@ public class QualityGates {
}
public Collection<Metric> gateMetrics() {
- return Collections2.filter(metricFinder.findAll(), new Predicate<Metric>() {
- @Override
- public boolean apply(Metric metric) {
- return isAvailableForInit(metric);
- }
- });
+ return metricFinder.findAll().stream()
+ .filter(QualityGates::isAvailableForInit)
+ .collect(Collectors.toList());
}
public boolean currentUserHasWritePermission() {
@@ -274,7 +269,9 @@ public class QualityGates {
if (conditionId == null) {
return conditions;
}
- return from(conditionDao.selectForQualityGate(qGateId)).filter(new MatchConditionId(conditionId)).toList();
+ return conditionDao.selectForQualityGate(qGateId).stream()
+ .filter(condition -> condition.getId() != conditionId)
+ .collect(Collectors.toList());
}
private static void validateCondition(Metric metric, String operator, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) {
@@ -293,7 +290,7 @@ public class QualityGates {
return;
}
- boolean conditionExists = from(conditions).anyMatch(new MatchMetricAndPeriod(metric.getId(), period));
+ boolean conditionExists = conditions.stream().anyMatch(new MatchMetricAndPeriod(metric.getId(), period)::apply);
if (conditionExists) {
String errorMessage = period == null
? format("Condition on metric '%s' already exists.", metric.getName())
@@ -421,18 +418,4 @@ public class QualityGates {
ObjectUtils.equals(input.getPeriod(), period);
}
}
-
- private static class MatchConditionId implements Predicate<QualityGateConditionDto> {
- private final long conditionId;
-
- private MatchConditionId(long conditionId) {
- this.conditionId = conditionId;
- }
-
- @Override
- public boolean apply(@Nonnull QualityGateConditionDto input) {
- return input.getId() != conditionId;
- }
- }
-
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java
index 89e77f7998e..21e56bf8e37 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CopyAction.java
@@ -26,6 +26,9 @@ import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.qualitygate.QualityGates;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_NAME;
+
public class CopyAction implements QualityGatesWsAction {
private final QualityGates qualityGates;
@@ -42,12 +45,12 @@ public class CopyAction implements QualityGatesWsAction {
.setSince("4.3")
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(PARAM_ID)
.setDescription("The ID of the source quality gate")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_NAME)
+ action.createParam(PARAM_NAME)
.setDescription("The name of the quality gate to create")
.setRequired(true)
.setExampleValue("My Quality Gate");
@@ -55,7 +58,7 @@ public class CopyAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- QualityGateDto newQualityGate = qualityGates.copy(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID), request.mandatoryParam(QualityGatesWs.PARAM_NAME));
+ QualityGateDto newQualityGate = qualityGates.copy(QualityGatesWs.parseId(request, PARAM_ID), request.mandatoryParam(PARAM_NAME));
JsonWriter writer = response.newJsonWriter();
QualityGatesWs.writeQualityGate(newQualityGate, writer).close();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java
index 5ddc735e02b..49b2e837d7c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java
@@ -25,6 +25,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class CreateAction implements QualityGatesWsAction {
@@ -42,7 +43,7 @@ public class CreateAction implements QualityGatesWsAction {
.setPost(true)
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_NAME)
+ action.createParam(QualityGatesWsParameters.PARAM_NAME)
.setDescription("The name of the quality gate to create")
.setRequired(true)
.setExampleValue("My Quality Gate");
@@ -50,7 +51,7 @@ public class CreateAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QualityGatesWs.PARAM_NAME));
+ QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QualityGatesWsParameters.PARAM_NAME));
JsonWriter writer = response.newJsonWriter();
QualityGatesWs.writeQualityGate(newQualityGate, writer).close();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
index aa572402040..fbaf599cea6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateConditionAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class CreateConditionAction implements QualityGatesWsAction {
@@ -41,7 +42,7 @@ public class CreateConditionAction implements QualityGatesWsAction {
.setHandler(this);
createCondition
- .createParam(QualityGatesWs.PARAM_GATE_ID)
+ .createParam(QualityGatesWsParameters.PARAM_GATE_ID)
.setDescription("ID of the quality gate")
.setRequired(true)
.setExampleValue("1");
@@ -53,12 +54,12 @@ public class CreateConditionAction implements QualityGatesWsAction {
public void handle(Request request, Response response) {
QualityGatesWs.writeQualityGateCondition(
qualityGates.createCondition(
- QualityGatesWs.parseId(request, QualityGatesWs.PARAM_GATE_ID),
- request.mandatoryParam(QualityGatesWs.PARAM_METRIC),
- request.mandatoryParam(QualityGatesWs.PARAM_OPERATOR),
- request.param(QualityGatesWs.PARAM_WARNING),
- request.param(QualityGatesWs.PARAM_ERROR),
- request.paramAsInt(QualityGatesWs.PARAM_PERIOD)
+ QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_GATE_ID),
+ request.mandatoryParam(QualityGatesWsParameters.PARAM_METRIC),
+ request.mandatoryParam(QualityGatesWsParameters.PARAM_OPERATOR),
+ request.param(QualityGatesWsParameters.PARAM_WARNING),
+ request.param(QualityGatesWsParameters.PARAM_ERROR),
+ request.paramAsInt(QualityGatesWsParameters.PARAM_PERIOD)
), response.newJsonWriter()
).close();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java
index cd1f94f0f9a..24510b91298 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeleteConditionAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class DeleteConditionAction implements QualityGatesWsAction {
@@ -41,7 +42,7 @@ public class DeleteConditionAction implements QualityGatesWsAction {
.setHandler(this);
createCondition
- .createParam(QualityGatesWs.PARAM_ID)
+ .createParam(QualityGatesWsParameters.PARAM_ID)
.setRequired(true)
.setDescription("Condition ID")
.setExampleValue("2");
@@ -49,7 +50,7 @@ public class DeleteConditionAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- qualityGates.deleteCondition(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID));
+ qualityGates.deleteCondition(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_ID));
response.noContent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java
index 1f1bfee0a47..0579676dfcb 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DeselectAction.java
@@ -23,6 +23,9 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
+
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
public class DeselectAction implements QualityGatesWsAction {
@@ -40,12 +43,12 @@ public class DeselectAction implements QualityGatesWsAction {
.setSince("4.3")
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_GATE_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_GATE_ID)
.setDescription("Quality Gate ID")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_PROJECT_ID)
+ action.createParam(PARAM_PROJECT_ID)
.setDescription("Project ID")
.setRequired(true)
.setExampleValue("12");
@@ -53,7 +56,7 @@ public class DeselectAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- qualityGates.dissociateProject(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_GATE_ID), QualityGatesWs.parseId(request, QualityGatesWs.PARAM_PROJECT_ID));
+ qualityGates.dissociateProject(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_GATE_ID), QualityGatesWs.parseId(request, PARAM_PROJECT_ID));
response.noContent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java
index 654a693e7f0..97e5e60080e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/DestroyAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class DestroyAction implements QualityGatesWsAction {
@@ -40,7 +41,7 @@ public class DestroyAction implements QualityGatesWsAction {
.setPost(true)
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("ID of the quality gate to delete")
.setRequired(true)
.setExampleValue("1");
@@ -48,7 +49,7 @@ public class DestroyAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- qualityGates.delete(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID));
+ qualityGates.delete(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_ID));
response.noContent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java
new file mode 100644
index 00000000000..2fbb8d03f4b
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java
@@ -0,0 +1,134 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.qualitygate.ws;
+
+import java.util.Optional;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.component.ComponentFinder.ParamNames;
+import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.WsQualityGates.GetByProjectWsResponse;
+
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
+
+public class GetByProjectAction implements QualityGatesWsAction {
+ private final UserSession userSession;
+ private final DbClient dbClient;
+ private final ComponentFinder componentFinder;
+ private final QualityGates qualityGates;
+
+ public GetByProjectAction(UserSession userSession, DbClient dbClient, ComponentFinder componentFinder, QualityGates qualityGates) {
+ this.userSession = userSession;
+ this.dbClient = dbClient;
+ this.componentFinder = componentFinder;
+ this.qualityGates = qualityGates;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction("get_by_project")
+ .setInternal(true)
+ .setSince("6.1")
+ .setDescription("Get the quality gate of a project.<br> " +
+ "Either project id or project key must be provided, not both.")
+ .setResponseExample(getClass().getResource("get_by_project-example.json"))
+ .setHandler(this);
+
+ action.createParam(PARAM_PROJECT_ID)
+ .setDescription("Project id")
+ .setExampleValue(UUID_EXAMPLE_01);
+
+ action.createParam(PARAM_PROJECT_KEY)
+ .setDescription("Project key")
+ .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ ComponentDto project = getProject(dbSession, request.param(PARAM_PROJECT_ID), request.param(PARAM_PROJECT_KEY));
+ QualityGateData data = getQualityGate(dbSession, project.getId());
+
+ writeProtobuf(buildResponse(data), request, response);
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+ }
+
+ private ComponentDto getProject(DbSession dbSession, String projectUuid, String projectKey) {
+ ComponentDto project = componentFinder.getByUuidOrKey(dbSession, projectUuid, projectKey, ParamNames.PROJECT_ID_AND_KEY);
+
+ if (!userSession.hasComponentUuidPermission(UserRole.USER, projectUuid) &&
+ !userSession.hasComponentUuidPermission(UserRole.ADMIN, projectUuid)) {
+ throw insufficientPrivilegesException();
+ }
+
+ return project;
+ }
+
+ private static GetByProjectWsResponse buildResponse(QualityGateData data) {
+ if (!data.qualityGate.isPresent()) {
+ return GetByProjectWsResponse.getDefaultInstance();
+ }
+
+ QualityGateDto qualityGate = data.qualityGate.get();
+ GetByProjectWsResponse.Builder response = GetByProjectWsResponse.newBuilder();
+
+ response.getQualityGateBuilder()
+ .setId(String.valueOf(qualityGate.getId()))
+ .setName(qualityGate.getName())
+ .setDefault(data.isDefault);
+
+ return response.build();
+ }
+
+ private QualityGateData getQualityGate(DbSession dbSession, long componentId) {
+ Optional<Long> qualityGateId = dbClient.projectQgateAssociationDao().selectQGateIdByComponentId(dbSession, componentId);
+
+ return qualityGateId.isPresent()
+ ? new QualityGateData(Optional.ofNullable(dbClient.qualityGateDao().selectById(dbSession, qualityGateId.get())), false)
+ : new QualityGateData(Optional.ofNullable(qualityGates.getDefault()), true);
+ }
+
+ private static class QualityGateData {
+ private final Optional<QualityGateDto> qualityGate;
+ private final boolean isDefault;
+
+ private QualityGateData(Optional<QualityGateDto> qualityGate, boolean isDefault) {
+ this.qualityGate = qualityGate;
+ this.isDefault = isDefault;
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
index fc98402788a..8e103f8e235 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
@@ -25,22 +25,9 @@ import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class QualityGatesWs implements WebService {
-
- static final String PARAM_PAGE_SIZE = "pageSize";
- static final String PARAM_PAGE = "page";
- static final String PARAM_QUERY = "query";
- static final String PARAM_NAME = "name";
- static final String PARAM_ERROR = "error";
- static final String PARAM_WARNING = "warning";
- static final String PARAM_PERIOD = "period";
- static final String PARAM_OPERATOR = "op";
- static final String PARAM_METRIC = "metric";
- static final String PARAM_GATE_ID = "gateId";
- static final String PARAM_PROJECT_ID = "projectId";
- static final String PARAM_ID = "id";
-
private final QualityGatesWsAction[] actions;
public QualityGatesWs(QualityGatesWsAction... actions) {
@@ -62,12 +49,12 @@ public class QualityGatesWs implements WebService {
static void addConditionParams(NewAction action) {
action
- .createParam(PARAM_METRIC)
+ .createParam(QualityGatesWsParameters.PARAM_METRIC)
.setDescription("Condition metric")
.setRequired(true)
.setExampleValue("blocker_violations");
- action.createParam(PARAM_OPERATOR)
+ action.createParam(QualityGatesWsParameters.PARAM_OPERATOR)
.setDescription("Condition operator:<br/>" +
"<ul>" +
"<li>EQ = equals</li>" +
@@ -78,15 +65,15 @@ public class QualityGatesWs implements WebService {
.setExampleValue(QualityGateConditionDto.OPERATOR_EQUALS)
.setPossibleValues(QualityGateConditionDto.ALL_OPERATORS);
- action.createParam(PARAM_PERIOD)
+ action.createParam(QualityGatesWsParameters.PARAM_PERIOD)
.setDescription("Condition period. If not set, the absolute value is considered.")
.setPossibleValues("1");
- action.createParam(PARAM_WARNING)
+ action.createParam(QualityGatesWsParameters.PARAM_WARNING)
.setDescription("Condition warning threshold")
.setExampleValue("5");
- action.createParam(PARAM_ERROR)
+ action.createParam(QualityGatesWsParameters.PARAM_ERROR)
.setDescription("Condition error threshold")
.setExampleValue("10");
}
@@ -101,24 +88,24 @@ public class QualityGatesWs implements WebService {
static JsonWriter writeQualityGate(QualityGateDto qualityGate, JsonWriter writer) {
return writer.beginObject()
- .prop(PARAM_ID, qualityGate.getId())
- .prop(PARAM_NAME, qualityGate.getName())
+ .prop(QualityGatesWsParameters.PARAM_ID, qualityGate.getId())
+ .prop(QualityGatesWsParameters.PARAM_NAME, qualityGate.getName())
.endObject();
}
static JsonWriter writeQualityGateCondition(QualityGateConditionDto condition, JsonWriter writer) {
writer.beginObject()
- .prop(PARAM_ID, condition.getId())
- .prop(PARAM_METRIC, condition.getMetricKey())
- .prop(PARAM_OPERATOR, condition.getOperator());
+ .prop(QualityGatesWsParameters.PARAM_ID, condition.getId())
+ .prop(QualityGatesWsParameters.PARAM_METRIC, condition.getMetricKey())
+ .prop(QualityGatesWsParameters.PARAM_OPERATOR, condition.getOperator());
if (condition.getWarningThreshold() != null) {
- writer.prop(PARAM_WARNING, condition.getWarningThreshold());
+ writer.prop(QualityGatesWsParameters.PARAM_WARNING, condition.getWarningThreshold());
}
if (condition.getErrorThreshold() != null) {
- writer.prop(PARAM_ERROR, condition.getErrorThreshold());
+ writer.prop(QualityGatesWsParameters.PARAM_ERROR, condition.getErrorThreshold());
}
if (condition.getPeriod() != null) {
- writer.prop(PARAM_PERIOD, condition.getPeriod());
+ writer.prop(QualityGatesWsParameters.PARAM_PERIOD, condition.getPeriod());
}
writer.endObject();
return writer;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java
index ca685d7fb61..af0231d6e90 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/RenameAction.java
@@ -25,6 +25,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class RenameAction implements QualityGatesWsAction {
@@ -42,12 +43,12 @@ public class RenameAction implements QualityGatesWsAction {
.setPost(true)
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("ID of the quality gate to rename")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_NAME)
+ action.createParam(QualityGatesWsParameters.PARAM_NAME)
.setDescription("New name of the quality gate")
.setRequired(true)
.setExampleValue("My Quality Gate");
@@ -55,8 +56,8 @@ public class RenameAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- long idToRename = QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID);
- QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(QualityGatesWs.PARAM_NAME));
+ long idToRename = QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_ID);
+ QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(QualityGatesWsParameters.PARAM_NAME));
JsonWriter writer = response.newJsonWriter();
QualityGatesWs.writeQualityGate(renamedQualityGate, writer).close();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
index 8f57e3bf59d..cfdc0004ad5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SearchAction.java
@@ -28,6 +28,7 @@ import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
import org.sonar.server.qualitygate.QgateProjectFinder;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class SearchAction implements QualityGatesWsAction {
@@ -46,23 +47,23 @@ public class SearchAction implements QualityGatesWsAction {
.setResponseExample(Resources.getResource(this.getClass(), "example-search.json"))
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_GATE_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_GATE_ID)
.setDescription("Quality Gate ID")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_QUERY)
+ action.createParam(QualityGatesWsParameters.PARAM_QUERY)
.setDescription("To search for projects containing this string. If this parameter is set, \"selected\" is set to \"all\".")
.setExampleValue("abc");
action.addSelectionModeParam();
- action.createParam(QualityGatesWs.PARAM_PAGE)
+ action.createParam(QualityGatesWsParameters.PARAM_PAGE)
.setDescription("Page number")
.setDefaultValue("1")
.setExampleValue("2");
- action.createParam(QualityGatesWs.PARAM_PAGE_SIZE)
+ action.createParam(QualityGatesWsParameters.PARAM_PAGE_SIZE)
.setDescription("Page size")
.setExampleValue("10");
}
@@ -70,11 +71,11 @@ public class SearchAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder()
- .gateId(request.mandatoryParam(QualityGatesWs.PARAM_GATE_ID))
- .membership(request.param(QualityGatesWs.PARAM_QUERY) == null ? request.param(Param.SELECTED) : ProjectQgateAssociationQuery.ANY)
- .projectSearch(request.param(QualityGatesWs.PARAM_QUERY))
- .pageIndex(request.paramAsInt(QualityGatesWs.PARAM_PAGE))
- .pageSize(request.paramAsInt(QualityGatesWs.PARAM_PAGE_SIZE))
+ .gateId(request.mandatoryParam(QualityGatesWsParameters.PARAM_GATE_ID))
+ .membership(request.param(QualityGatesWsParameters.PARAM_QUERY) == null ? request.param(Param.SELECTED) : ProjectQgateAssociationQuery.ANY)
+ .projectSearch(request.param(QualityGatesWsParameters.PARAM_QUERY))
+ .pageIndex(request.paramAsInt(QualityGatesWsParameters.PARAM_PAGE))
+ .pageSize(request.paramAsInt(QualityGatesWsParameters.PARAM_PAGE_SIZE))
.build());
JsonWriter writer = response.newJsonWriter();
writer.beginObject().prop("more", associations.hasMoreResults());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
index 4afdc7ae8c5..8f55ba0d85e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
@@ -23,6 +23,9 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
+
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
public class SelectAction implements QualityGatesWsAction {
@@ -40,12 +43,12 @@ public class SelectAction implements QualityGatesWsAction {
.setSince("4.3")
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_GATE_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_GATE_ID)
.setDescription("Quality Gate ID")
.setRequired(true)
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_PROJECT_ID)
+ action.createParam(PARAM_PROJECT_ID)
.setDescription("Project ID")
.setRequired(true)
.setExampleValue("12");
@@ -53,7 +56,7 @@ public class SelectAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- qualityGates.associateProject(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_GATE_ID), QualityGatesWs.parseId(request, QualityGatesWs.PARAM_PROJECT_ID));
+ qualityGates.associateProject(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_GATE_ID), QualityGatesWs.parseId(request, PARAM_PROJECT_ID));
response.noContent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java
index 38990131f9b..b9edc97e1e0 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SetAsDefaultAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class SetAsDefaultAction implements QualityGatesWsAction {
@@ -40,7 +41,7 @@ public class SetAsDefaultAction implements QualityGatesWsAction {
.setPost(true)
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("ID of the quality gate to set as default")
.setRequired(true)
.setExampleValue("1");
@@ -48,7 +49,7 @@ public class SetAsDefaultAction implements QualityGatesWsAction {
@Override
public void handle(Request request, Response response) {
- qualityGates.setDefault(QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID));
+ qualityGates.setDefault(QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_ID));
response.noContent();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
index cb447eb653c..0709867d1f2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
@@ -30,6 +30,7 @@ import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class ShowAction implements QualityGatesWsAction {
@@ -47,27 +48,27 @@ public class ShowAction implements QualityGatesWsAction {
.setResponseExample(Resources.getResource(this.getClass(), "example-show.json"))
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("ID of the quality gate. Either id or name must be set")
.setExampleValue("1");
- action.createParam(QualityGatesWs.PARAM_NAME)
+ action.createParam(QualityGatesWsParameters.PARAM_NAME)
.setDescription("Name of the quality gate. Either id or name must be set")
.setExampleValue("My Quality Gate");
}
@Override
public void handle(Request request, Response response) {
- Long qGateId = request.paramAsLong(QualityGatesWs.PARAM_ID);
- String qGateName = request.param(QualityGatesWs.PARAM_NAME);
+ Long qGateId = request.paramAsLong(QualityGatesWsParameters.PARAM_ID);
+ String qGateName = request.param(QualityGatesWsParameters.PARAM_NAME);
checkOneOfIdOrNamePresent(qGateId, qGateName);
QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId);
qGateId = qGate.getId();
JsonWriter writer = response.newJsonWriter().beginObject()
- .prop(QualityGatesWs.PARAM_ID, qGate.getId())
- .prop(QualityGatesWs.PARAM_NAME, qGate.getName());
+ .prop(QualityGatesWsParameters.PARAM_ID, qGate.getId())
+ .prop(QualityGatesWsParameters.PARAM_NAME, qGate.getName());
Collection<QualityGateConditionDto> conditions = qualityGates.listConditions(qGateId);
if (!conditions.isEmpty()) {
writer.name("conditions").beginArray();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java
index 29e905000ba..5945255045b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UnsetDefaultAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class UnsetDefaultAction implements QualityGatesWsAction {
@@ -40,7 +41,7 @@ public class UnsetDefaultAction implements QualityGatesWsAction {
.setPost(true)
.setHandler(this);
- action.createParam(QualityGatesWs.PARAM_ID)
+ action.createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("ID of the quality gate to unset as default")
.setRequired(true)
.setExampleValue("1");
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
index 111d68fc5ce..1c9f637a59e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/UpdateConditionAction.java
@@ -23,6 +23,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.qualitygate.QualityGates;
+import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
public class UpdateConditionAction implements QualityGatesWsAction {
@@ -41,7 +42,7 @@ public class UpdateConditionAction implements QualityGatesWsAction {
.setHandler(this);
createCondition
- .createParam(QualityGatesWs.PARAM_ID)
+ .createParam(QualityGatesWsParameters.PARAM_ID)
.setDescription("Condition ID")
.setRequired(true)
.setExampleValue("10");
@@ -53,12 +54,12 @@ public class UpdateConditionAction implements QualityGatesWsAction {
public void handle(Request request, Response response) {
QualityGatesWs.writeQualityGateCondition(
qualityGates.updateCondition(
- QualityGatesWs.parseId(request, QualityGatesWs.PARAM_ID),
- request.mandatoryParam(QualityGatesWs.PARAM_METRIC),
- request.mandatoryParam(QualityGatesWs.PARAM_OPERATOR),
- request.param(QualityGatesWs.PARAM_WARNING),
- request.param(QualityGatesWs.PARAM_ERROR),
- request.paramAsInt(QualityGatesWs.PARAM_PERIOD)
+ QualityGatesWs.parseId(request, QualityGatesWsParameters.PARAM_ID),
+ request.mandatoryParam(QualityGatesWsParameters.PARAM_METRIC),
+ request.mandatoryParam(QualityGatesWsParameters.PARAM_OPERATOR),
+ request.param(QualityGatesWsParameters.PARAM_WARNING),
+ request.param(QualityGatesWsParameters.PARAM_ERROR),
+ request.paramAsInt(QualityGatesWsParameters.PARAM_PERIOD)
), response.newJsonWriter()
).close();
}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/get_by_project-example.json b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/get_by_project-example.json
new file mode 100644
index 00000000000..3cf49b85ded
--- /dev/null
+++ b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/get_by_project-example.json
@@ -0,0 +1,7 @@
+{
+ "qualityGate": {
+ "id": "23",
+ "name": "My team QG",
+ "default": false
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
index 66360314728..a35f3b095f8 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
@@ -83,7 +83,7 @@ public class QgateProjectFinderTest {
dbClient.userDao().insert(dbSession, userDto);
qGate = new QualityGateDto().setName("Default Quality Gate");
- dbClient.qualityGateDao().insert(qGate, dbSession);
+ dbClient.qualityGateDao().insert(dbSession, qGate);
dbTester.commit();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
new file mode 100644
index 00000000000..0ea94b7f023
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.qualitygate;
+
+import org.junit.Test;
+import org.sonar.core.platform.ComponentContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class QualityGateModuleTest {
+ @Test
+ public void verify_count_of_added_components() {
+ ComponentContainer container = new ComponentContainer();
+ new QualityGateModule().configure(container);
+ assertThat(container.size()).isEqualTo(20 + 2);
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java
index 56f401ab687..ec9af1871e2 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java
@@ -19,18 +19,6 @@
*/
package org.sonar.server.qualitygate;
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.Collection;
@@ -44,11 +32,8 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
@@ -56,8 +41,8 @@ import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.property.PropertiesDao;
@@ -74,6 +59,18 @@ import org.sonar.server.tester.MockUserSession;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.user.UserSession;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
@RunWith(MockitoJUnitRunner.class)
public class QualityGatesTest {
@@ -82,31 +79,16 @@ public class QualityGatesTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
-
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
- @Mock
- DbSession session;
-
- @Mock
- QualityGateDao dao;
-
- @Mock
- QualityGateConditionDao conditionDao;
-
- @Mock
- MetricFinder metricFinder;
-
- @Mock
- PropertiesDao propertiesDao;
-
- @Mock
- ComponentDao componentDao;
-
- @Mock
- MyBatis myBatis;
-
+ DbSession dbSession = mock(DbSession.class);
+ DbClient dbClient = mock(DbClient.class);
+ QualityGateDao dao = mock(QualityGateDao.class);
+ QualityGateConditionDao conditionDao = mock(QualityGateConditionDao.class);
+ PropertiesDao propertiesDao = mock(PropertiesDao.class);
+ ComponentDao componentDao = mock(ComponentDao.class);
+ MetricFinder metricFinder = mock(MetricFinder.class);
Settings settings = new Settings();
QualityGates underTest;
@@ -122,10 +104,15 @@ public class QualityGatesTest {
public void initialize() {
settings.clear();
- when(componentDao.selectOrFailById(eq(session), anyLong())).thenReturn(new ComponentDto().setId(1L).setKey(PROJECT_KEY));
+ when(dbClient.openSession(false)).thenReturn(dbSession);
+ when(dbClient.qualityGateDao()).thenReturn(dao);
+ when(dbClient.gateConditionDao()).thenReturn(conditionDao);
+ when(dbClient.propertiesDao()).thenReturn(propertiesDao);
+ when(dbClient.componentDao()).thenReturn(componentDao);
+
+ when(componentDao.selectOrFailById(eq(dbSession), anyLong())).thenReturn(new ComponentDto().setId(1L).setKey(PROJECT_KEY));
- when(myBatis.openSession(false)).thenReturn(session);
- underTest = new QualityGates(dao, conditionDao, metricFinder, propertiesDao, componentDao, myBatis, userSessionRule, settings);
+ underTest = new QualityGates(dbClient, metricFinder, userSessionRule, settings);
userSessionRule.set(authorizedProfileAdminUserSession);
}
@@ -270,12 +257,11 @@ public class QualityGatesTest {
String name = "To Delete";
QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName(name);
when(dao.selectById(idToDelete)).thenReturn(toDelete);
- DbSession session = mock(DbSession.class);
- when(myBatis.openSession(false)).thenReturn(session);
+ when(dbClient.openSession(false)).thenReturn(dbSession);
underTest.delete(idToDelete);
verify(dao).selectById(idToDelete);
- verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", session);
- verify(dao).delete(toDelete, session);
+ verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", dbSession);
+ verify(dao).delete(toDelete, dbSession);
}
@Test
@@ -285,12 +271,11 @@ public class QualityGatesTest {
QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName(name);
when(dao.selectById(idToDelete)).thenReturn(toDelete);
when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue("666"));
- DbSession session = mock(DbSession.class);
- when(myBatis.openSession(false)).thenReturn(session);
+ when(dbClient.openSession(false)).thenReturn(dbSession);
underTest.delete(idToDelete);
verify(dao).selectById(idToDelete);
- verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", session);
- verify(dao).delete(toDelete, session);
+ verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", dbSession);
+ verify(dao).delete(toDelete, dbSession);
}
@Test
@@ -300,13 +285,12 @@ public class QualityGatesTest {
QualityGateDto toDelete = new QualityGateDto().setId(idToDelete).setName(name);
when(dao.selectById(idToDelete)).thenReturn(toDelete);
when(propertiesDao.selectGlobalProperty("sonar.qualitygate")).thenReturn(new PropertyDto().setValue("42"));
- DbSession session = mock(DbSession.class);
- when(myBatis.openSession(false)).thenReturn(session);
+ when(dbClient.openSession(false)).thenReturn(dbSession);
underTest.delete(idToDelete);
verify(dao).selectById(idToDelete);
- verify(propertiesDao).deleteGlobalProperty("sonar.qualitygate", session);
- verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", session);
- verify(dao).delete(toDelete, session);
+ verify(propertiesDao).deleteGlobalProperty("sonar.qualitygate", dbSession);
+ verify(propertiesDao).deleteProjectProperties("sonar.qualitygate", "42", dbSession);
+ verify(dao).delete(toDelete, dbSession);
}
@Test
@@ -637,22 +621,17 @@ public class QualityGatesTest {
Collection<QualityGateConditionDto> conditions = ImmutableList.of(cond1, cond2);
when(dao.selectById(sourceId)).thenReturn(new QualityGateDto().setId(sourceId).setName("SG-1"));
- DbSession session = mock(DbSession.class);
- when(myBatis.openSession(false)).thenReturn(session);
- Mockito.doAnswer(new Answer<Object>() {
- @Override
- public Object answer(InvocationOnMock invocation) throws Throwable {
- ((QualityGateDto) invocation.getArguments()[0]).setId(destId);
- return null;
- }
- }).when(dao).insert(any(QualityGateDto.class), eq(session));
- when(conditionDao.selectForQualityGate(anyLong(), eq(session))).thenReturn(conditions);
+ Mockito.doAnswer(invocation -> {
+ ((QualityGateDto) invocation.getArguments()[1]).setId(destId);
+ return null;
+ }).when(dao).insert(eq(dbSession), any(QualityGateDto.class));
+ when(conditionDao.selectForQualityGate(anyLong(), eq(dbSession))).thenReturn(conditions);
QualityGateDto atlantis = underTest.copy(sourceId, name);
assertThat(atlantis.getName()).isEqualTo(name);
verify(dao).selectByName(name);
- verify(dao).insert(atlantis, session);
- verify(conditionDao).selectForQualityGate(anyLong(), eq(session));
- verify(conditionDao, times(conditions.size())).insert(any(QualityGateConditionDto.class), eq(session));
+ verify(dao).insert(dbSession, atlantis);
+ verify(conditionDao).selectForQualityGate(anyLong(), eq(dbSession));
+ verify(conditionDao, times(conditions.size())).insert(any(QualityGateConditionDto.class), eq(dbSession));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java
new file mode 100644
index 00000000000..17c1b684a15
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java
@@ -0,0 +1,245 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.qualitygate.ws;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.qualitygate.QualityGates;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsQualityGates;
+import org.sonarqube.ws.WsQualityGates.GetByProjectWsResponse;
+
+import static com.google.common.base.Throwables.propagate;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
+import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
+
+public class GetByProjectActionTest {
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+ ComponentDbTester componentDb = new ComponentDbTester(db);
+ DbClient dbClient = db.getDbClient();
+ DbSession dbSession = db.getSession();
+
+ private WsActionTester ws = new WsActionTester(
+ new GetByProjectAction(userSession, dbClient, new ComponentFinder(dbClient),
+ new QualityGates(dbClient, mock(MetricFinder.class), mock(UserSession.class), mock(Settings.class))));
+
+ @Test
+ public void json_example() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ QualityGateDto qualityGate = insertQualityGate("My team QG");
+ associateProjectToQualityGate(project.getId(), qualityGate.getId());
+
+ String result = ws.newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).execute().getInput();
+
+ assertJson(result)
+ .ignoreFields("id")
+ .isSimilarTo(getClass().getResource("get_by_project-example.json"));
+ }
+
+ @Test
+ public void empty_response() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ insertQualityGate("Another QG");
+
+ String result = ws.newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).execute().getInput();
+
+ assertThat(result).isEqualToIgnoringWhitespace("{}");
+ }
+
+ @Test
+ public void default_quality_gate() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ QualityGateDto dbQualityGate = insertQualityGate("Sonar way");
+ setDefaultQualityGate(dbQualityGate.getId());
+
+ GetByProjectWsResponse result = callByUuid(project.uuid());
+
+ WsQualityGates.QualityGate qualityGate = result.getQualityGate();
+ assertThat(Long.valueOf(qualityGate.getId())).isEqualTo(dbQualityGate.getId());
+ assertThat(qualityGate.getName()).isEqualTo(dbQualityGate.getName());
+ assertThat(qualityGate.getDefault()).isTrue();
+ }
+
+ @Test
+ public void project_quality_gate_over_default() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ QualityGateDto defaultDbQualityGate = insertQualityGate("Sonar way");
+ QualityGateDto dbQualityGate = insertQualityGate("My team QG");
+ setDefaultQualityGate(defaultDbQualityGate.getId());
+ associateProjectToQualityGate(project.getId(), dbQualityGate.getId());
+
+ GetByProjectWsResponse result = callByUuid(project.uuid());
+
+ WsQualityGates.QualityGate qualityGate = result.getQualityGate();
+ assertThat(qualityGate.getName()).isEqualTo(dbQualityGate.getName());
+ assertThat(qualityGate.getDefault()).isFalse();
+ }
+
+ @Test
+ public void get_by_project_key() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ QualityGateDto dbQualityGate = insertQualityGate("My team QG");
+ associateProjectToQualityGate(project.getId(), dbQualityGate.getId());
+
+ GetByProjectWsResponse result = callByKey(project.key());
+
+ assertThat(result.getQualityGate().getName()).isEqualTo(dbQualityGate.getName());
+ }
+
+ @Test
+ public void get_with_project_admin_permission() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ userSession.anonymous().addProjectUuidPermissions(UserRole.USER, project.uuid());
+ QualityGateDto dbQualityGate = insertQualityGate("Sonar way");
+ setDefaultQualityGate(dbQualityGate.getId());
+
+ GetByProjectWsResponse result = callByUuid(project.uuid());
+
+ assertThat(result.getQualityGate().getName()).isEqualTo(dbQualityGate.getName());
+ }
+
+ @Test
+ public void get_with_project_browse_permission() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ userSession.anonymous().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());
+ QualityGateDto dbQualityGate = insertQualityGate("Sonar way");
+ setDefaultQualityGate(dbQualityGate.getId());
+
+ GetByProjectWsResponse result = callByUuid(project.uuid());
+
+ assertThat(result.getQualityGate().getName()).isEqualTo(dbQualityGate.getName());
+ }
+
+ @Test
+ public void fail_when_insufficient_permission() {
+ expectedException.expect(ForbiddenException.class);
+
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+ userSession.anonymous().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ QualityGateDto dbQualityGate = insertQualityGate("Sonar way");
+ setDefaultQualityGate(dbQualityGate.getId());
+
+ callByUuid(project.uuid());
+ }
+
+ @Test
+ public void fail_when_project_does_not_exist() {
+ expectedException.expect(NotFoundException.class);
+
+ callByUuid("Unknown");
+ }
+
+ @Test
+ public void fail_when_no_parameter() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ call(null, null);
+ }
+
+ @Test
+ public void fail_when_project_uuid_and_key_provided() {
+ expectedException.expect(IllegalArgumentException.class);
+
+ call("uuid", "key");
+ }
+
+ private GetByProjectWsResponse callByUuid(String projectUuid) {
+ return call(projectUuid, null);
+ }
+
+ private GetByProjectWsResponse callByKey(String projectKey) {
+ return call(null, projectKey);
+ }
+
+ private GetByProjectWsResponse call(@Nullable String projectUuid, @Nullable String projectKey) {
+ TestRequest request = ws.newRequest()
+ .setMediaType(MediaTypes.PROTOBUF);
+
+ if (projectUuid != null) {
+ request.setParam(PARAM_PROJECT_ID, projectUuid);
+ }
+
+ if (projectKey != null) {
+ request.setParam(PARAM_PROJECT_KEY, projectKey);
+ }
+
+ InputStream response = request.execute().getInputStream();
+
+ try {
+ return GetByProjectWsResponse.parseFrom(response);
+ } catch (IOException e) {
+ throw propagate(e);
+ }
+ }
+
+ private QualityGateDto insertQualityGate(String name) {
+ QualityGateDto qualityGate = dbClient.qualityGateDao().insert(dbSession, new QualityGateDto().setName(name));
+ db.commit();
+ return qualityGate;
+ }
+
+ private void associateProjectToQualityGate(long componentId, long qualityGateId) {
+ dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto()
+ .setKey("sonar.qualitygate")
+ .setResourceId(componentId)
+ .setValue(String.valueOf(qualityGateId)));
+ db.commit();
+ }
+
+ private void setDefaultQualityGate(long qualityGateId) {
+ dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto()
+ .setKey("sonar.qualitygate")
+ .setValue(String.valueOf(qualityGateId)));
+ db.commit();
+ }
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java b/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java
index c984fbe315c..74544f980ec 100644
--- a/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java
@@ -20,6 +20,7 @@
package org.sonar.db.qualitygate;
import java.util.List;
+import java.util.Optional;
import org.apache.ibatis.session.SqlSession;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
@@ -30,6 +31,16 @@ 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));
+ }
+
private static ProjectQgateAssociationMapper mapper(SqlSession session) {
return session.getMapper(ProjectQgateAssociationMapper.class);
}
diff --git a/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java b/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java
index 5b9d9462d2a..c4d058c69f7 100644
--- a/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java
@@ -20,10 +20,13 @@
package org.sonar.db.qualitygate;
import java.util.List;
+import javax.annotation.CheckForNull;
import org.apache.ibatis.annotations.Param;
public interface ProjectQgateAssociationMapper {
List<ProjectQgateAssociationDto> selectProjects(@Param("query") ProjectQgateAssociationQuery query);
+ @CheckForNull
+ String selectQGateIdByComponentId(long componentId);
}
diff --git a/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java b/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java
index 41cc46124ce..49982d7ed20 100644
--- a/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java
@@ -24,6 +24,7 @@ import java.util.Date;
import javax.annotation.CheckForNull;
import org.apache.ibatis.session.SqlSession;
import org.sonar.db.Dao;
+import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
public class QualityGateDao implements Dao{
@@ -35,17 +36,19 @@ public class QualityGateDao implements Dao{
}
public void insert(QualityGateDto newQualityGate) {
- SqlSession session = myBatis.openSession(false);
+ DbSession session = myBatis.openSession(false);
try {
- insert(newQualityGate, session);
+ insert(session, newQualityGate);
session.commit();
} finally {
MyBatis.closeQuietly(session);
}
}
- public void insert(QualityGateDto newQualityGate, SqlSession session) {
+ public QualityGateDto insert(DbSession session, QualityGateDto newQualityGate) {
mapper(session).insert(newQualityGate.setCreatedAt(new Date()));
+
+ return newQualityGate;
}
public Collection<QualityGateDto> selectAll() {
diff --git a/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java b/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java
index 9a1d8e60720..f7fa21e4d0c 100644
--- a/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/qualitygate/QualityGateMapper.java
@@ -42,7 +42,7 @@ import java.util.List;
*/
public interface QualityGateMapper {
- void insert(QualityGateDto newQualityGate);
+ void insert(QualityGateDto qualityGate);
List<QualityGateDto> selectAll();
diff --git a/sonar-db/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml b/sonar-db/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml
index fe6683b58db..01203faf49a 100644
--- a/sonar-db/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml
@@ -32,4 +32,13 @@
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>
+
</mapper>
diff --git a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java
index fbf6e2812b0..5673fe776a3 100644
--- a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java
@@ -20,61 +20,67 @@
package org.sonar.db.qualitygate;
import java.util.List;
+import java.util.Optional;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.property.PropertyDto;
import static org.assertj.core.api.Assertions.assertThat;
-
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
public class ProjectQgateAssociationDaoTest {
@Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
- DbSession dbSession = dbTester.getSession();
+ public DbTester db = DbTester.create(System2.INSTANCE);
+ ComponentDbTester componentDb = new ComponentDbTester(db);
+ DbClient dbClient = db.getDbClient();
+ DbSession dbSession = db.getSession();
- ProjectQgateAssociationDao dao = dbTester.getDbClient().projectQgateAssociationDao();
+ ProjectQgateAssociationDao underTest = db.getDbClient().projectQgateAssociationDao();
@Test
public void select_all_projects_by_query() {
- dbTester.prepareDbUnit(getClass(), "shared.xml");
+ db.prepareDbUnit(getClass(), "shared.xml");
ProjectQgateAssociationQuery query = ProjectQgateAssociationQuery.builder().gateId("42").build();
- List<ProjectQgateAssociationDto> result = dao.selectProjects(dbSession, query);
+ List<ProjectQgateAssociationDto> result = underTest.selectProjects(dbSession, query);
assertThat(result).hasSize(5);
}
@Test
public void select_projects_by_query() {
- dbTester.prepareDbUnit(getClass(), "shared.xml");
+ db.prepareDbUnit(getClass(), "shared.xml");
- assertThat(dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").membership(ProjectQgateAssociationQuery.IN).build())).hasSize(3);
- assertThat(dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").membership(ProjectQgateAssociationQuery.OUT).build())).hasSize(2);
+ assertThat(underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").membership(ProjectQgateAssociationQuery.IN).build())).hasSize(3);
+ assertThat(underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").membership(ProjectQgateAssociationQuery.OUT).build())).hasSize(2);
}
@Test
public void search_by_project_name() {
- dbTester.prepareDbUnit(getClass(), "shared.xml");
+ db.prepareDbUnit(getClass(), "shared.xml");
- List<ProjectQgateAssociationDto> result = dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("one").build());
+ List<ProjectQgateAssociationDto> result = underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("one").build());
assertThat(result).hasSize(1);
assertThat(result.get(0).getName()).isEqualTo("Project One");
- result = dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("one").build());
+ result = underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("one").build());
assertThat(result).hasSize(1);
- result = dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("project").build());
+ result = underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").projectSearch("project").build());
assertThat(result).hasSize(2);
}
@Test
public void should_be_sorted_by_project_name() {
- dbTester.prepareDbUnit(getClass(), "shared.xml");
+ db.prepareDbUnit(getClass(), "shared.xml");
- List<ProjectQgateAssociationDto> result = dao.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").build());
+ List<ProjectQgateAssociationDto> result = underTest.selectProjects(dbSession, ProjectQgateAssociationQuery.builder().gateId("42").build());
assertThat(result).hasSize(5);
assertThat(result.get(0).getName()).isEqualTo("Project Five");
assertThat(result.get(1).getName()).isEqualTo("Project Four");
@@ -82,4 +88,31 @@ public class ProjectQgateAssociationDaoTest {
assertThat(result.get(3).getName()).isEqualTo("Project Three");
assertThat(result.get(4).getName()).isEqualTo("Project Two");
}
+
+ @Test
+ public void select_qgate_id_is_absent() {
+ ComponentDto project = componentDb.insertComponent(newProjectDto());
+
+ Optional<Long> result = underTest.selectQGateIdByComponentId(dbSession, project.getId());
+
+ assertThat(result.isPresent()).isFalse();
+ }
+
+ @Test
+ public void select_qgate_id() {
+ associateProjectToQualityGate(10L, 1L);
+ associateProjectToQualityGate(11L, 2L);
+
+ Optional<Long> result = underTest.selectQGateIdByComponentId(dbSession, 10L);
+
+ assertThat(result).contains(1L);
+ }
+
+ private void associateProjectToQualityGate(long componentId, long qualityGateId) {
+ dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto()
+ .setKey("sonar.qualitygate")
+ .setResourceId(componentId)
+ .setValue(String.valueOf(qualityGateId)));
+ db.commit();
+ }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java
index 5ba885b3dd3..e01d58e7b70 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java
@@ -24,6 +24,17 @@ public class QualityGatesWsParameters {
public static final String PARAM_ANALYSIS_ID = "analysisId";
public static final String PARAM_PROJECT_ID = "projectId";
public static final String PARAM_PROJECT_KEY = "projectKey";
+ public static final String PARAM_PAGE_SIZE = "pageSize";
+ public static final String PARAM_PAGE = "page";
+ public static final String PARAM_QUERY = "query";
+ public static final String PARAM_NAME = "name";
+ public static final String PARAM_ERROR = "error";
+ public static final String PARAM_WARNING = "warning";
+ public static final String PARAM_PERIOD = "period";
+ public static final String PARAM_OPERATOR = "op";
+ public static final String PARAM_METRIC = "metric";
+ public static final String PARAM_GATE_ID = "gateId";
+ public static final String PARAM_ID = "id";
private QualityGatesWsParameters() {
// prevent instantiation
diff --git a/sonar-ws/src/main/protobuf/ws-qualitygates.proto b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
index 57e867e767d..514a5341a37 100644
--- a/sonar-ws/src/main/protobuf/ws-qualitygates.proto
+++ b/sonar-ws/src/main/protobuf/ws-qualitygates.proto
@@ -65,3 +65,14 @@ message ProjectStatusWsResponse {
NE = 4;
}
}
+
+// GET api/qualitygates/get_by_project
+message GetByProjectWsResponse {
+ optional QualityGate qualityGate = 1;
+}
+
+message QualityGate {
+ optional string id = 1;
+ optional string name = 2;
+ optional bool default = 3;
+}