*/
package org.sonar.batch.local;
+import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import org.sonar.api.BatchComponent;
+import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.platform.Server;
private final LocalMode localMode;
private final Settings settings;
private final Server server;
- private final HttpDownloader httpDownloader;
private final TempDirectories tempDirectories;
- public LocalDatabase(LocalMode localMode, Settings settings, Server server, HttpDownloader httpDownloader, TempDirectories tempDirectories) {
+ public LocalDatabase(LocalMode localMode, Settings settings, Server server, TempDirectories tempDirectories) {
this.localMode = localMode;
this.settings = settings;
this.server = server;
- this.httpDownloader = httpDownloader;
this.tempDirectories = tempDirectories;
}
}
private void downloadDatabase(File toFile) {
+ String login = settings.getString(CoreProperties.LOGIN);
+ String password = settings.getString(CoreProperties.PASSWORD);
+ String resourceKey = settings.getString("sonar.resource");
+ if (null == resourceKey) {
+ throw new SonarException("No resource key was provided using sonar.resource property");
+ }
+
+ URI uri = URI.create(server.getURL() + API_SYNCHRO + "?resource=" + resourceKey);
+
+ HttpDownloader.BaseHttpDownloader downloader = new HttpDownloader.BaseHttpDownloader(settings, null);
+ InputSupplier<InputStream> inputSupplier;
+ if (Strings.isNullOrEmpty(login)) {
+ inputSupplier = downloader.newInputSupplier(uri);
+ } else {
+ inputSupplier = downloader.newInputSupplier(uri, login, password);
+ }
+
try {
- Files.copy(new InputSupplier<InputStream>() {
- public InputStream getInput() {
- return httpDownloader.openStream(URI.create(server.getURL() + API_SYNCHRO));
- }
- }, toFile);
+ Files.copy(inputSupplier, toFile);
} catch (IOException e) {
- throw new SonarException("Unable to download database", e);
+ throw new SonarException("Unable to save local database to file: " + toFile, e);
}
}
package org.sonar.api.utils;
import com.google.common.annotations.VisibleForTesting;
-
import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
+import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
* @since 2.2
*/
public class HttpDownloader extends UriReader.SchemeProcessor implements BatchComponent, ServerComponent {
-
public static final int TIMEOUT_MILLISECONDS = 20 * 1000;
- private static final List<String> PROXY_SETTINGS = ImmutableList.of(
- "http.proxyHost", "http.proxyPort", "http.nonProxyHosts",
- "http.auth.ntlm.domain", "socksProxyHost", "socksProxyPort");
- private String userAgent;
+ private final BaseHttpDownloader downloader;
public HttpDownloader(Server server, Settings settings) {
- this(settings, server.getVersion());
+ downloader = new BaseHttpDownloader(settings, server.getVersion());
}
public HttpDownloader(Settings settings) {
- this(settings, null);
- }
-
- private HttpDownloader(Settings settings, String userAgent) {
- initProxy(settings);
- initUserAgent(userAgent);
- }
-
- private void initProxy(Settings settings) {
- propagateProxySystemProperties(settings);
- if (requiresProxyAuthentication(settings)) {
- registerProxyCredentials(settings);
- }
- }
-
- private void initUserAgent(String sonarVersion) {
- userAgent = (sonarVersion == null ? "Sonar" : String.format("Sonar %s", sonarVersion));
- System.setProperty("http.agent", userAgent);
- }
-
- public String getProxySynthesis(URI uri) {
- return getProxySynthesis(uri, ProxySelector.getDefault());
- }
-
- @VisibleForTesting
- static String getProxySynthesis(URI uri, ProxySelector proxySelector) {
- List<Proxy> proxies = proxySelector.select(uri);
- if (proxies.size() == 1 && proxies.get(0).type().equals(Proxy.Type.DIRECT)) {
- return "no proxy";
- }
-
- List<String> descriptions = Lists.newArrayList();
- for (Proxy proxy : proxies) {
- if (proxy.type() != Proxy.Type.DIRECT) {
- descriptions.add("proxy: " + proxy.address());
- }
- }
-
- return Joiner.on(", ").join(descriptions);
- }
-
- private void registerProxyCredentials(Settings settings) {
- Authenticator.setDefault(new ProxyAuthenticator(settings.getString("http.proxyUser"), settings
- .getString("http.proxyPassword")));
- }
-
- private boolean requiresProxyAuthentication(Settings settings) {
- return settings.getString("http.proxyUser") != null;
- }
-
- private void propagateProxySystemProperties(Settings settings) {
- for (String key : PROXY_SETTINGS) {
- if (settings.getString(key) != null) {
- System.setProperty(key, settings.getString(key));
- }
- }
+ downloader = new BaseHttpDownloader(settings, null);
}
@Override
@Override
byte[] readBytes(URI uri) {
- try {
- return ByteStreams.toByteArray(new HttpInputSupplier(uri));
- } catch (IOException e) {
- throw failToDownload(uri, e);
- }
+ return download(uri);
}
@Override
String readString(URI uri, Charset charset) {
try {
- return CharStreams.toString(CharStreams.newReaderSupplier(new HttpInputSupplier(uri), charset));
+ return CharStreams.toString(CharStreams.newReaderSupplier(downloader.newInputSupplier(uri), charset));
} catch (IOException e) {
throw failToDownload(uri, e);
}
}
+ public String downloadPlainText(URI uri, String encoding) {
+ return readString(uri, Charset.forName(encoding));
+ }
+
public byte[] download(URI uri) {
- return readBytes(uri);
+ try {
+ return ByteStreams.toByteArray(downloader.newInputSupplier(uri));
+ } catch (IOException e) {
+ throw failToDownload(uri, e);
+ }
}
- public String downloadPlainText(URI uri, String encoding) {
- return readString(uri, Charset.forName(encoding));
+ public String getProxySynthesis(URI uri) {
+ return downloader.getProxySynthesis(uri);
}
public InputStream openStream(URI uri) {
try {
- return new HttpInputSupplier(uri).getInput();
- } catch (Exception e) {
- throw new SonarException("Fail to download the file: " + uri + " (" + getProxySynthesis(uri) + ")", e);
+ return downloader.newInputSupplier(uri).getInput();
+ } catch (IOException e) {
+ throw failToDownload(uri, e);
}
}
public void download(URI uri, File toFile) {
try {
- Files.copy(new HttpInputSupplier(uri), toFile);
+ Files.copy(downloader.newInputSupplier(uri), toFile);
} catch (IOException e) {
FileUtils.deleteQuietly(toFile);
throw failToDownload(uri, e);
}
private SonarException failToDownload(URI uri, IOException e) {
- return new SonarException(String.format("Fail to download the file: %s (%s)", uri, getProxySynthesis(uri)), e);
+ throw new SonarException(String.format("Fail to download: %s (%s)", uri, getProxySynthesis(uri)), e);
}
- class HttpInputSupplier implements InputSupplier<InputStream> {
- private final URI uri;
+ public static class BaseHttpDownloader {
+ private static final List<String> PROXY_SETTINGS = ImmutableList.of(
+ "http.proxyHost", "http.proxyPort", "http.nonProxyHosts",
+ "http.auth.ntlm.domain", "socksProxyHost", "socksProxyPort");
- HttpInputSupplier(URI uri) {
- this.uri = uri;
+ private String userAgent;
+
+ public BaseHttpDownloader(Settings settings, String userAgent) {
+ initProxy(settings);
+ initUserAgent(userAgent);
}
- public InputStream getInput() throws IOException {
- LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri) + ")");
+ private void initProxy(Settings settings) {
+ propagateProxySystemProperties(settings);
+ if (requiresProxyAuthentication(settings)) {
+ registerProxyCredentials(settings);
+ }
+ }
- HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
- connection.setConnectTimeout(TIMEOUT_MILLISECONDS);
- connection.setReadTimeout(TIMEOUT_MILLISECONDS);
- connection.setUseCaches(true);
- connection.setInstanceFollowRedirects(true);
- connection.setRequestProperty("User-Agent", userAgent);
- return connection.getInputStream();
+ private void initUserAgent(String sonarVersion) {
+ userAgent = (sonarVersion == null ? "Sonar" : String.format("Sonar %s", sonarVersion));
+ System.setProperty("http.agent", userAgent);
}
- }
-}
-class ProxyAuthenticator extends Authenticator {
- private PasswordAuthentication auth;
+ private String getProxySynthesis(URI uri) {
+ return getProxySynthesis(uri, ProxySelector.getDefault());
+ }
- ProxyAuthenticator(String user, String password) {
- auth = new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
- }
+ @VisibleForTesting
+ static String getProxySynthesis(URI uri, ProxySelector proxySelector) {
+ List<Proxy> proxies = proxySelector.select(uri);
+ if (proxies.size() == 1 && proxies.get(0).type().equals(Proxy.Type.DIRECT)) {
+ return "no proxy";
+ }
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return auth;
+ List<String> descriptions = Lists.newArrayList();
+ for (Proxy proxy : proxies) {
+ if (proxy.type() != Proxy.Type.DIRECT) {
+ descriptions.add("proxy: " + proxy.address());
+ }
+ }
+
+ return Joiner.on(", ").join(descriptions);
+ }
+
+ private void registerProxyCredentials(Settings settings) {
+ Authenticator.setDefault(new ProxyAuthenticator(
+ settings.getString("http.proxyUser"),
+ settings.getString("http.proxyPassword")));
+ }
+
+ private boolean requiresProxyAuthentication(Settings settings) {
+ return settings.getString("http.proxyUser") != null;
+ }
+
+ private void propagateProxySystemProperties(Settings settings) {
+ for (String key : PROXY_SETTINGS) {
+ if (settings.getString(key) != null) {
+ System.setProperty(key, settings.getString(key));
+ }
+ }
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri) {
+ return new HttpInputSupplier(uri, userAgent, null, null);
+ }
+
+ public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password) {
+ return new HttpInputSupplier(uri, userAgent, login, password);
+ }
+
+ private static class HttpInputSupplier implements InputSupplier<InputStream> {
+ private final String login;
+ private final String password;
+ private final URI uri;
+ private final String userAgent;
+
+ HttpInputSupplier(URI uri, String userAgent, String login, String password) {
+ this.uri = uri;
+ this.userAgent = userAgent;
+ this.login = login;
+ this.password = password;
+ }
+
+ public InputStream getInput() throws IOException {
+ LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")");
+
+ HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
+ if (!Strings.isNullOrEmpty(login)) {
+ String encoded = new String(Base64.encodeBase64((login + ":" + password).getBytes()));
+ connection.setRequestProperty("Authorization", "Basic " + encoded);
+ }
+ connection.setConnectTimeout(TIMEOUT_MILLISECONDS);
+ connection.setReadTimeout(TIMEOUT_MILLISECONDS);
+ connection.setUseCaches(true);
+ connection.setInstanceFollowRedirects(true);
+ connection.setRequestProperty("User-Agent", userAgent);
+ return connection.getInputStream();
+ }
+ }
+
+ private static class ProxyAuthenticator extends Authenticator {
+ private final PasswordAuthentication auth;
+
+ ProxyAuthenticator(String user, String password) {
+ auth = new PasswordAuthentication(user, password == null ? new char[0] : password.toCharArray());
+ }
+
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return auth;
+ }
+ }
}
}