<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-squid</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.sonar</groupId>
- <artifactId>sonar-ws-client</artifactId>
- </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
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;
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() {
}
}
- public SonarClient wsClient() {
- return wsClient;
- }
-
private InputSupplier<InputStream> doRequest(String pathStartingWithSlash, @Nullable Integer timeoutMillis) {
Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /");
String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash);
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;
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) {
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;
}
}
*/
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;
}
}
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;
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"));
*/
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;
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.*;
@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();
}
@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);
}
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<QualityGateCondition> 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<ResolvedCondition> 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);
}