diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-05-02 18:03:58 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-05-02 18:03:58 +0200 |
commit | a9de40dcab992729d8dc697d276e8e61f115727f (patch) | |
tree | 198c9713a53bf7cc93bae430133eb9ee8f2058d1 | |
parent | abd944ab6b7589d7a8bd437d9826c867b7d7330f (diff) | |
download | sonarqube-a9de40dcab992729d8dc697d276e8e61f115727f.tar.gz sonarqube-a9de40dcab992729d8dc697d276e8e61f115727f.zip |
SONAR-5111 Complete "api/qualitygates" WS documentation and do some refactoring to split actions of this WS into multiple classes
24 files changed, 1189 insertions, 439 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java index 819d271350a..7fc5fc7a6e6 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java +++ b/sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java @@ -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, diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index b05f65fa83d..7907d27de8b 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -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); diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java index a6734e39b67..bee8436ebdb 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java @@ -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(); diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java new file mode 100644 index 00000000000..bef3d32a92b --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java new file mode 100644 index 00000000000..c21e433c51f --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java new file mode 100644 index 00000000000..053df901342 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java new file mode 100644 index 00000000000..ae806fde47f --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java new file mode 100644 index 00000000000..436d87c4d15 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java new file mode 100644 index 00000000000..c67029ddc77 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java new file mode 100644 index 00000000000..98c95e70e34 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java new file mode 100644 index 00000000000..d0c0905fd7f --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java new file mode 100644 index 00000000000..c6f455d7862 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java new file mode 100644 index 00000000000..678934b7cbe --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java new file mode 100644 index 00000000000..2d8b3b2785c --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java new file mode 100644 index 00000000000..816589ed0a3 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java @@ -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."); + } + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java new file mode 100644 index 00000000000..d796efcbeab --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java new file mode 100644 index 00000000000..f9222d7f9ee --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java @@ -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(); + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java new file mode 100644 index 00000000000..1a7c5c262df --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java @@ -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; + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java deleted file mode 100644 index 0c7fee0c56c..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java +++ /dev/null @@ -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; - } - -} diff --git a/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-list.json b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-list.json new file mode 100644 index 00000000000..0a57b779516 --- /dev/null +++ b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-list.json @@ -0,0 +1,12 @@ +{ + "qualitygates": [ + { + "id": 2, + "name": "QG1" + }, + { + "id": 4, + "name": "QG2" + } + ] +} diff --git a/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json new file mode 100644 index 00000000000..7ad6eed5a24 --- /dev/null +++ b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json @@ -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 + } + ] +} diff --git a/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-show.json b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-show.json new file mode 100644 index 00000000000..99132a0173d --- /dev/null +++ b/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-show.json @@ -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" + } + ] +} diff --git a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QgateAppHandlerTest.java b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java index 529b153f8ef..956192c1fbd 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QgateAppHandlerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java @@ -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 diff --git a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java index 3b1f78f5e6a..f14a0c836c6 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java @@ -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 |