From: Jean-Baptiste Lievremont Date: Thu, 6 Mar 2014 12:47:26 +0000 (+0100) Subject: SONAR-5094 Update Quality Gate show WS and its associated client for easier loading... X-Git-Tag: 4.3~520 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=efe0e18c136dbea99c50eb855966ff1f4d93fdc3;p=sonarqube.git SONAR-5094 Update Quality Gate show WS and its associated client for easier loading of config from batch --- diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java index 92c39485fe7..acff22e1838 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java +++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java @@ -93,8 +93,12 @@ public class QualityGates { return newQualityGate; } - public QualityGateDto get(Long parseId) { - return getNonNullQgate(parseId); + public QualityGateDto get(Long qGateId) { + return getNonNullQgate(qGateId); + } + + public QualityGateDto get(String qGateName) { + return getNonNullQgate(qGateName); } public QualityGateDto rename(long idToRename, String name) { @@ -304,6 +308,14 @@ public class QualityGates { return qGate; } + private QualityGateDto getNonNullQgate(String name) { + QualityGateDto qGate = dao.selectByName(name); + if (qGate == null) { + throw new NotFoundException("There is no quality gate with name=" + name); + } + return qGate; + } + private Metric getNonNullMetric(String metricKey) { Metric metric = metricFinder.findByKey(metricKey); if (metric == null) { 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 index 71ca3ede91f..a60274f2df4 100644 --- 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 @@ -197,7 +197,8 @@ public class QualityGatesWs implements WebService { public void handle(Request request, Response response) { show(request, response); } - }).newParam(PARAM_ID).setDescription("The ID of the quality gate."); + }).newParam(PARAM_ID, "The ID of the quality gate; either this or name must be provided.") + .newParam(PARAM_NAME, "The name of the quality gate; either this or id must be provided."); controller.newAction("destroy") .setDescription("Destroy a quality gate, given its id.") @@ -280,8 +281,19 @@ public class QualityGatesWs implements WebService { } protected void show(Request request, Response response) { - final Long qGateId = parseId(request, PARAM_ID); - QualityGateDto qGate = qualityGates.get(qGateId); + Long qGateId = request.paramAsLong(PARAM_ID); + String qGateName = request.param(PARAM_NAME); + 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."); + } + + QualityGateDto qGate = qGateId == null ? qualityGates.get(qGateName) : qualityGates.get(qGateId); + if (qGateId == null) { + qGateId = qGate.getId(); + } + JsonWriter writer = response.newJsonWriter().beginObject() .prop(PARAM_ID, qGate.getId()) .prop(PARAM_NAME, qGate.getName()); diff --git a/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java b/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java index b12010d00eb..7a8cddf965d 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java @@ -144,7 +144,7 @@ public class QualityGatesTest { } @Test - public void should_get_qgate() throws Exception { + public void should_get_qgate_by_id() throws Exception { long id = 42L; final String name = "Golden"; QualityGateDto existing = new QualityGateDto().setId(id).setName(name); @@ -153,6 +153,21 @@ public class QualityGatesTest { verify(dao).selectById(id); } + @Test + public void should_get_qgate_by_name() throws Exception { + long id = 42L; + final String name = "Golden"; + QualityGateDto existing = new QualityGateDto().setId(id).setName(name); + when(dao.selectByName(name)).thenReturn(existing); + assertThat(qGates.get(name)).isEqualTo(existing); + verify(dao).selectByName(name); + } + + @Test(expected = NotFoundException.class) + public void should_fail_to_find_qgate_by_name() throws Exception { + qGates.get("Does not exist"); + } + @Test public void should_rename_qgate() throws Exception { long id = 42L; 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/QualityGatesWsTest.java index 2011e67bef6..29e162df83a 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/QualityGatesWsTest.java @@ -278,7 +278,7 @@ public class QualityGatesWsTest { } @Test - public void show_nominal() throws Exception { + public void show_by_id_nominal() throws Exception { long gateId = 12345L; when(qGates.get(gateId)).thenReturn(new QualityGateDto().setId(gateId).setName("Golden")); when(qGates.listConditions(gateId)).thenReturn(ImmutableList.of( @@ -292,6 +292,32 @@ public class QualityGatesWsTest { + "]}"); } + @Test + public void show_by_name_nominal() throws Exception { + long qGateId = 12345L; + String gateName = "Golden"; + when(qGates.get(gateName)).thenReturn(new QualityGateDto().setId(qGateId).setName(gateName)); + when(qGates.listConditions(qGateId)).thenReturn(ImmutableList.of( + new QualityGateConditionDto().setId(1L).setMetricKey("ncloc").setOperator("GT").setErrorThreshold("10000"), + new QualityGateConditionDto().setId(2L).setMetricKey("new_coverage").setOperator("LT").setWarningThreshold("90").setPeriod(3) + )); + tester.newRequest("show").setParam("name", gateName).execute().assertJson( + "{'id':12345,'name':'Golden','conditions':[" + + "{'id':1,'metric':'ncloc','op':'GT','error':'10000'}," + + "{'id':2,'metric':'new_coverage','op':'LT','warning':'90','period':3}" + + "]}"); + } + + @Test(expected = BadRequestException.class) + public void show_without_parameters() throws Exception { + tester.newRequest("show").execute(); + } + + @Test(expected = BadRequestException.class) + public void show_with_both_parameters() throws Exception { + tester.newRequest("show").setParam("id", "12345").setParam("name", "Polop").execute(); + } + @Test public void create_condition_nominal() throws Exception { long qGateId = 42L; diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateClient.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateClient.java index 9f5563f1cd4..073cae9a868 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateClient.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateClient.java @@ -19,7 +19,6 @@ */ package org.sonar.wsclient.qualitygate; -import java.util.Collection; /** * @since 4.3 @@ -32,7 +31,9 @@ public interface QualityGateClient { QualityGate rename(long qGateId, String qGateName); - Collection conditions(long qGateId); + QualityGateDetails show(long qGateId); + + QualityGateDetails show(String qGateName); void destroy(long qGateId); diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateDetails.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateDetails.java new file mode 100644 index 00000000000..69b3e8e5581 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/QualityGateDetails.java @@ -0,0 +1,30 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.wsclient.qualitygate; + +import java.util.Collection; + +/** + * @since 4.3 + */ +public interface QualityGateDetails extends QualityGate { + + Collection conditions(); +} diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClient.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClient.java index 1b95997bb75..601acbaf2eb 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClient.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClient.java @@ -21,10 +21,7 @@ package org.sonar.wsclient.qualitygate.internal; import org.json.simple.JSONValue; import org.sonar.wsclient.internal.HttpRequestFactory; -import org.sonar.wsclient.qualitygate.QualityGate; -import org.sonar.wsclient.qualitygate.QualityGateClient; -import org.sonar.wsclient.qualitygate.QualityGateCondition; -import org.sonar.wsclient.qualitygate.QualityGates; +import org.sonar.wsclient.qualitygate.*; import java.util.*; @@ -67,9 +64,15 @@ public class DefaultQualityGateClient implements QualityGateClient { } @Override - public Collection conditions(long qGateId) { + public QualityGateDetails show(long qGateId) { String json = requestFactory.get(SHOW_URL, Collections.singletonMap("id", (Object) qGateId)); - return jsonToConditions(json); + return jsonToDetails(json); + } + + @Override + public QualityGateDetails show(String qGateName) { + String json = requestFactory.get(SHOW_URL, Collections.singletonMap("name", (Object) qGateName)); + return jsonToDetails(json); } @Override @@ -99,6 +102,12 @@ public class DefaultQualityGateClient implements QualityGateClient { return new DefaultQualityGates((Map) jsonRoot); } + @SuppressWarnings({"rawtypes", "unchecked"}) + private QualityGateDetails jsonToDetails(String json) { + Map jsonRoot = (Map) JSONValue.parse(json); + return new DefaultQualityGateDetails((Map) jsonRoot, jsonToConditions(json)); + } + @SuppressWarnings({"rawtypes", "unchecked"}) private Collection jsonToConditions(String json) { Map jsonRoot = (Map) JSONValue.parse(json); @@ -109,4 +118,6 @@ public class DefaultQualityGateClient implements QualityGateClient { } return conditions; } + + } diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateDetails.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateDetails.java new file mode 100644 index 00000000000..5f5c796e371 --- /dev/null +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateDetails.java @@ -0,0 +1,42 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.wsclient.qualitygate.internal; + +import org.sonar.wsclient.qualitygate.QualityGateCondition; +import org.sonar.wsclient.qualitygate.QualityGateDetails; + +import java.util.Collection; +import java.util.Map; + +public class DefaultQualityGateDetails extends DefaultQualityGate implements QualityGateDetails { + + private final Collection conditions; + + DefaultQualityGateDetails(Map json, Collection conditions) { + super(json); + this.conditions = conditions; + } + + @Override + public Collection conditions() { + return conditions; + } + +} diff --git a/sonar-ws-client/src/test/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClientTest.java b/sonar-ws-client/src/test/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClientTest.java index 24fd6d507c7..a2628931f74 100644 --- a/sonar-ws-client/src/test/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClientTest.java +++ b/sonar-ws-client/src/test/java/org/sonar/wsclient/qualitygate/internal/DefaultQualityGateClientTest.java @@ -23,10 +23,7 @@ import org.junit.Rule; import org.junit.Test; import org.sonar.wsclient.MockHttpServerInterceptor; import org.sonar.wsclient.internal.HttpRequestFactory; -import org.sonar.wsclient.qualitygate.QualityGate; -import org.sonar.wsclient.qualitygate.QualityGateClient; -import org.sonar.wsclient.qualitygate.QualityGateCondition; -import org.sonar.wsclient.qualitygate.QualityGates; +import org.sonar.wsclient.qualitygate.*; import java.net.HttpURLConnection; import java.util.Collection; @@ -92,7 +89,7 @@ public class DefaultQualityGateClientTest { } @Test - public void should_show_qualitygate_conditions() { + public void should_show_qualitygate_by_id() { HttpRequestFactory requestFactory = new HttpRequestFactory(httpServer.url()); httpServer.stubResponseBody("{\"id\":5,\"name\":\"Sonar way\",\"conditions\":[" @@ -108,10 +105,52 @@ public class DefaultQualityGateClientTest { QualityGateClient client = new DefaultQualityGateClient(requestFactory); - Collection conditions = client.conditions(5L); - + QualityGateDetails qGate = client.show(5L); assertThat(httpServer.requestedPath()).isEqualTo("/api/qualitygates/show?id=5"); + assertThat(qGate.id()).isEqualTo(5L); + assertThat(qGate.name()).isEqualTo("Sonar way"); + + Collection conditions = qGate.conditions(); + assertThat(conditions).hasSize(8); + Iterator condIterator = conditions.iterator(); + QualityGateCondition first = condIterator.next(); + assertThat(first.id()).isEqualTo(6L); + QualityGateCondition second = condIterator.next(); + assertThat(second.period()).isNull(); + QualityGateCondition third = condIterator.next(); + assertThat(third.metricKey()).isEqualTo("test_errors"); + QualityGateCondition fourth = condIterator.next(); + assertThat(fourth.operator()).isEqualTo("GT"); + QualityGateCondition fifth = condIterator.next(); + assertThat(fifth.errorThreshold()).isEqualTo("80%"); + assertThat(fifth.period()).isEqualTo(3); + QualityGateCondition sixth = condIterator.next(); + assertThat(sixth.warningThreshold()).isEqualTo("0"); + } + @Test + public void should_show_qualitygate_by_name() { + HttpRequestFactory requestFactory = new HttpRequestFactory(httpServer.url()); + + httpServer.stubResponseBody("{\"id\":5,\"name\":\"Sonar way\",\"conditions\":[" + + "{\"id\":6,\"metric\":\"blocker_violations\",\"op\":\"GT\",\"warning\":\"\",\"error\":\"0\"}," + + "{\"id\":7,\"metric\":\"critical_violations\",\"op\":\"GT\",\"warning\":\"\",\"error\":\"0\"}," + + "{\"id\":10,\"metric\":\"test_errors\",\"op\":\"GT\",\"warning\":\"\",\"error\":\"0\"}," + + "{\"id\":11,\"metric\":\"test_failures\",\"op\":\"GT\",\"warning\":\"\",\"error\":\"0\"}," + + "{\"id\":12,\"metric\":\"new_coverage\",\"op\":\"LT\",\"warning\":\"\",\"error\":\"80%\",\"period\":3}," + + "{\"id\":13,\"metric\":\"open_issues\",\"op\":\"GT\",\"warning\":\"0\",\"error\":\"\"}," + + "{\"id\":14,\"metric\":\"reopened_issues\",\"op\":\"GT\",\"warning\":\"0\",\"error\":\"\"}," + + "{\"id\":15,\"metric\":\"skipped_tests\",\"op\":\"GT\",\"warning\":\"0\",\"error\":\"\"}" + + "]}"); + + QualityGateClient client = new DefaultQualityGateClient(requestFactory); + + QualityGateDetails qGate = client.show("Sonar way"); + assertThat(httpServer.requestedPath()).isEqualTo("/api/qualitygates/show?name=Sonar%20way"); + assertThat(qGate.id()).isEqualTo(5L); + assertThat(qGate.name()).isEqualTo("Sonar way"); + + Collection conditions = qGate.conditions(); assertThat(conditions).hasSize(8); Iterator condIterator = conditions.iterator(); QualityGateCondition first = condIterator.next(); @@ -129,6 +168,7 @@ public class DefaultQualityGateClientTest { assertThat(sixth.warningThreshold()).isEqualTo("0"); } + @Test public void should_destroy_qualitygate() { HttpRequestFactory requestFactory = new HttpRequestFactory(httpServer.url());