aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-05-22 16:57:17 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-05-26 13:43:06 +0200
commit3c9e53b57a7d5a20d2f47d0462b53c10a587d250 (patch)
tree21ca9f923877b6132abb75a1c745351f09078b4a /server
parent958529665bd6e47b0f0cc43e4a73a3d8ca0f72f4 (diff)
downloadsonarqube-3c9e53b57a7d5a20d2f47d0462b53c10a587d250.tar.gz
sonarqube-3c9e53b57a7d5a20d2f47d0462b53c10a587d250.zip
WS api/metrics/list - SONAR-6570
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java14
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/ListAction.java128
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWs.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWsAction.java27
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java4
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/measure/ws/example-list.json23
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/measure/ws/ListActionTest.java162
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/measure/ws/MetricTesting.java54
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/measure/ws/ListActionTest/list_metrics.json25
9 files changed, 445 insertions, 1 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java
index 97758e56759..32bf681229d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MetricDao.java
@@ -20,15 +20,20 @@
package org.sonar.server.measure.persistence;
+import com.google.common.collect.Maps;
+import org.apache.ibatis.session.RowBounds;
import org.sonar.api.server.ServerSide;
import org.sonar.core.measure.db.MetricDto;
import org.sonar.core.measure.db.MetricMapper;
import org.sonar.core.persistence.DaoComponent;
import org.sonar.core.persistence.DbSession;
+import org.sonar.server.es.SearchOptions;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import java.util.List;
+import java.util.Map;
@ServerSide
public class MetricDao implements DaoComponent {
@@ -42,6 +47,15 @@ public class MetricDao implements DaoComponent {
return session.getMapper(MetricMapper.class).selectAllEnabled();
}
+ public List<MetricDto> selectEnabled(DbSession session, @Nullable Boolean isCustom, SearchOptions searchOptions) {
+ Map<String, Object> properties = Maps.newHashMapWithExpectedSize(1);
+ if (isCustom != null) {
+ properties.put("isCustom", isCustom);
+ }
+
+ return session.getMapper(MetricMapper.class).selectAllEnabled(properties, new RowBounds(searchOptions.getOffset(), searchOptions.getLimit()));
+ }
+
public void insert(DbSession session, MetricDto dto) {
session.getMapper(MetricMapper.class).insert(dto);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ListAction.java
new file mode 100644
index 00000000000..9ba67c1f013
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ListAction.java
@@ -0,0 +1,128 @@
+/*
+ * 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.measure.ws;
+
+import org.sonar.api.measures.Metric;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.measure.db.MetricDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.es.SearchOptions;
+
+import javax.annotation.Nullable;
+
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+public class ListAction implements MetricsWsAction {
+
+ public static final String PARAM_IS_CUSTOM = "is_custom";
+
+ public static final String FIELD_ID = "id";
+ public static final String FIELD_KEY = "key";
+ public static final String FIELD_NAME = "name";
+ public static final String FIELD_DESCRIPTION = "description";
+ public static final String FIELD_DOMAIN = "domain";
+ public static final String FIELD_TYPE = "type";
+ private static final Set<String> POSSIBLE_FIELDS = newHashSet(FIELD_ID, FIELD_KEY, FIELD_NAME, FIELD_DESCRIPTION, FIELD_DOMAIN, FIELD_TYPE);
+
+ private final DbClient dbClient;
+
+ public ListAction(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction("list")
+ .setSince("5.2")
+ .setResponseExample(getClass().getResource("example-list.json"))
+ .addPagingParams(100)
+ .addFieldsParam(POSSIBLE_FIELDS)
+ .setHandler(this);
+
+ action.createParam(PARAM_IS_CUSTOM)
+ .setExampleValue("true")
+ .setDescription("Choose custom metrics following 3 cases:" +
+ "<ul>" +
+ "<li>true: only custom metrics are returned</li>" +
+ "<li>false: only non custom metrics are returned</li>" +
+ "<li>not specified: all metrics are returned</li>" +
+ "</ul>");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ SearchOptions searchOptions = new SearchOptions()
+ .setPage(request.mandatoryParamAsInt(Param.PAGE),
+ request.mandatoryParamAsInt(Param.PAGE_SIZE));
+ Boolean isCustom = request.paramAsBoolean(PARAM_IS_CUSTOM);
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ List<MetricDto> metrics = dbClient.metricDao().selectEnabled(dbSession, isCustom, searchOptions);
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject();
+ Set<String> desiredFields = desiredFields(request.paramAsStrings(Param.FIELDS));
+ writeMetrics(json, metrics, desiredFields);
+ json.endObject();
+ json.close();
+ } finally {
+ MyBatis.closeQuietly(dbSession);
+ }
+ }
+
+ private Set<String> desiredFields(@Nullable List<String> fields) {
+ if (fields == null || fields.isEmpty()) {
+ return POSSIBLE_FIELDS;
+ }
+
+ return newHashSet(fields);
+ }
+
+ private void writeMetrics(JsonWriter json, List<MetricDto> metrics, Set<String> desiredFields) {
+ json.name("metrics");
+ json.beginArray();
+ for (MetricDto metric : metrics) {
+ json.beginObject();
+ json.prop(FIELD_ID, String.valueOf(metric.getId()));
+ json.prop(FIELD_KEY, metric.getKey());
+ writeIfDesired(json, FIELD_NAME, metric.getShortName(), desiredFields);
+ writeIfDesired(json, FIELD_DESCRIPTION, metric.getDescription(), desiredFields);
+ writeIfDesired(json, FIELD_DOMAIN, metric.getDomain(), desiredFields);
+ writeIfDesired(json, FIELD_TYPE, Metric.ValueType.descriptionOf(metric.getValueType()), desiredFields);
+ json.endObject();
+ }
+ json.endArray();
+ }
+
+ private void writeIfDesired(JsonWriter json, String field, String value, Set<String> desiredFields) {
+ if (desiredFields.contains(field)) {
+ json.prop(field, value);
+ }
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWs.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWs.java
index ed34355709b..2f352ef3bc6 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWs.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWs.java
@@ -25,12 +25,21 @@ import org.sonar.api.server.ws.WebService;
public class MetricsWs implements WebService {
+ private final MetricsWsAction[] actions;
+
+ public MetricsWs(MetricsWsAction... actions) {
+ this.actions = actions;
+ }
+
@Override
public void define(Context context) {
NewController controller = context.createController("api/metrics");
controller.setDescription("Metrics management");
controller.setSince("2.6");
+ for (MetricsWsAction action : actions) {
+ action.define(controller);
+ }
defineIndexAction(controller);
controller.done();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWsAction.java
new file mode 100644
index 00000000000..61b28ba802b
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/MetricsWsAction.java
@@ -0,0 +1,27 @@
+/*
+ * 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.measure.ws;
+
+import org.sonar.server.ws.WsAction;
+
+public interface MetricsWsAction extends WsAction {
+ // marker interface
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index a09daf2b385..a7af1692d96 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -19,7 +19,6 @@
*/
package org.sonar.server.platform.platformlevel;
-import java.util.List;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.issue.action.Actions;
import org.sonar.api.profiles.AnnotationProfileParser;
@@ -291,6 +290,8 @@ import org.sonar.server.view.index.ViewIndexer;
import org.sonar.server.ws.ListingWs;
import org.sonar.server.ws.WebServiceEngine;
+import java.util.List;
+
public class PlatformLevel4 extends PlatformLevel {
private final List<Object> level4AddedComponents;
@@ -431,6 +432,7 @@ public class PlatformLevel4 extends PlatformLevel {
TimeMachineWs.class,
ManualMeasuresWs.class,
MetricsWs.class,
+ org.sonar.server.measure.ws.ListAction.class,
// quality gates
QualityGateDao.class,
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/measure/ws/example-list.json b/server/sonar-server/src/main/resources/org/sonar/server/measure/ws/example-list.json
new file mode 100644
index 00000000000..3a7a4ddd8d7
--- /dev/null
+++ b/server/sonar-server/src/main/resources/org/sonar/server/measure/ws/example-list.json
@@ -0,0 +1,23 @@
+{
+ "metrics": [
+ {
+ "id": "23",
+ "key": "team_size",
+ "name": "Team size",
+ "description": "Number of people in the team",
+ "domain": "Management",
+ "type": "INT"
+ },
+ {
+ "id": "2",
+ "key": "uncovered_lines",
+ "name": "Uncovered lines",
+ "description": "Uncovered lines",
+ "domain": "Tests",
+ "type": "INT"
+ }
+ ],
+ "total": 2,
+ "p": 1,
+ "ps": 100
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ListActionTest.java
new file mode 100644
index 00000000000..4bbcb9b1406
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ListActionTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.measure.ws;
+
+import org.apache.commons.lang.StringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.core.measure.db.MetricDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.measure.persistence.MetricDao;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.measure.ws.ListAction.PARAM_IS_CUSTOM;
+
+public class ListActionTest {
+
+ @ClassRule
+ public static DbTester db = new DbTester();
+ DbClient dbClient;
+ DbSession dbSession;
+ WsTester ws;
+
+ @Before
+ public void setUp() {
+ dbClient = new DbClient(db.database(), db.myBatis(), new MetricDao());
+ dbSession = dbClient.openSession(false);
+ ws = new WsTester(new MetricsWs(new ListAction(dbClient)));
+ db.truncateTables();
+ }
+
+ @After
+ public void tearDown() {
+ dbSession.close();
+ }
+
+ @Test
+ public void list_metrics_in_database() throws Exception {
+ insertNewCustomMetric("1", "2", "3");
+
+ WsTester.Result result = newRequest().execute();
+
+ result.assertJson(getClass(), "list_metrics.json");
+ }
+
+ @Test
+ public void list_metrics_ordered_by_name_case_insensitive() throws Exception {
+ insertNewCustomMetric("3", "1", "2");
+
+ String firstResult = newRequest().setParam(Param.PAGE, "1").setParam(Param.PAGE_SIZE, "1").execute().outputAsString();
+ String secondResult = newRequest().setParam(Param.PAGE, "2").setParam(Param.PAGE_SIZE, "1").execute().outputAsString();
+ String thirdResult = newRequest().setParam(Param.PAGE, "3").setParam(Param.PAGE_SIZE, "1").execute().outputAsString();
+
+ assertThat(firstResult).contains("custom-key-1").doesNotContain("custom-key-2").doesNotContain("custom-key-3");
+ assertThat(secondResult).contains("custom-key-2").doesNotContain("custom-key-1").doesNotContain("custom-key-3");
+ assertThat(thirdResult).contains("custom-key-3").doesNotContain("custom-key-1").doesNotContain("custom-key-2");
+ }
+
+ @Test
+ public void list_metrics_with_pagination() throws Exception {
+ insertNewCustomMetric("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
+
+ WsTester.Result result = newRequest()
+ .setParam(Param.PAGE, "3")
+ .setParam(Param.PAGE_SIZE, "4")
+ .execute();
+
+ assertThat(StringUtils.countMatches(result.outputAsString(), "custom-key")).isEqualTo(2);
+ }
+
+ @Test
+ public void list_metric_with_is_custom_true() throws Exception {
+ insertNewCustomMetric("1", "2");
+ insertNewNonCustomMetric("3");
+
+ String result = newRequest()
+ .setParam(PARAM_IS_CUSTOM, "true").execute().outputAsString();
+
+ assertThat(result).contains("custom-key-1", "custom-key-2")
+ .doesNotContain("non-custom-key-3");
+ }
+
+ @Test
+ public void list_metric_with_is_custom_false() throws Exception {
+ insertNewCustomMetric("1", "2");
+ insertNewNonCustomMetric("3");
+
+ String result = newRequest()
+ .setParam(PARAM_IS_CUSTOM, "false").execute().outputAsString();
+
+ assertThat(result).doesNotContain("custom-key-1")
+ .doesNotContain("custom-key-2")
+ .contains("non-custom-key-3");
+ }
+
+ @Test
+ public void list_metric_with_chosen_fields() throws Exception {
+ insertNewCustomMetric("1");
+
+ String result = newRequest().setParam(Param.FIELDS, "name").execute().outputAsString();
+
+ assertThat(result).contains("id", "key", "name")
+ .doesNotContain("domain")
+ .doesNotContain("description")
+ .doesNotContain("type");
+ }
+
+ private void insertNewNonCustomMetric(String... ids) {
+ for (String id : ids) {
+ dbClient.metricDao().insert(dbSession, MetricTesting.newDto()
+ .setKey("non-custom-key-" + id)
+ .setEnabled(true)
+ .setUserManaged(false));
+ }
+ dbSession.commit();
+ }
+
+ private void insertNewCustomMetric(String... ids) {
+ for (String id : ids) {
+ dbClient.metricDao().insert(dbSession, newCustomMetric(id));
+ }
+ dbSession.commit();
+ }
+
+ private MetricDto newCustomMetric(String id) {
+ return MetricTesting.newDto()
+ .setKey("custom-key-" + id)
+ .setShortName("custom-name-" + id)
+ .setDomain("custom-domain-" + id)
+ .setDescription("custom-description-" + id)
+ .setValueType("INT")
+ .setUserManaged(true)
+ .setEnabled(true);
+ }
+
+ private WsTester.TestRequest newRequest() {
+ return ws.newGetRequest("api/metrics", "list");
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MetricTesting.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MetricTesting.java
new file mode 100644
index 00000000000..753faf4689c
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/MetricTesting.java
@@ -0,0 +1,54 @@
+/*
+ * 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.measure.ws;
+
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.sonar.api.measures.Metric;
+import org.sonar.core.measure.db.MetricDto;
+
+public class MetricTesting {
+ private MetricTesting() {
+ // static stuff only
+ }
+
+ public static MetricDto newDto() {
+ Metric.ValueType[] metricTypes = Metric.ValueType.values();
+ return new MetricDto()
+ .setId(RandomUtils.nextInt())
+ .setKey(RandomStringUtils.randomAlphanumeric(64))
+ .setShortName(RandomStringUtils.randomAlphanumeric(64))
+ .setValueType(metricTypes[RandomUtils.nextInt(metricTypes.length - 1)].name())
+ .setDomain(RandomStringUtils.randomAlphanumeric(64))
+ .setDescription(RandomStringUtils.randomAlphanumeric(250))
+ .setBestValue(RandomUtils.nextDouble())
+ .setDeleteHistoricalData(RandomUtils.nextBoolean())
+ .setDirection(RandomUtils.nextInt())
+ .setHidden(RandomUtils.nextBoolean())
+ .setEnabled(RandomUtils.nextBoolean())
+ .setOptimizedBestValue(RandomUtils.nextBoolean())
+ .setQualitative(RandomUtils.nextBoolean())
+ .setOrigin(RandomStringUtils.randomAlphabetic(3))
+ .setUserManaged(RandomUtils.nextBoolean())
+ .setWorstValue(RandomUtils.nextDouble());
+ }
+
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/measure/ws/ListActionTest/list_metrics.json b/server/sonar-server/src/test/resources/org/sonar/server/measure/ws/ListActionTest/list_metrics.json
new file mode 100644
index 00000000000..4f5049c8aeb
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/measure/ws/ListActionTest/list_metrics.json
@@ -0,0 +1,25 @@
+{
+ "metrics":[
+ {
+ "key":"custom-key-1",
+ "name":"custom-name-1",
+ "type":"Integer",
+ "domain":"custom-domain-1",
+ "description":"custom-description-1"
+ },
+ {
+ "key":"custom-key-2",
+ "name":"custom-name-2",
+ "type":"Integer",
+ "domain":"custom-domain-2",
+ "description":"custom-description-2"
+ },
+ {
+ "key":"custom-key-3",
+ "name":"custom-name-3",
+ "type":"Integer",
+ "domain":"custom-domain-3",
+ "description":"custom-description-3"
+ }
+ ]
+}