@@ -19,9 +19,8 @@ | |||
*/ | |||
package org.sonar.core.qualitygate.db; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.ImmutableList; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import javax.annotation.CheckForNull; | |||
@@ -42,6 +41,13 @@ public class QualityGateConditionDto { | |||
public static final String OPERATOR_LESS_THAN = "LT"; | |||
public static final List<String> ALL_OPERATORS = ImmutableList.of( | |||
OPERATOR_LESS_THAN, | |||
OPERATOR_GREATER_THAN, | |||
OPERATOR_EQUALS, | |||
OPERATOR_NOT_EQUALS | |||
); | |||
private static final List<String> NUMERIC_OPERATORS = ImmutableList.of( | |||
OPERATOR_LESS_THAN, | |||
OPERATOR_GREATER_THAN, |
@@ -107,8 +107,7 @@ import org.sonar.server.plugins.*; | |||
import org.sonar.server.qualitygate.QgateProjectFinder; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
import org.sonar.server.qualitygate.RegisterQualityGates; | |||
import org.sonar.server.qualitygate.ws.QgateAppHandler; | |||
import org.sonar.server.qualitygate.ws.QualityGatesWs; | |||
import org.sonar.server.qualitygate.ws.*; | |||
import org.sonar.server.qualityprofile.*; | |||
import org.sonar.server.qualityprofile.ws.QProfileRestoreDefaultAction; | |||
import org.sonar.server.qualityprofile.ws.QProfilesWs; | |||
@@ -319,8 +318,23 @@ class ServerComponents { | |||
pico.addSingleton(QualityGates.class); | |||
pico.addSingleton(ProjectQgateAssociationDao.class); | |||
pico.addSingleton(QgateProjectFinder.class); | |||
pico.addSingleton(QgateAppHandler.class); | |||
pico.addSingleton(QualityGatesWs.class); | |||
pico.addSingleton(QGatesListAction.class); | |||
pico.addSingleton(QGatesSearchAction.class); | |||
pico.addSingleton(QGatesShowAction.class); | |||
pico.addSingleton(QGatesCreateAction.class); | |||
pico.addSingleton(QGatesRenameAction.class); | |||
pico.addSingleton(QGatesCopyAction.class); | |||
pico.addSingleton(QGatesDestroyAction.class); | |||
pico.addSingleton(QGatesSetAsDefaultAction.class); | |||
pico.addSingleton(QGatesUnsetDefaultAction.class); | |||
pico.addSingleton(QGatesSelectAction.class); | |||
pico.addSingleton(QGatesDeselectAction.class); | |||
pico.addSingleton(QGatesCreateConditionAction.class); | |||
pico.addSingleton(QGatesDeleteConditionAction.class); | |||
pico.addSingleton(QGatesUpdateConditionAction.class); | |||
pico.addSingleton(QGatesAppAction.class); | |||
pico.addSingleton(QGatesWs.class); | |||
// web services | |||
pico.addSingleton(WebServiceEngine.class); |
@@ -25,13 +25,14 @@ import org.sonar.api.measures.Metric; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
import java.util.Locale; | |||
public class QgateAppHandler implements RequestHandler { | |||
public class QGatesAppAction implements RequestHandler { | |||
private static final String[] MESSAGE_KEYS = { | |||
"add_verb", | |||
@@ -96,12 +97,20 @@ public class QgateAppHandler implements RequestHandler { | |||
private final I18n i18n; | |||
public QgateAppHandler(QualityGates qualityGates, Periods periods, I18n i18n) { | |||
public QGatesAppAction(QualityGates qualityGates, Periods periods, I18n i18n) { | |||
this.qualityGates = qualityGates; | |||
this.periods = periods; | |||
this.i18n = i18n; | |||
} | |||
void define(WebService.NewController controller) { | |||
controller.createAction("app") | |||
.setInternal(true) | |||
.setDescription("Get initialization items for the admin UI. For internal use.") | |||
.setSince("4.3") | |||
.setHandler(this); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
JsonWriter writer = response.newJsonWriter().beginObject(); |
@@ -0,0 +1,64 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesCopyAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesCopyAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("copy") | |||
.setDescription("Copy a Quality Gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("The ID of the source quality gate") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.PARAM_NAME) | |||
.setDescription("The name of the quality gate to create") | |||
.setRequired(true) | |||
.setExampleValue("My Quality Gate"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
QualityGateDto newQualityGate = qualityGates.copy(QGatesWs.parseId(request, QGatesWs.PARAM_ID), request.mandatoryParam(QGatesWs.PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
QGatesWs.writeQualityGate(newQualityGate, writer).close(); | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesCreateAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesCreateAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("create") | |||
.setDescription("Create a Quality Gate. Require Administer Quality Profiles and Gates permission") | |||
.setSince("4.3") | |||
.setPost(true) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_NAME) | |||
.setDescription("The name of the quality gate to create") | |||
.setRequired(true) | |||
.setExampleValue("My Quality Gate"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QGatesWs.PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
QGatesWs.writeQualityGate(newQualityGate, writer).close(); | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesCreateConditionAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesCreateConditionAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction createCondition = controller.createAction("create_condition") | |||
.setDescription("Add a new condition to a quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
createCondition | |||
.createParam(QGatesWs.PARAM_GATE_ID) | |||
.setDescription("ID of the quality gate") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
QGatesWs.addConditionParams(createCondition); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
QGatesWs.writeQualityGateCondition( | |||
qualityGates.createCondition( | |||
QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), | |||
request.mandatoryParam(QGatesWs.PARAM_METRIC), | |||
request.mandatoryParam(QGatesWs.PARAM_OPERATOR), | |||
request.param(QGatesWs.PARAM_WARNING), | |||
request.param(QGatesWs.PARAM_ERROR), | |||
request.paramAsInt(QGatesWs.PARAM_PERIOD) | |||
), response.newJsonWriter() | |||
).close(); | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesDeleteConditionAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesDeleteConditionAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction createCondition = controller.createAction("delete_condition") | |||
.setDescription("Delete a condition from a quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
createCondition | |||
.createParam(QGatesWs.PARAM_ID) | |||
.setRequired(true) | |||
.setDescription("Condition ID") | |||
.setExampleValue("2"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.deleteCondition(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesDeselectAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesDeselectAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("deselect") | |||
.setDescription("Remove the association of a project from a quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_GATE_ID) | |||
.setDescription("Quality Gate ID") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.PARAM_PROJECT_ID) | |||
.setDescription("Project ID") | |||
.setRequired(true) | |||
.setExampleValue("12"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.dissociateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesDestroyAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesDestroyAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("destroy") | |||
.setDescription("Delete a Quality Gate. Require Administer Quality Profiles and Gates permission") | |||
.setSince("4.3") | |||
.setPost(true) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("ID of the quality gate to delete") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.delete(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 com.google.common.io.Resources; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesListAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesListAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
controller.createAction("list") | |||
.setDescription("Get a list of quality gates") | |||
.setSince("4.3") | |||
.setResponseExample(Resources.getResource(this.getClass(), "example-list.json")) | |||
.setHandler(this); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
JsonWriter writer = response.newJsonWriter().beginObject().name("qualitygates").beginArray(); | |||
for (QualityGateDto qgate : qualityGates.list()) { | |||
QGatesWs.writeQualityGate(qgate, writer); | |||
} | |||
writer.endArray(); | |||
QualityGateDto defaultQgate = qualityGates.getDefault(); | |||
if (defaultQgate != null) { | |||
writer.prop("default", defaultQgate.getId()); | |||
} | |||
writer.endObject().close(); | |||
} | |||
} |
@@ -0,0 +1,64 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesRenameAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesRenameAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("rename") | |||
.setDescription("Rename a Quality Gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("ID of the quality gate to rename") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.PARAM_NAME) | |||
.setDescription("New name of the quality gate") | |||
.setRequired(true) | |||
.setExampleValue("My Quality Gate"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
long idToRename = QGatesWs.parseId(request, QGatesWs.PARAM_ID); | |||
QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(QGatesWs.PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
QGatesWs.writeQualityGate(renamedQualityGate, writer).close(); | |||
} | |||
} |
@@ -0,0 +1,91 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 com.google.common.io.Resources; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociation; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociationQuery; | |||
import org.sonar.server.qualitygate.QgateProjectFinder; | |||
public class QGatesSearchAction implements RequestHandler { | |||
private final QgateProjectFinder projectFinder; | |||
public QGatesSearchAction(QgateProjectFinder projectFinder) { | |||
this.projectFinder = projectFinder; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("search") | |||
.setDescription("Search for projects associated (or not) to a quality gate") | |||
.setSince("4.3") | |||
.setResponseExample(Resources.getResource(this.getClass(), "example-search.json")) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_GATE_ID) | |||
.setDescription("Quality Gate ID") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.PARAM_QUERY) | |||
.setDescription("To search for projects containing this string") | |||
.setExampleValue("abc"); | |||
action.createParam(QGatesWs.PARAM_SELECTED) | |||
.setDescription("If \"selected\", search for projects associated to the quality gate.") | |||
.setDefaultValue("selected") | |||
.setPossibleValues("selected", "deselected") | |||
.setExampleValue("deselected"); | |||
action.createParam(QGatesWs.PARAM_PAGE) | |||
.setDescription("Page number") | |||
.setDefaultValue("1") | |||
.setExampleValue("2"); | |||
action.createParam(QGatesWs.PARAM_PAGE_SIZE) | |||
.setDescription("Page size") | |||
.setExampleValue("10"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
QgateProjectFinder.Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder() | |||
.gateId(request.mandatoryParam(QGatesWs.PARAM_GATE_ID)) | |||
.membership(request.param(QGatesWs.PARAM_SELECTED)) | |||
.projectSearch(request.param(QGatesWs.PARAM_QUERY)) | |||
.pageIndex(request.paramAsInt(QGatesWs.PARAM_PAGE)) | |||
.pageSize(request.paramAsInt(QGatesWs.PARAM_PAGE_SIZE)) | |||
.build()); | |||
JsonWriter writer = response.newJsonWriter(); | |||
writer.beginObject().prop("more", associations.hasMoreResults()); | |||
writer.name("results").beginArray(); | |||
for (ProjectQgateAssociation project : associations.projects()) { | |||
writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(QGatesWs.PARAM_SELECTED, project.isMember()).endObject(); | |||
} | |||
writer.endArray().endObject().close(); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesSelectAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesSelectAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("select") | |||
.setDescription("Associate a project to a quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_GATE_ID) | |||
.setDescription("Quality Gate ID") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.PARAM_PROJECT_ID) | |||
.setDescription("Project ID") | |||
.setRequired(true) | |||
.setExampleValue("12"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.associateProject(QGatesWs.parseId(request, QGatesWs.PARAM_GATE_ID), QGatesWs.parseId(request, QGatesWs.PARAM_PROJECT_ID)); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesSetAsDefaultAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesSetAsDefaultAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("set_as_default") | |||
.setDescription("Set a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setSince("4.3") | |||
.setPost(true) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("ID of the quality gate to set as default") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.setDefault(QGatesWs.parseId(request, QGatesWs.PARAM_ID)); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,93 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 com.google.common.io.Resources; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
import javax.annotation.Nullable; | |||
import java.util.Collection; | |||
public class QGatesShowAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesShowAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("show") | |||
.setDescription("Display the details of a quality gate") | |||
.setSince("4.3") | |||
.setResponseExample(Resources.getResource(this.getClass(), "example-show.json")) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("ID of the quality gate. Either id or name must be set") | |||
.setExampleValue("1"); | |||
action.createParam(QGatesWs.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(QGatesWs.PARAM_ID); | |||
String qGateName = request.param(QGatesWs.PARAM_NAME); | |||
checkOneOfIdOrNamePresent(qGateId, qGateName); | |||
QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId); | |||
qGateId = qGate.getId(); | |||
JsonWriter writer = response.newJsonWriter().beginObject() | |||
.prop(QGatesWs.PARAM_ID, qGate.getId()) | |||
.prop(QGatesWs.PARAM_NAME, qGate.getName()); | |||
Collection<QualityGateConditionDto> conditions = qualityGates.listConditions(qGateId); | |||
if (!conditions.isEmpty()) { | |||
writer.name("conditions").beginArray(); | |||
for (QualityGateConditionDto condition : conditions) { | |||
QGatesWs.writeQualityGateCondition(condition, writer); | |||
} | |||
writer.endArray(); | |||
} | |||
writer.endObject().close(); | |||
} | |||
private void checkOneOfIdOrNamePresent(@Nullable Long qGateId, @Nullable String qGateName) { | |||
if (qGateId == null && qGateName == null) { | |||
throw new BadRequestException("Either one of 'id' or 'name' is required."); | |||
} else if (qGateId != null && qGateName != null) { | |||
throw new BadRequestException("Only one of 'id' or 'name' must be provided."); | |||
} | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesUnsetDefaultAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesUnsetDefaultAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction action = controller.createAction("unset_default") | |||
.setDescription("Unset a quality gate as the default quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setSince("4.3") | |||
.setPost(true) | |||
.setHandler(this); | |||
action.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("ID of the quality gate to unset as default") | |||
.setRequired(true) | |||
.setExampleValue("1"); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
qualityGates.setDefault(null); | |||
response.noContent(); | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
public class QGatesUpdateConditionAction implements RequestHandler { | |||
private final QualityGates qualityGates; | |||
public QGatesUpdateConditionAction(QualityGates qualityGates) { | |||
this.qualityGates = qualityGates; | |||
} | |||
void define(WebService.NewController controller) { | |||
WebService.NewAction createCondition = controller.createAction("update_condition") | |||
.setDescription("Update a condition attached to a quality gate. Require Administer Quality Profiles and Gates permission") | |||
.setPost(true) | |||
.setSince("4.3") | |||
.setHandler(this); | |||
createCondition | |||
.createParam(QGatesWs.PARAM_ID) | |||
.setDescription("Condition ID") | |||
.setRequired(true) | |||
.setExampleValue("10"); | |||
QGatesWs.addConditionParams(createCondition); | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
QGatesWs.writeQualityGateCondition( | |||
qualityGates.updateCondition( | |||
QGatesWs.parseId(request, QGatesWs.PARAM_ID), | |||
request.mandatoryParam(QGatesWs.PARAM_METRIC), | |||
request.mandatoryParam(QGatesWs.PARAM_OPERATOR), | |||
request.param(QGatesWs.PARAM_WARNING), | |||
request.param(QGatesWs.PARAM_ERROR), | |||
request.paramAsInt(QGatesWs.PARAM_PERIOD) | |||
), response.newJsonWriter() | |||
).close(); | |||
} | |||
} |
@@ -0,0 +1,174 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
public class QGatesWs 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_SELECTED = "selected"; | |||
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 QGatesListAction listAction; | |||
private final QGatesShowAction showAction; | |||
private final QGatesSearchAction searchAction; | |||
private final QGatesCreateAction createAction; | |||
private final QGatesCopyAction copyAction; | |||
private final QGatesSetAsDefaultAction setAsDefaultAction; | |||
private final QGatesUnsetDefaultAction unsetAction; | |||
private final QGatesDestroyAction destroyAction; | |||
private final QGatesRenameAction renameAction; | |||
private final QGatesCreateConditionAction createConditionAction; | |||
private final QGatesUpdateConditionAction updateConditionAction; | |||
private final QGatesDeleteConditionAction deleteConditionAction; | |||
private final QGatesSelectAction selectAction; | |||
private final QGatesDeselectAction deselectAction; | |||
private final QGatesAppAction appAction; | |||
public QGatesWs(QGatesListAction listAction, QGatesShowAction showAction, QGatesSearchAction searchAction, | |||
QGatesCreateAction createAction, QGatesCopyAction copyAction, QGatesDestroyAction destroyAction, QGatesRenameAction renameAction, | |||
QGatesSetAsDefaultAction setAsDefaultAction, QGatesUnsetDefaultAction unsetAction, | |||
QGatesCreateConditionAction createConditionAction, QGatesUpdateConditionAction updateConditionAction, QGatesDeleteConditionAction deleteConditionAction, | |||
QGatesSelectAction selectAction, QGatesDeselectAction deselectAction, QGatesAppAction appAction) { | |||
this.listAction = listAction; | |||
this.showAction = showAction; | |||
this.searchAction = searchAction; | |||
this.createAction = createAction; | |||
this.destroyAction = destroyAction; | |||
this.renameAction = renameAction; | |||
this.unsetAction = unsetAction; | |||
this.createConditionAction = createConditionAction; | |||
this.updateConditionAction = updateConditionAction; | |||
this.deleteConditionAction = deleteConditionAction; | |||
this.selectAction = selectAction; | |||
this.deselectAction = deselectAction; | |||
this.copyAction = copyAction; | |||
this.setAsDefaultAction = setAsDefaultAction; | |||
this.appAction = appAction; | |||
} | |||
@Override | |||
public void define(Context context) { | |||
NewController controller = context.createController("api/qualitygates") | |||
.setSince("4.3") | |||
.setDescription("This service manages quality gates, including conditions and project association"); | |||
listAction.define(controller); | |||
showAction.define(controller); | |||
searchAction.define(controller); | |||
createAction.define(controller); | |||
renameAction.define(controller); | |||
copyAction.define(controller); | |||
destroyAction.define(controller); | |||
setAsDefaultAction.define(controller); | |||
unsetAction.define(controller); | |||
createConditionAction.define(controller); | |||
updateConditionAction.define(controller); | |||
deleteConditionAction.define(controller); | |||
selectAction.define(controller); | |||
deselectAction.define(controller); | |||
appAction.define(controller); | |||
controller.done(); | |||
} | |||
static void addConditionParams(NewAction action) { | |||
action | |||
.createParam(PARAM_METRIC) | |||
.setDescription("Condition metric") | |||
.setRequired(true) | |||
.setExampleValue("blocker_violations"); | |||
action.createParam(PARAM_OPERATOR) | |||
.setDescription("Condition operator. EQ = equals, NE = is not, LT = is lower than, GT = is greater than") | |||
.setExampleValue(QualityGateConditionDto.OPERATOR_EQUALS) | |||
.setPossibleValues(QualityGateConditionDto.ALL_OPERATORS); | |||
action.createParam(PARAM_PERIOD) | |||
.setDescription("Condition period") | |||
.setExampleValue("1"); | |||
action.createParam(PARAM_WARNING) | |||
.setDescription("Condition warning threshold") | |||
.setExampleValue("5"); | |||
action.createParam(PARAM_ERROR) | |||
.setDescription("Condition error threshold") | |||
.setExampleValue("10"); | |||
} | |||
static Long parseId(Request request, String paramName) { | |||
try { | |||
return Long.valueOf(request.mandatoryParam(paramName)); | |||
} catch (NumberFormatException badFormat) { | |||
throw new BadRequestException(paramName + " must be a valid long value"); | |||
} | |||
} | |||
static JsonWriter writeQualityGate(QualityGateDto qualityGate, JsonWriter writer) { | |||
return writer.beginObject() | |||
.prop(PARAM_ID, qualityGate.getId()) | |||
.prop(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()); | |||
if (condition.getWarningThreshold() != null) { | |||
writer.prop(PARAM_WARNING, condition.getWarningThreshold()); | |||
} | |||
if (condition.getErrorThreshold() != null) { | |||
writer.prop(PARAM_ERROR, condition.getErrorThreshold()); | |||
} | |||
if (condition.getPeriod() != null) { | |||
writer.prop(PARAM_PERIOD, condition.getPeriod()); | |||
} | |||
writer.endObject(); | |||
return writer; | |||
} | |||
} |
@@ -1,420 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociation; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociationQuery; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.qualitygate.QgateProjectFinder; | |||
import org.sonar.server.qualitygate.QgateProjectFinder.Association; | |||
import org.sonar.server.qualitygate.QualityGates; | |||
import java.util.Collection; | |||
public class QualityGatesWs implements WebService { | |||
private static final String PARAM_PAGE_SIZE = "pageSize"; | |||
private static final String PARAM_PAGE = "page"; | |||
private static final String PARAM_QUERY = "query"; | |||
private static final String PARAM_SELECTED = "selected"; | |||
private static final String PARAM_NAME = "name"; | |||
private static final String PARAM_ERROR = "error"; | |||
private static final String PARAM_WARNING = "warning"; | |||
private static final String PARAM_PERIOD = "period"; | |||
private static final String PARAM_OPERATOR = "op"; | |||
private static final String PARAM_METRIC = "metric"; | |||
private static final String PARAM_GATE_ID = "gateId"; | |||
private static final String PARAM_PROJECT_ID = "projectId"; | |||
private static final String PARAM_ID = "id"; | |||
private final QualityGates qualityGates; | |||
private final QgateProjectFinder projectFinder; | |||
private final QgateAppHandler appHandler; | |||
public QualityGatesWs(QualityGates qualityGates, QgateProjectFinder projectFinder, QgateAppHandler appHandler) { | |||
this.qualityGates = qualityGates; | |||
this.projectFinder = projectFinder; | |||
this.appHandler = appHandler; | |||
} | |||
@Override | |||
public void define(Context context) { | |||
NewController controller = context.createController("api/qualitygates") | |||
.setSince("4.3") | |||
.setDescription("This service manages quality gates, including conditions and project association"); | |||
defineQualityGateActions(controller); | |||
defineConditionActions(controller); | |||
defineProjectAssociationActions(controller); | |||
controller.createAction("app") | |||
.setInternal(true) | |||
.setDescription("Get initialization items for the admin UI. For internal use.") | |||
.setSince("4.3") | |||
.setHandler(appHandler); | |||
controller.done(); | |||
} | |||
private void defineConditionActions(NewController controller) { | |||
NewAction createCondition = controller.createAction("create_condition") | |||
.setDescription("Add a new condition to a quality gate") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
createCondition(request, response); | |||
} | |||
}); | |||
createCondition.createParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate for which the condition will be created."); | |||
addConditionParams(createCondition); | |||
NewAction updateCondition = controller.createAction("update_condition") | |||
.setDescription("Update a condition attached to a quality gate") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
updateCondition(request, response); | |||
} | |||
}); | |||
updateCondition.createParam(PARAM_ID).setDescription("The numerical ID of the condition to update."); | |||
addConditionParams(updateCondition); | |||
controller.createAction("delete_condition") | |||
.setDescription("Remove a condition from a quality gate") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
deleteCondition(request, response); | |||
} | |||
}).createParam(PARAM_ID).setDescription("The numerical ID of the condition to delete."); | |||
} | |||
private void addConditionParams(NewAction createCondition) { | |||
createCondition.createParam(PARAM_METRIC).setDescription("The key for the metric tested by this condition."); | |||
createCondition.createParam(PARAM_OPERATOR).setDescription("The operator used for the test, one of 'EQ', 'NE', 'LT', 'GT'."); | |||
createCondition.createParam(PARAM_PERIOD).setDescription("The optional period to use (for differential measures)."); | |||
createCondition.createParam(PARAM_WARNING).setDescription("An optional value for the warning threshold."); | |||
createCondition.createParam(PARAM_ERROR).setDescription("An optional value for the error threshold."); | |||
} | |||
private void defineQualityGateActions(NewController controller) { | |||
controller.createAction("create") | |||
.setDescription("Create a quality gate, given its name.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
create(request, response); | |||
} | |||
}).createParam(PARAM_NAME).setDescription("The name of the quality gate to create."); | |||
NewAction copy = controller.createAction("copy") | |||
.setDescription("Copy a quality gate, given its ID and the name for the new quality gate.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
copy(request, response); | |||
} | |||
}); | |||
copy.createParam(PARAM_ID).setDescription("The ID of the source quality gate."); | |||
copy.createParam(PARAM_NAME).setDescription("The name of the destination quality gate."); | |||
controller.createAction("set_as_default") | |||
.setDescription("Select the default quality gate.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
setDefault(request, response); | |||
} | |||
}).createParam(PARAM_ID).setDescription("The ID of the quality gate to use as default."); | |||
controller.createAction("unset_default") | |||
.setDescription("Unselect the default quality gate.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
unsetDefault(response); | |||
} | |||
}); | |||
NewAction rename = controller.createAction("rename") | |||
.setDescription("Rename a quality gate, given its id and new name.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
rename(request, response); | |||
} | |||
}); | |||
rename.createParam(PARAM_ID).setDescription("The ID of the quality gate to rename."); | |||
rename.createParam(PARAM_NAME).setDescription("The new name for the quality gate."); | |||
controller.createAction("list") | |||
.setDescription("List all quality gates.") | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
list(response); | |||
} | |||
}); | |||
controller.createAction("show") | |||
.setDescription("Show a quality gate in details, with associated conditions.") | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
show(request, response); | |||
} | |||
}).createParam(PARAM_ID, "The ID of the quality gate; either this or name must be provided.") | |||
.createParam(PARAM_NAME, "The name of the quality gate; either this or id must be provided."); | |||
controller.createAction("destroy") | |||
.setDescription("Destroy a quality gate, given its id.") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
destroy(request, response); | |||
} | |||
}).createParam(PARAM_ID).setDescription("The numerical ID of the quality gate to destroy."); | |||
NewAction search = controller.createAction("search") | |||
.setDescription("Search projects associated (or not) with a quality gate.") | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
search(request, response); | |||
} | |||
}); | |||
search.createParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate considered for association."); | |||
search.createParam(PARAM_SELECTED).setDescription("Optionally, to search for projects associated (selected=selected) or not (selected=deselected)."); | |||
search.createParam(PARAM_QUERY).setDescription("Optionally, part of the name of the projects to search for."); | |||
search.createParam(PARAM_PAGE); | |||
search.createParam(PARAM_PAGE_SIZE); | |||
} | |||
private void defineProjectAssociationActions(NewController controller) { | |||
NewAction select = controller.createAction("select") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
select(request, response); | |||
} | |||
}); | |||
select.createParam(PARAM_GATE_ID); | |||
select.createParam(PARAM_PROJECT_ID); | |||
NewAction deselect = controller.createAction("deselect") | |||
.setPost(true) | |||
.setHandler(new RequestHandler() { | |||
@Override | |||
public void handle(Request request, Response response) { | |||
deselect(request, response); | |||
} | |||
}); | |||
deselect.createParam(PARAM_GATE_ID); | |||
deselect.createParam(PARAM_PROJECT_ID); | |||
} | |||
protected void copy(Request request, Response response) { | |||
QualityGateDto newQualityGate = qualityGates.copy(parseId(request, PARAM_ID), request.mandatoryParam(PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
writeQualityGate(newQualityGate, writer).close(); | |||
} | |||
protected void select(Request request, Response response) { | |||
qualityGates.associateProject(parseId(request, PARAM_GATE_ID), parseId(request, PARAM_PROJECT_ID)); | |||
response.noContent(); | |||
} | |||
protected void deselect(Request request, Response response) { | |||
qualityGates.dissociateProject(parseId(request, PARAM_GATE_ID), parseId(request, PARAM_PROJECT_ID)); | |||
response.noContent(); | |||
} | |||
protected void search(Request request, Response response) { | |||
Association associations = projectFinder.find(ProjectQgateAssociationQuery.builder() | |||
.gateId(request.mandatoryParam(PARAM_GATE_ID)) | |||
.membership(request.param(PARAM_SELECTED)) | |||
.projectSearch(request.param(PARAM_QUERY)) | |||
.pageIndex(request.paramAsInt(PARAM_PAGE)) | |||
.pageSize(request.paramAsInt(PARAM_PAGE_SIZE)) | |||
.build()); | |||
JsonWriter writer = response.newJsonWriter(); | |||
writer.beginObject().prop("more", associations.hasMoreResults()); | |||
writer.name("results").beginArray(); | |||
for (ProjectQgateAssociation project: associations.projects()) { | |||
writer.beginObject().prop("id", project.id()).prop("name", project.name()).prop(PARAM_SELECTED, project.isMember()).endObject(); | |||
} | |||
writer.endArray().endObject().close(); | |||
} | |||
protected void show(Request request, Response response) { | |||
Long qGateId = request.paramAsLong(PARAM_ID); | |||
String qGateName = request.param(PARAM_NAME); | |||
checkOneOfIdOrNamePresent(qGateId, qGateName); | |||
QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId); | |||
qGateId = qGate.getId(); | |||
JsonWriter writer = response.newJsonWriter().beginObject() | |||
.prop(PARAM_ID, qGate.getId()) | |||
.prop(PARAM_NAME, qGate.getName()); | |||
Collection<QualityGateConditionDto> conditions = qualityGates.listConditions(qGateId); | |||
if (!conditions.isEmpty()) { | |||
writer.name("conditions").beginArray(); | |||
for (QualityGateConditionDto condition: conditions) { | |||
writeQualityGateCondition(condition, writer); | |||
} | |||
writer.endArray(); | |||
} | |||
writer.endObject().close(); | |||
} | |||
private void checkOneOfIdOrNamePresent(Long qGateId, String qGateName) { | |||
if (qGateId == null && qGateName == null) { | |||
throw new BadRequestException("Either one of 'id' or 'name' is required."); | |||
} else if (qGateId != null && qGateName != null) { | |||
throw new BadRequestException("Only one of 'id' or 'name' must be provided."); | |||
} | |||
} | |||
protected void createCondition(Request request, Response response) { | |||
writeQualityGateCondition( | |||
qualityGates.createCondition( | |||
parseId(request, PARAM_GATE_ID), | |||
request.mandatoryParam(PARAM_METRIC), | |||
request.mandatoryParam(PARAM_OPERATOR), | |||
request.param(PARAM_WARNING), | |||
request.param(PARAM_ERROR), | |||
request.paramAsInt(PARAM_PERIOD) | |||
), response.newJsonWriter()).close(); | |||
} | |||
protected void updateCondition(Request request, Response response) { | |||
writeQualityGateCondition( | |||
qualityGates.updateCondition( | |||
parseId(request, PARAM_ID), | |||
request.mandatoryParam(PARAM_METRIC), | |||
request.mandatoryParam(PARAM_OPERATOR), | |||
request.param(PARAM_WARNING), | |||
request.param(PARAM_ERROR), | |||
request.paramAsInt(PARAM_PERIOD) | |||
), response.newJsonWriter()).close(); | |||
} | |||
protected void deleteCondition(Request request, Response response) { | |||
qualityGates.deleteCondition(parseId(request, PARAM_ID)); | |||
response.noContent(); | |||
} | |||
protected void setDefault(Request request, Response response) { | |||
qualityGates.setDefault(parseId(request, PARAM_ID)); | |||
response.noContent(); | |||
} | |||
protected void unsetDefault(Response response) { | |||
qualityGates.setDefault(null); | |||
response.noContent(); | |||
} | |||
protected void rename(Request request, Response response) { | |||
long idToRename = parseId(request, PARAM_ID); | |||
QualityGateDto renamedQualityGate = qualityGates.rename(idToRename, request.mandatoryParam(PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
writeQualityGate(renamedQualityGate, writer).close(); | |||
} | |||
protected void destroy(Request request, Response response) { | |||
qualityGates.delete(parseId(request, PARAM_ID)); | |||
response.noContent(); | |||
} | |||
protected void list(Response response) { | |||
JsonWriter writer = response.newJsonWriter().beginObject().name("qualitygates").beginArray(); | |||
for (QualityGateDto qgate: qualityGates.list()) { | |||
writeQualityGate(qgate, writer); | |||
} | |||
writer.endArray(); | |||
QualityGateDto defaultQgate = qualityGates.getDefault(); | |||
if (defaultQgate != null) { | |||
writer.prop("default", defaultQgate.getId()); | |||
} | |||
writer.endObject().close(); | |||
} | |||
protected void create(Request request, Response response) { | |||
QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(PARAM_NAME)); | |||
JsonWriter writer = response.newJsonWriter(); | |||
writeQualityGate(newQualityGate, writer).close(); | |||
} | |||
private Long parseId(Request request, String paramName) { | |||
try { | |||
return Long.valueOf(request.mandatoryParam(paramName)); | |||
} catch (NumberFormatException badFormat) { | |||
throw new BadRequestException(paramName + " must be a valid long value"); | |||
} | |||
} | |||
private JsonWriter writeQualityGate(QualityGateDto qualityGate, JsonWriter writer) { | |||
return writer.beginObject() | |||
.prop(PARAM_ID, qualityGate.getId()) | |||
.prop(PARAM_NAME, qualityGate.getName()) | |||
.endObject(); | |||
} | |||
private JsonWriter writeQualityGateCondition(QualityGateConditionDto condition, JsonWriter writer) { | |||
writer.beginObject() | |||
.prop(PARAM_ID, condition.getId()) | |||
.prop(PARAM_METRIC, condition.getMetricKey()) | |||
.prop(PARAM_OPERATOR, condition.getOperator()); | |||
if(condition.getWarningThreshold() != null) { | |||
writer.prop(PARAM_WARNING, condition.getWarningThreshold()); | |||
} | |||
if(condition.getErrorThreshold() != null) { | |||
writer.prop(PARAM_ERROR, condition.getErrorThreshold()); | |||
} | |||
if(condition.getPeriod() != null) { | |||
writer.prop(PARAM_PERIOD, condition.getPeriod()); | |||
} | |||
writer.endObject(); | |||
return writer; | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
{ | |||
"qualitygates": [ | |||
{ | |||
"id": 2, | |||
"name": "QG1" | |||
}, | |||
{ | |||
"id": 4, | |||
"name": "QG2" | |||
} | |||
] | |||
} |
@@ -0,0 +1,15 @@ | |||
{ | |||
"more": true, | |||
"results": [ | |||
{ | |||
"id": 1, | |||
"name": "Simple Java project analyzed with the SonarQube Runner", | |||
"selected": true | |||
}, | |||
{ | |||
"id": 4, | |||
"name": "My Project", | |||
"selected": true | |||
} | |||
] | |||
} |
@@ -0,0 +1,18 @@ | |||
{ | |||
"id": 2, | |||
"name": "My Quality Gate", | |||
"conditions": [ | |||
{ | |||
"id": 9, | |||
"metric": "blocker_violations", | |||
"op": "GT", | |||
"error": "0" | |||
}, | |||
{ | |||
"id": 10, | |||
"metric": "critical_violations", | |||
"op": "GT", | |||
"warning": "0" | |||
} | |||
] | |||
} |
@@ -44,12 +44,10 @@ import java.util.Set; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.doAnswer; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.mockito.Mockito.*; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class QgateAppHandlerTest { | |||
public class QGatesAppActionTest { | |||
@Mock | |||
private QualityGates qGates; | |||
@@ -64,7 +62,12 @@ public class QgateAppHandlerTest { | |||
@Before | |||
public void setUp() { | |||
tester = new WsTester(new QualityGatesWs(qGates, mock(QgateProjectFinder.class), new QgateAppHandler(qGates, periods, i18n))); | |||
tester = new WsTester(new QGatesWs( | |||
new QGatesListAction(qGates), new QGatesShowAction(qGates), new QGatesSearchAction(mock(QgateProjectFinder.class)), | |||
new QGatesCreateAction(qGates), new QGatesCopyAction(qGates), new QGatesDestroyAction(qGates), new QGatesRenameAction(qGates), | |||
new QGatesSetAsDefaultAction(qGates), new QGatesUnsetDefaultAction(qGates), | |||
new QGatesCreateConditionAction(qGates), new QGatesUpdateConditionAction(qGates), new QGatesDeleteConditionAction(qGates), | |||
new QGatesSelectAction(qGates), new QGatesDeselectAction(qGates), new QGatesAppAction(qGates, periods, i18n))); | |||
} | |||
@Test |
@@ -26,12 +26,14 @@ import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.server.ws.WebService.Action; | |||
import org.sonar.api.server.ws.WebService.Controller; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociation; | |||
import org.sonar.core.qualitygate.db.ProjectQgateAssociationQuery; | |||
import org.sonar.core.qualitygate.db.QualityGateConditionDto; | |||
import org.sonar.core.qualitygate.db.QualityGateDto; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.qualitygate.QgateProjectFinder; | |||
import org.sonar.server.qualitygate.QgateProjectFinder.Association; | |||
@@ -42,12 +44,10 @@ import java.util.List; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
import static org.mockito.Mockito.*; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class QualityGatesWsTest { | |||
public class QGatesWsTest { | |||
@Mock | |||
private QualityGates qGates; | |||
@@ -56,13 +56,18 @@ public class QualityGatesWsTest { | |||
private QgateProjectFinder projectFinder; | |||
@Mock | |||
private QgateAppHandler appHandler; | |||
private QGatesAppAction appHandler; | |||
WsTester tester; | |||
@Before | |||
public void setUp() { | |||
tester = new WsTester(new QualityGatesWs(qGates, projectFinder, appHandler)); | |||
tester = new WsTester(new QGatesWs( | |||
new QGatesListAction(qGates), new QGatesShowAction(qGates), new QGatesSearchAction(projectFinder), | |||
new QGatesCreateAction(qGates), new QGatesCopyAction(qGates), new QGatesDestroyAction(qGates), new QGatesRenameAction(qGates), | |||
new QGatesSetAsDefaultAction(qGates), new QGatesUnsetDefaultAction(qGates), | |||
new QGatesCreateConditionAction(qGates), new QGatesUpdateConditionAction(qGates), new QGatesDeleteConditionAction(qGates), | |||
new QGatesSelectAction(qGates), new QGatesDeselectAction(qGates), new QGatesAppAction(qGates, mock(Periods.class), mock(I18n.class)))); | |||
} | |||
@Test |