Explorar el Código

SONAR-5111 Complete "api/qualitygates" WS documentation and do some refactoring to split actions of this WS into multiple classes

tags/4.4-RC1
Julien Lancelot hace 10 años
padre
commit
a9de40dcab
Se han modificado 24 ficheros con 1189 adiciones y 439 borrados
  1. 8
    2
      sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java
  2. 18
    4
      sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
  3. 11
    2
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java
  4. 64
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java
  5. 59
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java
  6. 67
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java
  7. 57
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java
  8. 61
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java
  9. 56
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java
  10. 62
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java
  11. 64
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java
  12. 91
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java
  13. 61
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java
  14. 56
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java
  15. 93
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java
  16. 56
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java
  17. 67
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java
  18. 174
    0
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java
  19. 0
    420
      sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
  20. 12
    0
      sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-list.json
  21. 15
    0
      sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json
  22. 18
    0
      sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-show.json
  23. 8
    5
      sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java
  24. 11
    6
      sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java

+ 8
- 2
sonar-core/src/main/java/org/sonar/core/qualitygate/db/QualityGateConditionDto.java Ver fichero

@@ -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,

+ 18
- 4
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java Ver fichero

@@ -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);

sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java → sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesAppAction.java Ver fichero

@@ -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();

+ 64
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCopyAction.java Ver fichero

@@ -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();
}

}

+ 59
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateAction.java Ver fichero

@@ -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();
}

}

+ 67
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesCreateConditionAction.java Ver fichero

@@ -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();
}

}

+ 57
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeleteConditionAction.java Ver fichero

@@ -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();
}

}

+ 61
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDeselectAction.java Ver fichero

@@ -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();
}

}

+ 56
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesDestroyAction.java Ver fichero

@@ -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();
}

}

+ 62
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesListAction.java Ver fichero

@@ -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();
}

}

+ 64
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesRenameAction.java Ver fichero

@@ -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();
}

}

+ 91
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSearchAction.java Ver fichero

@@ -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();
}

}

+ 61
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSelectAction.java Ver fichero

@@ -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();
}

}

+ 56
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesSetAsDefaultAction.java Ver fichero

@@ -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();
}

}

+ 93
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesShowAction.java Ver fichero

@@ -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.");
}
}

}

+ 56
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUnsetDefaultAction.java Ver fichero

@@ -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();
}

}

+ 67
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesUpdateConditionAction.java Ver fichero

@@ -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();
}

}

+ 174
- 0
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QGatesWs.java Ver fichero

@@ -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;
}

}

+ 0
- 420
sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java Ver fichero

@@ -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;
}

}

+ 12
- 0
sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-list.json Ver fichero

@@ -0,0 +1,12 @@
{
"qualitygates": [
{
"id": 2,
"name": "QG1"
},
{
"id": 4,
"name": "QG2"
}
]
}

+ 15
- 0
sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-search.json Ver fichero

@@ -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
}
]
}

+ 18
- 0
sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/example-show.json Ver fichero

@@ -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"
}
]
}

sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QgateAppHandlerTest.java → sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesAppActionTest.java Ver fichero

@@ -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

sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java → sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QGatesWsTest.java Ver fichero

@@ -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

Cargando…
Cancelar
Guardar