aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-runner-api/src/main/java
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2015-07-20 13:30:07 +0200
committerDuarte Meneses <duarte.meneses@sonarsource.com>2015-07-24 14:32:25 +0200
commit914a384ad19302f71c356dedbf3207eaed00ca67 (patch)
tree58bcbef3605ace99effd46b6ef6a2c347f559b63 /sonar-runner-api/src/main/java
parenta2b8cbaa2d582a17b9e07b02a6d7b84e68c08307 (diff)
downloadsonar-scanner-cli-914a384ad19302f71c356dedbf3207eaed00ca67.tar.gz
sonar-scanner-cli-914a384ad19302f71c356dedbf3207eaed00ca67.zip
SONARUNNER-132 Add support for offline mode
Diffstat (limited to 'sonar-runner-api/src/main/java')
-rw-r--r--sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java5
-rw-r--r--sonar-runner-api/src/main/java/org/sonar/runner/impl/ServerConnection.java101
2 files changed, 65 insertions, 41 deletions
diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java
index 5c2a590..c56b72d 100644
--- a/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java
+++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/IsolatedLauncherFactory.java
@@ -50,11 +50,6 @@ public class IsolatedLauncherFactory {
private PersistentCache getCache(Properties props) {
PersistentCacheBuilder builder = new PersistentCacheBuilder(logger);
-
- if (!"true".equals(props.getProperty("sonar.enableHttpCache"))) {
- builder.forceUpdate(true);
- }
-
return builder.build();
}
diff --git a/sonar-runner-api/src/main/java/org/sonar/runner/impl/ServerConnection.java b/sonar-runner-api/src/main/java/org/sonar/runner/impl/ServerConnection.java
index 7abd093..da9a86c 100644
--- a/sonar-runner-api/src/main/java/org/sonar/runner/impl/ServerConnection.java
+++ b/sonar-runner-api/src/main/java/org/sonar/runner/impl/ServerConnection.java
@@ -19,7 +19,10 @@
*/
package org.sonar.runner.impl;
+import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
+
import com.github.kevinsawicki.http.HttpRequest;
+
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
@@ -27,9 +30,9 @@ import java.net.URL;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.Properties;
-import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
import org.apache.commons.io.FileUtils;
import org.sonar.home.cache.Logger;
import org.sonar.home.cache.PersistentCache;
@@ -38,7 +41,7 @@ class ServerConnection {
private static final String SONAR_SERVER_CAN_NOT_BE_REACHED = "Sonar server ''{0}'' can not be reached";
private static final String STATUS_RETURNED_BY_URL_IS_INVALID = "Status returned by url : ''{0}'' is invalid : {1}";
- static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
+ static final int CONNECT_TIMEOUT_MILLISECONDS = 5000;
static final int READ_TIMEOUT_MILLISECONDS = 60000;
private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
@@ -46,15 +49,15 @@ class ServerConnection {
private final String userAgent;
private final PersistentCache wsCache;
- private final boolean isModePreview;
+ private final boolean isCacheEnable;
private final Logger logger;
- private ServerConnection(String serverUrl, String app, String appVersion, boolean preview, PersistentCache cache, Logger logger) {
+ private ServerConnection(String serverUrl, String app, String appVersion, boolean isCacheEnable, PersistentCache cache, Logger logger) {
this.logger = logger;
this.serverUrl = removeEndSlash(serverUrl);
this.userAgent = app + "/" + appVersion;
this.wsCache = cache;
- this.isModePreview = preview;
+ this.isCacheEnable = isCacheEnable;
}
private static String removeEndSlash(String url) {
@@ -69,36 +72,42 @@ class ServerConnection {
String app = properties.getProperty(InternalProperties.RUNNER_APP);
String appVersion = properties.getProperty(InternalProperties.RUNNER_APP_VERSION);
String analysisMode = properties.getProperty("sonar.analysis.mode");
- boolean preview = "preview".equalsIgnoreCase(analysisMode);
+ String enableOffline = properties.getProperty("sonar.enableOffline");
+ boolean enableCache = "preview".equalsIgnoreCase(analysisMode) && "true".equals(enableOffline);
- return new ServerConnection(serverUrl, app, appVersion, preview, cache, logger);
+ return new ServerConnection(serverUrl, app, appVersion, enableCache, cache, logger);
}
- private class StringDownloader implements Callable<String> {
- private String url;
-
- StringDownloader(String url) {
- this.url = url;
- }
+ /**
+ *
+ * @throws HttpRequestException If there is an underlying IOException related to the connection
+ * @throws IOException If the HTTP response code is != 200
+ */
+ private String downloadString(String url, boolean saveCache) throws HttpRequestException, IOException {
+ HttpRequest httpRequest = null;
+ try {
+ httpRequest = newHttpRequest(new URL(url));
+ String charset = getCharsetFromContentType(httpRequest.contentType());
+ if (charset == null || "".equals(charset)) {
+ charset = "UTF-8";
+ }
+ if (!httpRequest.ok()) {
+ throw new IOException(MessageFormat.format(STATUS_RETURNED_BY_URL_IS_INVALID, url, httpRequest.code()));
+ }
- @Override
- public String call() throws Exception {
- HttpRequest httpRequest = null;
- try {
- httpRequest = newHttpRequest(new URL(url));
- String charset = getCharsetFromContentType(httpRequest.contentType());
- if (charset == null || "".equals(charset)) {
- charset = "UTF-8";
- }
- if (!httpRequest.ok()) {
- throw new IOException(MessageFormat.format(STATUS_RETURNED_BY_URL_IS_INVALID, url, httpRequest.code()));
- }
- return httpRequest.body(charset);
- } finally {
- if (httpRequest != null) {
- httpRequest.disconnect();
+ byte[] body = httpRequest.bytes();
+ if (saveCache) {
+ try {
+ wsCache.put(url, body);
+ } catch (IOException e) {
+ logger.warn("Failed to cache WS call: " + e.getMessage());
}
}
+ return new String(body, charset);
+ } finally {
+ if (httpRequest != null) {
+ httpRequest.disconnect();
+ }
}
}
@@ -121,22 +130,42 @@ class ServerConnection {
}
}
- String downloadStringCache(String path) throws Exception {
+ /**
+ * Tries to fetch from server and falls back to cache. If both attempts fail, it throws the exception
+ * linked to the server connection failure.
+ */
+ String downloadStringCache(String path) throws IOException {
String fullUrl = serverUrl + path;
try {
- if (isModePreview) {
- return wsCache.getString(serverUrl, new StringDownloader(fullUrl));
- } else {
- return new StringDownloader(fullUrl).call();
- }
+ return downloadString(fullUrl, isCacheEnable);
} catch (HttpRequest.HttpRequestException e) {
if (e.getCause() instanceof ConnectException || e.getCause() instanceof UnknownHostException) {
- logger.error(MessageFormat.format(SONAR_SERVER_CAN_NOT_BE_REACHED, serverUrl));
+ if (isCacheEnable) {
+ return fallbackToCache(fullUrl, e);
+ }
}
+
+ logger.error(MessageFormat.format(SONAR_SERVER_CAN_NOT_BE_REACHED, serverUrl));
throw e;
}
}
+ private String fallbackToCache(String fullUrl, HttpRequest.HttpRequestException originalException) {
+ logger.info(MessageFormat.format(SONAR_SERVER_CAN_NOT_BE_REACHED + ", trying cache", serverUrl));
+
+ try {
+ String cached = wsCache.getString(fullUrl, null);
+ if (cached != null) {
+ return cached;
+ }
+ logger.error(MessageFormat.format(SONAR_SERVER_CAN_NOT_BE_REACHED + " and had a cache miss", serverUrl));
+ throw originalException;
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to access cache", e);
+ }
+
+ }
+
private HttpRequest newHttpRequest(URL url) {
HttpRequest request = HttpRequest.get(url);
request.trustAllCerts().trustAllHosts();