]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6888 Support "views" task 558/head
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 1 Oct 2015 15:31:10 +0000 (17:31 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 1 Oct 2015 19:43:29 +0000 (21:43 +0200)
sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/MockHttpServer.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/tasks/TasksMediumTest.java [new file with mode: 0644]

index ebcc795c9e52ebeda20a2324d85a98edd4791ed5..3516932cd50cc626b6115e58607f7f51a68a4d85 100644 (file)
  */
 package org.sonar.batch.bootstrap;
 
+import com.github.kevinsawicki.http.HttpRequest;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.CheckForNull;
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.SonarPlugin;
+import org.sonar.api.platform.Server;
+import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.UriReader;
+import org.sonar.api.utils.log.Loggers;
 import org.sonar.batch.analysis.AnalysisProperties;
 import org.sonar.batch.analysis.DefaultAnalysisMode;
 import org.sonar.batch.cache.GlobalPersistentCacheProvider;
@@ -49,8 +56,12 @@ import org.sonar.core.platform.PluginRepository;
 import org.sonar.core.util.DefaultHttpDownloader;
 import org.sonar.core.util.UuidFactoryImpl;
 
+import static java.lang.String.format;
+
 public class GlobalContainer extends ComponentContainer {
 
+  private static final org.sonar.api.utils.log.Logger LOG = Loggers.get(GlobalContainer.class);
+
   private final Map<String, String> bootstrapProperties;
   private boolean preferCache;
 
@@ -128,7 +139,18 @@ public class GlobalContainer extends ComponentContainer {
   }
 
   public void executeAnalysis(Map<String, String> analysisProperties, Object... components) {
-    AnalysisProperties props = new AnalysisProperties(analysisProperties, this.getComponentByType(GlobalProperties.class).property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
+    GlobalProperties globalProperties = this.getComponentByType(GlobalProperties.class);
+    // SONAR-6888
+    String task = analysisProperties.get(CoreProperties.TASK);
+    if ("views".equals(task)) {
+      triggerViews(this.getComponentByType(ServerClient.class), this.getComponentByType(Server.class));
+      return;
+    }
+    if (StringUtils.isNotBlank(task) && !CoreProperties.SCAN_TASK.equals(task)) {
+      throw MessageException.of("Tasks are no more supported on batch side since SonarQube 5.2");
+    }
+
+    AnalysisProperties props = new AnalysisProperties(analysisProperties, globalProperties.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
     if (isIssuesMode(props)) {
       String projectKey = getProjectKeyWithBranch(props);
       new ProjectSyncContainer(this, projectKey, false).execute();
@@ -136,6 +158,35 @@ public class GlobalContainer extends ComponentContainer {
     new ProjectScanContainer(this, props, components).execute();
   }
 
+  private static void triggerViews(ServerClient serverClient, Server server) {
+    LOG.info("Trigger Views update");
+    URL url;
+    try {
+      url = new URL(serverClient.getURL() + "/api/views/run");
+    } catch (MalformedURLException e) {
+      throw new IllegalArgumentException("Invalid URL", e);
+    }
+    HttpRequest request = HttpRequest.post(url);
+    request.trustAllCerts();
+    request.trustAllHosts();
+    request.header("User-Agent", format("SonarQube %s", server.getVersion()));
+    request.basic(serverClient.getLogin(), serverClient.getPassword());
+    if (!request.ok()) {
+      int responseCode = request.code();
+      if (responseCode == 401) {
+        throw new IllegalStateException(format(serverClient.getMessageWhenNotAuthorized(), CoreProperties.LOGIN, CoreProperties.PASSWORD));
+      }
+      if (responseCode == 409) {
+        throw new IllegalStateException("A full refresh of Views is already queued or running");
+      }
+      if (responseCode == 403) {
+        // SONAR-4397 Details are in response content
+        throw new IllegalStateException(request.body());
+      }
+      throw new IllegalStateException(format("Fail to execute request [code=%s, url=%s]: %s", responseCode, url, request.body()));
+    }
+  }
+
   @CheckForNull
   private static String getProjectKeyWithBranch(AnalysisProperties props) {
     String projectKey = props.property(CoreProperties.PROJECT_KEY_PROPERTY);
index 757e35367178f8f38ec567e61187e296210aaab8..a8c3750bc1b2c32c92d32b7c6bea0a8c5dd251d2 100644 (file)
  */
 package org.sonar.batch.bootstrap;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.io.IOUtils;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.handler.AbstractHandler;
 
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.io.IOException;
-
 import static javax.servlet.http.HttpServletResponse.SC_OK;
 import static org.apache.commons.io.IOUtils.write;
 
@@ -40,7 +40,7 @@ public class MockHttpServer {
   private String requestBody;
   private String mockResponseData;
   private int mockResponseStatus = SC_OK;
-  private int numRequests = 0;
+  private List<String> targets = new ArrayList<>();
 
   public void start() throws Exception {
     server = new Server(0);
@@ -49,7 +49,7 @@ public class MockHttpServer {
   }
 
   public int getNumberRequests() {
-    return numRequests;
+    return targets.size();
   }
 
   /**
@@ -61,7 +61,7 @@ public class MockHttpServer {
     Handler handler = new AbstractHandler() {
 
       public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
-        numRequests++;
+        targets.add(target);
         setResponseBody(getMockResponseData());
         setRequestBody(IOUtils.toString(baseRequest.getInputStream()));
         response.setStatus(mockResponseStatus);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tasks/TasksMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/tasks/TasksMediumTest.java
new file mode 100644 (file)
index 0000000..a4acf3a
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * 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.batch.mediumtest.tasks;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.batch.bootstrap.MockHttpServer;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TasksMediumTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Rule
+  public LogTester logTester = new LogTester();
+
+  public BatchMediumTester tester = BatchMediumTester.builder()
+    .build();
+
+  private MockHttpServer server = null;
+
+  @After
+  public void stopServer() {
+    if (server != null) {
+      server.stop();
+    }
+  }
+
+  @After
+  public void stop() {
+    tester.stop();
+  }
+
+  @Test
+  public void triggerViews() throws Exception {
+    startServer(200, "OK");
+    tester = BatchMediumTester.builder()
+      .bootstrapProperties(ImmutableMap.of("sonar.host.url", "http://localhost:" + server.getPort()))
+      .build();
+    tester.start();
+    tester.newTask()
+      .properties(ImmutableMap.<String, String>builder()
+        .put("sonar.task", "views").build())
+      .start();
+
+    assertThat(logTester.logs()).contains("Trigger views update");
+  }
+
+  @Test(expected = MessageException.class)
+  public void unsupportedTask() throws Exception {
+    tester = BatchMediumTester.builder()
+      .build();
+    tester.start();
+    tester.newTask()
+      .properties(ImmutableMap.<String, String>builder()
+        .put("sonar.task", "foo").build())
+      .start();
+  }
+
+  private void startServer(Integer responseStatus, String responseData) throws Exception {
+    server = new MockHttpServer();
+    server.start();
+
+    if (responseStatus != null) {
+      server.setMockResponseStatus(responseStatus);
+    }
+    if (responseData != null) {
+      server.setMockResponseData(responseData);
+    }
+  }
+
+}