]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5629 Call /batch/upload_report at the end of an analysis
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 17 Sep 2014 09:26:32 +0000 (11:26 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 17 Sep 2014 11:23:45 +0000 (13:23 +0200)
sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
sonar-batch/src/main/java/org/sonar/batch/phases/UpdateStatusJob.java
sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateProvider.java
sonar-batch/src/main/java/org/sonar/batch/scan/LastSnapshots.java
sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/LastSnapshotsTest.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/HttpDownloader.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/HttpDownloaderTest.java

index 99f5f02897880760b0953bc2c905a06e972a4b86..46720c4e22416e906aa0d4472fa3778e164bdefa 100644 (file)
@@ -143,7 +143,7 @@ public class JdbcDriverHolder {
       String indexContent = serverClient.request(url);
       // File is empty when H2 is used
       if (Strings.isNullOrEmpty(indexContent)) {
-        return new String[]{};
+        return new String[] {};
       }
       return indexContent.split("\\|");
     } catch (Exception e) {
index d43ef8e0e711ded34dc5f5416efb6eb1ee6c8765..86130986d1faf3783fb470f9d1df65637524350b 100644 (file)
@@ -46,6 +46,7 @@ import java.net.URI;
  */
 public class ServerClient implements BatchComponent {
 
+  private static final String GET = "GET";
   private BootstrapProperties props;
   private HttpDownloader.BaseHttpDownloader downloader;
 
@@ -64,7 +65,7 @@ public class ServerClient implements BatchComponent {
 
   public void download(String pathStartingWithSlash, File toFile, @Nullable Integer readTimeoutMillis) {
     try {
-      InputSupplier<InputStream> inputSupplier = doRequest(pathStartingWithSlash, readTimeoutMillis);
+      InputSupplier<InputStream> inputSupplier = doRequest(pathStartingWithSlash, GET, readTimeoutMillis);
       Files.copy(inputSupplier, toFile);
     } catch (HttpDownloader.HttpException he) {
       throw handleHttpException(he);
@@ -74,15 +75,23 @@ public class ServerClient implements BatchComponent {
   }
 
   public String request(String pathStartingWithSlash) {
-    return request(pathStartingWithSlash, true);
+    return request(pathStartingWithSlash, GET, true);
+  }
+
+  public String request(String pathStartingWithSlash, String requestMethod) {
+    return request(pathStartingWithSlash, requestMethod, true);
   }
 
   public String request(String pathStartingWithSlash, boolean wrapHttpException) {
-    return request(pathStartingWithSlash, wrapHttpException, null);
+    return request(pathStartingWithSlash, GET, wrapHttpException, null);
+  }
+
+  public String request(String pathStartingWithSlash, String requestMethod, boolean wrapHttpException) {
+    return request(pathStartingWithSlash, requestMethod, wrapHttpException, null);
   }
 
-  public String request(String pathStartingWithSlash, boolean wrapHttpException, @Nullable Integer timeoutMillis) {
-    InputSupplier<InputStream> inputSupplier = doRequest(pathStartingWithSlash, timeoutMillis);
+  public String request(String pathStartingWithSlash, String requestMethod, boolean wrapHttpException, @Nullable Integer timeoutMillis) {
+    InputSupplier<InputStream> inputSupplier = doRequest(pathStartingWithSlash, requestMethod, timeoutMillis);
     try {
       return IOUtils.toString(inputSupplier.getInput(), "UTF-8");
     } catch (HttpDownloader.HttpException e) {
@@ -92,7 +101,7 @@ public class ServerClient implements BatchComponent {
     }
   }
 
-  private InputSupplier<InputStream> doRequest(String pathStartingWithSlash, @Nullable Integer timeoutMillis) {
+  private InputSupplier<InputStream> doRequest(String pathStartingWithSlash, String requestMethod, @Nullable Integer timeoutMillis) {
     Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /");
     String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash);
 
@@ -100,9 +109,9 @@ public class ServerClient implements BatchComponent {
     try {
       InputSupplier<InputStream> inputSupplier;
       if (Strings.isNullOrEmpty(getLogin())) {
-        inputSupplier = downloader.newInputSupplier(uri, timeoutMillis);
+        inputSupplier = downloader.newInputSupplier(uri, requestMethod, timeoutMillis);
       } else {
-        inputSupplier = downloader.newInputSupplier(uri, getLogin(), getPassword(), timeoutMillis);
+        inputSupplier = downloader.newInputSupplier(uri, requestMethod, getLogin(), getPassword(), timeoutMillis);
       }
       return inputSupplier;
     } catch (Exception e) {
index d3faf902b485b95b13df83b553baee9d50d77690..fabac1e31d0ccdbd0fb104114810045e49b43ea0 100644 (file)
@@ -29,7 +29,6 @@ import org.sonar.api.database.DatabaseSession;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.SonarException;
 import org.sonar.batch.bootstrap.AnalysisMode;
 import org.sonar.batch.bootstrap.ServerClient;
 import org.sonar.batch.index.ResourcePersister;
@@ -65,21 +64,28 @@ public class UpdateStatusJob implements BatchComponent {
   public void execute() {
     disablePreviousSnapshot();
     enableCurrentSnapshot();
-    evictPreviewDB();
+    uploadReport();
   }
 
   @VisibleForTesting
-  void evictPreviewDB() {
+  void uploadReport() {
     if (analysisMode.isPreview()) {
-      // If this is a preview analysis then we should not evict remote preview database
+      // If this is a preview analysis then we should not upload reports
       return;
     }
     String url = "/batch_bootstrap/evict?project=" + project.getId();
     try {
-      LOG.debug("Evict preview database");
-      server.request(url);
+      LOG.debug("Upload report");
+      server.request(url, "POST");
     } catch (Exception e) {
-      throw new SonarException("Unable to evict preview database: " + url, e);
+      throw new IllegalStateException("Unable to evict preview database: " + url, e);
+    }
+    url = "/batch/upload_report?project=" + project.getEffectiveKey();
+    try {
+      LOG.debug("Publish results");
+      server.request(url, "POST");
+    } catch (Exception e) {
+      throw new IllegalStateException("Unable to publish results: " + url, e);
     }
   }
 
index 7294e4e668bf2ae27fa40c76f2384ae016ed7158..5333c767ee17a4a2778dd6ad12cf39f0ba0d9578 100644 (file)
@@ -36,7 +36,6 @@ import java.net.HttpURLConnection;
 
 public class QualityGateProvider extends ProviderAdapter {
 
-
   private static final Logger LOG = LoggerFactory.getLogger(QualityGateProvider.class);
 
   private static final String PROPERTY_QUALITY_GATE = "sonar.qualitygate";
@@ -86,9 +85,9 @@ public class QualityGateProvider extends ProviderAdapter {
     String jsonText = null;
     try {
       long qGateId = Long.valueOf(qualityGateSetting);
-      jsonText = client.request(SHOW_URL + "?id="+qGateId, false);
-    } catch(NumberFormatException configIsNameInsteadOfId) {
-      jsonText = client.request(SHOW_URL + "?name="+qualityGateSetting, false);
+      jsonText = client.request(SHOW_URL + "?id=" + qGateId, false);
+    } catch (NumberFormatException configIsNameInsteadOfId) {
+      jsonText = client.request(SHOW_URL + "?name=" + qualityGateSetting, false);
     }
 
     JsonParser parser = new JsonParser();
@@ -97,7 +96,7 @@ public class QualityGateProvider extends ProviderAdapter {
     QualityGate configuredGate = new QualityGate(root.get("name").getAsString());
 
     if (root.has(ATTRIBUTE_CONDITIONS)) {
-      for (JsonElement condition: root.get(ATTRIBUTE_CONDITIONS).getAsJsonArray()) {
+      for (JsonElement condition : root.get(ATTRIBUTE_CONDITIONS).getAsJsonArray()) {
         JsonObject conditionObject = condition.getAsJsonObject();
         configuredGate.add(new ResolvedCondition(conditionObject, metricFinder.findByKey(conditionObject.get("metric").getAsString())));
       }
index f3917d40f20b55da965e8c0138bb2c2852c25d73..3f2b0225940268bd9e1c2d28817518fabf0263ed 100644 (file)
@@ -64,7 +64,7 @@ public class LastSnapshots implements BatchComponent {
   private String loadSourceFromWs(Resource resource) {
     TimeProfiler profiler = new TimeProfiler(LOG).start("Load previous source code of: " + resource.getEffectiveKey()).setLevelToDebug();
     try {
-      return server.request("/api/sources?resource=" + resource.getEffectiveKey() + "&format=txt", false, analysisMode.getPreviewReadTimeoutSec() * 1000);
+      return server.request("/api/sources?resource=" + resource.getEffectiveKey() + "&format=txt", "GET", false, analysisMode.getPreviewReadTimeoutSec() * 1000);
     } catch (HttpDownloader.HttpException he) {
       if (he.getResponseCode() == 404) {
         return "";
index 9768619144ebb3c974f31cb53f975691b8be3826..b39d4c918327dc3d13f94d60a84d9d8d14d56eae 100644 (file)
@@ -40,6 +40,7 @@ import javax.persistence.Query;
 
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -118,19 +119,20 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
   }
 
   @Test
-  public void should_evict_cache_for_regular_analysis() throws Exception {
+  public void should_publish_results_for_regular_analysis() throws Exception {
     Settings settings = new Settings();
     Project project = new Project("struts");
     ServerClient serverClient = mock(ServerClient.class);
     UpdateStatusJob job = new UpdateStatusJob(settings, serverClient, mock(DatabaseSession.class),
       mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
-    job.evictPreviewDB();
-    verify(serverClient).request(contains("/batch_bootstrap/evict"));
+    job.uploadReport();
+    verify(serverClient).request(contains("/batch_bootstrap/evict"), eq("POST"));
+    verify(serverClient).request(contains("/batch/upload_report"), eq("POST"));
   }
 
   @Test
-  public void should_not_evict_cache_for_preview_analysis() throws Exception {
+  public void should_not_publish_results_for_preview_analysis() throws Exception {
     Settings settings = new Settings();
     when(mode.isPreview()).thenReturn(true);
     Project project = new Project("struts");
@@ -138,7 +140,7 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
     UpdateStatusJob job = new UpdateStatusJob(settings, serverClient, mock(DatabaseSession.class),
       mock(ResourcePersister.class), project, mock(Snapshot.class), mode);
 
-    job.evictPreviewDB();
+    job.uploadReport();
     verify(serverClient, never()).request(anyString());
   }
 }
index d6cddb4447d81be7a40636526cedbcfe9834fef6..d0624082e96b0d194aea2d27ae458adc8cbdd79e 100644 (file)
@@ -79,21 +79,21 @@ public class LastSnapshotsTest extends AbstractDbUnitTestCase {
   public void should_download_source_from_ws_if_preview_mode() {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
-    when(server.request(anyString(), eq(false), eq(30 * 1000))).thenReturn("downloaded source of Bar.c");
+    when(server.request(anyString(), eq("GET"), eq(false), eq(30 * 1000))).thenReturn("downloaded source of Bar.c");
 
     when(mode.isPreview()).thenReturn(true);
     LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     String source = lastSnapshots.getSource(newFile());
     assertThat(source).isEqualTo("downloaded source of Bar.c");
-    verify(server).request("/api/sources?resource=myproject:org/foo/Bar.c&format=txt", false, 30 * 1000);
+    verify(server).request("/api/sources?resource=myproject:org/foo/Bar.c&format=txt", "GET", false, 30 * 1000);
   }
 
   @Test
   public void should_fail_to_download_source_from_ws() throws URISyntaxException {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
-    when(server.request(anyString(), eq(false), eq(30 * 1000))).thenThrow(new HttpDownloader.HttpException(new URI(""), 500));
+    when(server.request(anyString(), eq("GET"), eq(false), eq(30 * 1000))).thenThrow(new HttpDownloader.HttpException(new URI(""), 500));
 
     when(mode.isPreview()).thenReturn(true);
     LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
@@ -106,14 +106,14 @@ public class LastSnapshotsTest extends AbstractDbUnitTestCase {
   public void should_return_empty_source_if_preview_mode_and_no_last_snapshot() throws URISyntaxException {
     setupData("last_snapshot");
     ServerClient server = mock(ServerClient.class);
-    when(server.request(anyString(), eq(false), eq(30 * 1000))).thenThrow(new HttpDownloader.HttpException(new URI(""), 404));
+    when(server.request(anyString(), eq("GET"), eq(false), eq(30 * 1000))).thenThrow(new HttpDownloader.HttpException(new URI(""), 404));
 
     when(mode.isPreview()).thenReturn(true);
     LastSnapshots lastSnapshots = new LastSnapshots(mode, getSession(), server);
 
     String source = lastSnapshots.getSource(newFile());
     assertThat(source).isEqualTo("");
-    verify(server).request("/api/sources?resource=myproject:org/foo/Bar.c&format=txt", false, 30 * 1000);
+    verify(server).request("/api/sources?resource=myproject:org/foo/Bar.c&format=txt", "GET", false, 30 * 1000);
   }
 
   @Test
index 02bdd7138db970990aff306bad1066a1962d9de7..562c6f48b86a9c1921b478da5e86fe61f337fabb 100644 (file)
@@ -145,6 +145,7 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
 
   public static class BaseHttpDownloader {
 
+    private static final String GET = "GET";
     private static final String HTTP_PROXY_USER = "http.proxyUser";
     private static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
 
@@ -167,7 +168,7 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
     }
 
     private void initUserAgent(String sonarVersion) {
-      userAgent = (sonarVersion == null ? "Sonar" : String.format("Sonar %s", sonarVersion));
+      userAgent = (sonarVersion == null ? "SonarQube" : String.format("SonarQube %s", sonarVersion));
       System.setProperty("http.agent", userAgent);
     }
 
@@ -211,25 +212,43 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
     }
 
     public InputSupplier<InputStream> newInputSupplier(URI uri) {
-      return new HttpInputSupplier(uri, userAgent, null, null, TIMEOUT_MILLISECONDS);
+      return new HttpInputSupplier(uri, GET, userAgent, null, null, TIMEOUT_MILLISECONDS);
     }
 
     public InputSupplier<InputStream> newInputSupplier(URI uri, @Nullable Integer readTimeoutMillis) {
+      return newInputSupplier(uri, GET, readTimeoutMillis);
+    }
+
+    public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, @Nullable Integer readTimeoutMillis) {
       if (readTimeoutMillis != null) {
-        return new HttpInputSupplier(uri, userAgent, null, null, readTimeoutMillis);
+        return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, readTimeoutMillis);
       }
-      return new HttpInputSupplier(uri, userAgent, null, null, TIMEOUT_MILLISECONDS);
+      return new HttpInputSupplier(uri, requestMethod, userAgent, null, null, TIMEOUT_MILLISECONDS);
     }
 
     public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password) {
-      return new HttpInputSupplier(uri, userAgent, login, password, TIMEOUT_MILLISECONDS);
+      return newInputSupplier(uri, GET, login, password);
+    }
+
+    /**
+     * @since 5.0
+     */
+    public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password) {
+      return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
     }
 
     public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password, @Nullable Integer readTimeoutMillis) {
+      return newInputSupplier(uri, GET, login, password, readTimeoutMillis);
+    }
+
+    /**
+     * @since 5.0
+     */
+    public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer readTimeoutMillis) {
       if (readTimeoutMillis != null) {
-        return new HttpInputSupplier(uri, userAgent, login, password, readTimeoutMillis);
+        return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, readTimeoutMillis);
       }
-      return new HttpInputSupplier(uri, userAgent, login, password, TIMEOUT_MILLISECONDS);
+      return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, TIMEOUT_MILLISECONDS);
     }
 
     private static class HttpInputSupplier implements InputSupplier<InputStream> {
@@ -238,9 +257,11 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
       private final URI uri;
       private final String userAgent;
       private final int readTimeoutMillis;
+      private final String requestMethod;
 
-      HttpInputSupplier(URI uri, String userAgent, String login, String password, int readTimeoutMillis) {
+      HttpInputSupplier(URI uri, String requestMethod, String userAgent, String login, String password, int readTimeoutMillis) {
         this.uri = uri;
+        this.requestMethod = requestMethod;
         this.userAgent = userAgent;
         this.login = login;
         this.password = password;
@@ -251,6 +272,7 @@ public class HttpDownloader extends UriReader.SchemeProcessor implements BatchCo
         LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
 
         HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
+        connection.setRequestMethod(requestMethod);
         HttpsTrust.INSTANCE.trust(connection);
 
         // allow both GZip and Deflate (ZLib) encodings
index 79d44b9588e0bef9566a518d63717288c3e75b26..5978438e8c61c33bfa747e7fe07b334ecfab88ba 100644 (file)
@@ -149,14 +149,11 @@ public class HttpDownloaderTest {
     thrown.expect(new BaseMatcher<Exception>() {
       @Override
       public boolean matches(Object ex) {
-        // TODO Auto-generated method stub
         return ex instanceof SonarException && ((SonarException) ex).getCause() instanceof SocketTimeoutException;
       }
 
       @Override
       public void describeTo(Description arg0) {
-        // TODO Auto-generated method stub
-
       }
     });
     new HttpDownloader(new Settings(), 100).readString(new URI(baseUrl + "/timeout/"), Charsets.UTF_8);
@@ -201,7 +198,7 @@ public class HttpDownloaderTest {
     props.load(stream);
     stream.close();
 
-    assertThat(props.getProperty("agent")).isEqualTo("Sonar 2.2");
+    assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2");
   }
 
   @Test
@@ -220,7 +217,7 @@ public class HttpDownloaderTest {
   @Test
   public void shouldGetProxySynthesis() throws URISyntaxException {
     ProxySelector proxySelector = mock(ProxySelector.class);
-    when(proxySelector.select(any(URI.class))).thenReturn(Arrays.<Proxy> asList(new FakeProxy()));
+    when(proxySelector.select(any(URI.class))).thenReturn(Arrays.<Proxy>asList(new FakeProxy()));
     assertThat(HttpDownloader.BaseHttpDownloader.getProxySynthesis(new URI("http://an_url"), proxySelector)).isEqualTo("proxy: http://proxy_url:4040");
   }