From c0e6c4b6dd0f8c1b92b5941807c2a137e57ba14d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Wed, 12 Mar 2014 11:01:27 +0100 Subject: [PATCH] SONAR-5094 Remove dependency on sonar-ws-client from sonar-batch --- sonar-batch/pom.xml | 4 - .../sonar/batch/bootstrap/ServerClient.java | 7 -- .../qualitygate/QualityGateProvider.java | 51 +++++++----- .../batch/qualitygate/ResolvedCondition.java | 50 ++++++------ .../batch/bootstrap/ServerClientTest.java | 10 --- .../qualitygate/QualityGateProviderTest.java | 77 +++++++++---------- 6 files changed, 91 insertions(+), 108 deletions(-) diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index f4b09bf2142..4d473f38149 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -45,10 +45,6 @@ org.codehaus.sonar sonar-squid - - org.codehaus.sonar - sonar-ws-client - org.slf4j slf4j-api diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java index fee1e67ba6e..111f28b36b8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java @@ -31,7 +31,6 @@ import org.sonar.api.CoreProperties; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrapper.EnvironmentInformation; -import org.sonar.wsclient.SonarClient; import javax.annotation.Nullable; @@ -50,12 +49,10 @@ public class ServerClient implements BatchComponent { private BootstrapSettings settings; private HttpDownloader.BaseHttpDownloader downloader; - private SonarClient wsClient; public ServerClient(BootstrapSettings settings, EnvironmentInformation env) { this.settings = settings; this.downloader = new HttpDownloader.BaseHttpDownloader(settings.properties(), env.toString()); - this.wsClient = SonarClient.create(getURL()); } public String getURL() { @@ -96,10 +93,6 @@ public class ServerClient implements BatchComponent { } } - public SonarClient wsClient() { - return wsClient; - } - private InputSupplier doRequest(String pathStartingWithSlash, @Nullable Integer timeoutMillis) { Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /"); String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash); diff --git a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateProvider.java b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateProvider.java index 39028ab8a07..2babe56d104 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateProvider.java @@ -20,17 +20,17 @@ package org.sonar.batch.qualitygate; import com.google.common.annotations.VisibleForTesting; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import org.picocontainer.injectors.ProviderAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.config.Settings; import org.sonar.api.measures.MetricFinder; +import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.MessageException; import org.sonar.batch.bootstrap.ServerClient; -import org.sonar.wsclient.base.HttpException; -import org.sonar.wsclient.qualitygate.QualityGateClient; -import org.sonar.wsclient.qualitygate.QualityGateCondition; -import org.sonar.wsclient.qualitygate.QualityGateDetails; import java.net.HttpURLConnection; @@ -40,6 +40,8 @@ public class QualityGateProvider extends ProviderAdapter { private static final String PROPERTY_QUALITY_GATE = "sonar.qualitygate"; + private static final String SHOW_URL = "/api/qualitygates/show"; + private QualityGate instance; public QualityGate provide(Settings settings, ServerClient client, MetricFinder metricFinder) { @@ -56,41 +58,48 @@ public class QualityGateProvider extends ProviderAdapter { if (qualityGateSetting == null) { logger.info("No quality gate is configured."); } else { - result = load(qualityGateSetting, client.wsClient().qualityGateClient(), metricFinder); + result = load(qualityGateSetting, client, metricFinder); logger.info("Loaded quality gate '{}'", result.name()); } return result; } - private QualityGate load(String qualityGateSetting, QualityGateClient qualityGateClient, MetricFinder metricFinder) { - QualityGateDetails definitionFromServer = null; + private QualityGate load(String qualityGateSetting, ServerClient client, MetricFinder metricFinder) { + QualityGate configuredGate = null; try { - definitionFromServer = fetch(qualityGateSetting, qualityGateClient); - } catch (HttpException serverError) { - if (serverError.status() == HttpURLConnection.HTTP_NOT_FOUND) { + configuredGate = fetch(qualityGateSetting, client, metricFinder); + } catch (HttpDownloader.HttpException serverError) { + if (serverError.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { throw MessageException.of("No quality gate found with configured value '" + qualityGateSetting + "'. Please check your configuration."); } else { throw serverError; } } - QualityGate configuredGate = new QualityGate(definitionFromServer.name()); - - for (QualityGateCondition condition: definitionFromServer.conditions()) { - configuredGate.add(new ResolvedCondition(condition, metricFinder.findByKey(condition.metricKey()))); - } - return configuredGate; } - private QualityGateDetails fetch(String qualityGateSetting, QualityGateClient qualityGateClient) { - QualityGateDetails definitionFromServer = null; + private QualityGate fetch(String qualityGateSetting, ServerClient client, MetricFinder metricFinder) { + String jsonText = null; try { long qGateId = Long.valueOf(qualityGateSetting); - definitionFromServer = qualityGateClient.show(qGateId); + jsonText = client.request(SHOW_URL + "?id="+qGateId); } catch(NumberFormatException configIsNameInsteadOfId) { - definitionFromServer = qualityGateClient.show(qualityGateSetting); + jsonText = client.request(SHOW_URL + "?name="+qualityGateSetting); } - return definitionFromServer; + + JsonParser parser = new JsonParser(); + JsonObject root = parser.parse(jsonText).getAsJsonObject(); + + QualityGate configuredGate = new QualityGate(root.get("name").getAsString()); + + if (root.has("conditions")) { + for (JsonElement condition: root.get("conditions").getAsJsonArray()) { + JsonObject conditionObject = condition.getAsJsonObject(); + configuredGate.add(new ResolvedCondition(conditionObject, metricFinder.findByKey(conditionObject.get("metric").getAsString()))); + } + } + + return configuredGate; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/ResolvedCondition.java b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/ResolvedCondition.java index 8f63a614640..6f893419c3d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/qualitygate/ResolvedCondition.java +++ b/sonar-batch/src/main/java/org/sonar/batch/qualitygate/ResolvedCondition.java @@ -19,51 +19,53 @@ */ package org.sonar.batch.qualitygate; +import javax.annotation.CheckForNull; + +import com.google.gson.JsonObject; import org.sonar.api.measures.Metric; -import org.sonar.wsclient.qualitygate.QualityGateCondition; -public class ResolvedCondition implements QualityGateCondition { +public class ResolvedCondition { + + private static final String ATTRIBUTE_PERIOD = "period"; + + private static final String ATTRIBUTE_ERROR = "error"; - private QualityGateCondition wrapped; + private static final String ATTRIBUTE_WARNING = "warning"; + + private JsonObject json; private Metric metric; - public ResolvedCondition(QualityGateCondition condition, Metric metric) { - this.wrapped = condition; + public ResolvedCondition(JsonObject jsonObject, Metric metric) { + this.json = jsonObject; this.metric = metric; } - public Metric metric() { - return metric; - } - - @Override public Long id() { - return wrapped.id(); + return json.get("id").getAsLong(); } - @Override public String metricKey() { - return wrapped.metricKey(); + return json.get("metric").getAsString(); + } + + public Metric metric() { + return metric; } - @Override public String operator() { - return wrapped.operator(); + return json.get("op").getAsString(); } - @Override - public String warningThreshold() { - return wrapped.warningThreshold(); + public @CheckForNull String warningThreshold() { + return json.has(ATTRIBUTE_WARNING) ? json.get(ATTRIBUTE_WARNING).getAsString() : null; } - @Override - public String errorThreshold() { - return wrapped.errorThreshold(); + public @CheckForNull String errorThreshold() { + return json.has(ATTRIBUTE_ERROR) ? json.get(ATTRIBUTE_ERROR).getAsString() : null; } - @Override - public Integer period() { - return wrapped.period(); + public @CheckForNull Integer period() { + return json.has(ATTRIBUTE_PERIOD) ? json.get(ATTRIBUTE_PERIOD).getAsInt() : null; } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java index feaa3d125f0..742f53e25dc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerClientTest.java @@ -32,7 +32,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.batch.bootstrapper.EnvironmentInformation; -import org.sonar.wsclient.SonarClient; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -137,15 +136,6 @@ public class ServerClientTest { newServerClient().request("/foo"); } - @Test - public void should_give_access_to_ws_client() throws Exception { - server = new MockHttpServer(); - server.start(); - - SonarClient wsClient = newServerClient().wsClient(); - assertThat(wsClient).isNotNull(); - } - private ServerClient newServerClient() { when(settings.property(eq("sonar.host.url"), anyString())).thenReturn("http://localhost:" + server.getPort()); return new ServerClient(settings, new EnvironmentInformation("Junit", "4")); diff --git a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateProviderTest.java index 05bd725c067..4e8cf612c2c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateProviderTest.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.qualitygate; -import com.google.common.collect.ImmutableList; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -28,16 +26,13 @@ import org.mockito.runners.MockitoJUnitRunner; import org.slf4j.Logger; import org.sonar.api.config.Settings; import org.sonar.api.measures.MetricFinder; +import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.MessageException; import org.sonar.batch.bootstrap.ServerClient; -import org.sonar.wsclient.SonarClient; -import org.sonar.wsclient.base.HttpException; -import org.sonar.wsclient.qualitygate.QualityGateClient; -import org.sonar.wsclient.qualitygate.QualityGateCondition; -import org.sonar.wsclient.qualitygate.QualityGateDetails; import java.net.HttpURLConnection; -import java.util.Collection; +import java.net.URI; +import java.util.Iterator; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -54,19 +49,9 @@ public class QualityGateProviderTest { @Mock private MetricFinder metricFinder; - @Mock - private QualityGateClient qualityGateClient; - @Mock private Logger logger; - @Before - public void initMocks() { - SonarClient wsClient = mock(SonarClient.class); - when(client.wsClient()).thenReturn(wsClient); - when(wsClient.qualityGateClient()).thenReturn(qualityGateClient); - } - @Test public void should_load_empty_quality_gate_from_default_settings() { QualityGateProvider provider = new QualityGateProvider(); @@ -77,15 +62,14 @@ public class QualityGateProviderTest { } @Test - public void should_load_quality_gate_using_name() { + public void should_load_empty_quality_gate_using_name() { String qGateName = "Sonar way"; when(settings.getString("sonar.qualitygate")).thenReturn(qGateName); - QualityGateDetails qGate = mock(QualityGateDetails.class); - when(qualityGateClient.show(qGateName)).thenReturn(qGate); - when(qGate.name()).thenReturn(qGateName); - QualityGate actualGate = new QualityGateProvider().init(settings, client, metricFinder, logger); - assertThat(actualGate.name()).isEqualTo(qGateName); - assertThat(actualGate.isEnabled()).isTrue(); + when(client.request("/api/qualitygates/show?name=Sonar way")).thenReturn("{'id':12345,'name':'Sonar way'}"); + QualityGate qGate = new QualityGateProvider().init(settings, client, metricFinder, logger); + assertThat(qGate.name()).isEqualTo(qGateName); + assertThat(qGate.isEnabled()).isTrue(); + assertThat(qGate.conditions()).isEmpty(); verify(logger).info("Loaded quality gate '{}'", qGateName); } @@ -94,36 +78,45 @@ public class QualityGateProviderTest { long qGateId = 12345L; String qGateName = "Sonar way"; when(settings.getString("sonar.qualitygate")).thenReturn(Long.toString(qGateId)); - QualityGateDetails qGate = mock(QualityGateDetails.class); - when(qualityGateClient.show(qGateId)).thenReturn(qGate); - when(qGate.name()).thenReturn(qGateName); - String metricKey1 = "metric1"; - QualityGateCondition serverCondition1 = mock(QualityGateCondition.class); - when(serverCondition1.metricKey()).thenReturn(metricKey1); - String metricKey2 = "metric2"; - QualityGateCondition serverCondition2 = mock(QualityGateCondition.class); - when(serverCondition2.metricKey()).thenReturn(metricKey2); - Collection conditions = ImmutableList.of(serverCondition1, serverCondition2); - when(qGate.conditions()).thenReturn(conditions); - assertThat(new QualityGateProvider().init(settings, client, metricFinder, logger).name()).isEqualTo(qGateName); + when(client.request("/api/qualitygates/show?id=12345")).thenReturn("{'id':12345,'name':'Sonar way','conditions':[" + + "{'id':1,'metric':'metric1','op':'EQ','warning':'POLOP'}," + + "{'id':2,'metric':'metric2','op':'NE','error':'PALAP','period':3}" + + "]}"); + + QualityGate qGate = new QualityGateProvider().init(settings, client, metricFinder, logger); + + assertThat(qGate.name()).isEqualTo(qGateName); + assertThat(qGate.conditions()).hasSize(2); + Iterator conditions = qGate.conditions().iterator(); + ResolvedCondition cond1 = conditions.next(); + assertThat(cond1.warningThreshold()).isEqualTo("POLOP"); + assertThat(cond1.errorThreshold()).isNull(); + assertThat(cond1.period()).isNull(); + ResolvedCondition cond2 = conditions.next(); + assertThat(cond2.warningThreshold()).isNull(); + assertThat(cond2.errorThreshold()).isEqualTo("PALAP"); + assertThat(cond2.period()).isEqualTo(3); + verify(logger).info("Loaded quality gate '{}'", qGateName); - verify(metricFinder).findByKey(metricKey1); - verify(metricFinder).findByKey(metricKey2); + verify(metricFinder).findByKey("metric1"); + verify(metricFinder).findByKey("metric2"); } @Test(expected = MessageException.class) public void should_stop_analysis_if_gate_not_found() { String qGateName = "Sonar way"; when(settings.getString("sonar.qualitygate")).thenReturn(qGateName); - when(qualityGateClient.show(qGateName)).thenThrow(new HttpException("http://server/api/qualitygates/show?name=Sonar%20way", HttpURLConnection.HTTP_NOT_FOUND)); + when(client.request("/api/qualitygates/show?name=Sonar way")).thenThrow( + new HttpDownloader.HttpException(URI.create("/api/qualitygates/show?name=Sonar%20way"), HttpURLConnection.HTTP_NOT_FOUND)); new QualityGateProvider().provide(settings, client, metricFinder); } - @Test(expected = HttpException.class) + @Test(expected = HttpDownloader.HttpException.class) public void should_stop_analysis_if_server_error() { String qGateName = "Sonar way"; when(settings.getString("sonar.qualitygate")).thenReturn(qGateName); - when(qualityGateClient.show(qGateName)).thenThrow(new HttpException("http://server/api/qualitygates/show?name=Sonar%20way", HttpURLConnection.HTTP_NOT_ACCEPTABLE)); + when(client.request("/api/qualitygates/show?name=Sonar way")).thenThrow( + new HttpDownloader.HttpException(URI.create("/api/qualitygates/show?name=Sonar%20way"), HttpURLConnection.HTTP_NOT_ACCEPTABLE)); new QualityGateProvider().provide(settings, client, metricFinder); } -- 2.39.5