import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.HttpDownloader;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-
/**
* Replace the deprecated org.sonar.batch.ServerMetadata
* TODO extends Server when removing the deprecated org.sonar.batch.ServerMetadata
*/
public class ServerClient implements BatchComponent {
+ private static final int WS_TIMEOUT_DEFAULT = 60 * 1000;
+ static final String SONAR_WS_TIMEOUT_PROP = "sonar.ws.timeout";
private BootstrapProperties props;
private HttpDownloader.BaseHttpDownloader downloader;
Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /");
String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash);
+ int readTimeout;
+ if (timeoutMillis != null) {
+ readTimeout = timeoutMillis.intValue();
+ } else {
+ readTimeout = props.properties().containsKey(SONAR_WS_TIMEOUT_PROP) ? Integer.parseInt(props.property(SONAR_WS_TIMEOUT_PROP)) * 1000 : WS_TIMEOUT_DEFAULT;
+ }
+
URI uri = URI.create(getURL() + path);
try {
InputSupplier<InputStream> inputSupplier;
if (Strings.isNullOrEmpty(getLogin())) {
- inputSupplier = downloader.newInputSupplier(uri, timeoutMillis);
+ inputSupplier = downloader.newInputSupplier(uri, readTimeout);
} else {
- inputSupplier = downloader.newInputSupplier(uri, getLogin(), getPassword(), timeoutMillis);
+ inputSupplier = downloader.newInputSupplier(uri, getLogin(), getPassword(), readTimeout);
}
return inputSupplier;
} catch (Exception e) {
package org.sonar.batch.bootstrap;
import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
+import java.io.File;
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+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 org.junit.After;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.io.File;
-import java.io.IOException;
-
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.apache.commons.io.IOUtils.write;
import static org.fest.assertions.Assertions.assertThat;
assertThat(newServerClient().request("/foo")).isEqualTo("this is the content");
}
+ @Test
+ public void should_timeout() throws Exception {
+ server = new MockHttpServer();
+ server.start();
+ server.setMockResponseData("this is the content");
+ server.setDelay(3 * 1000);
+
+ when(bootstrapProps.properties()).thenReturn(ImmutableMap.of(ServerClient.SONAR_WS_TIMEOUT_PROP, "1"));
+ when(bootstrapProps.property(ServerClient.SONAR_WS_TIMEOUT_PROP)).thenReturn("1");
+
+ try {
+ newServerClient().request("/<foo>");
+ Assert.fail("Should timeout");
+ } catch (Exception e) {
+ assertThat(e.getCause()).isExactlyInstanceOf(SocketTimeoutException.class);
+ }
+ }
+
@Test
public void should_escape_html_from_url() throws Exception {
server = new MockHttpServer();
server.start();
server.setMockResponseData("this is the content");
- assertThat(newServerClient().request("/<foo>")).isEqualTo("this is the content");
+ assertThat(newServerClient().request("/foo")).isEqualTo("this is the content");
}
@Test
private String requestBody;
private String mockResponseData;
private int mockResponseStatus = SC_OK;
+ private int delay = 0;
public void start() throws Exception {
server = new Server(0);
setRequestBody(IOUtils.toString(baseRequest.getInputStream()));
response.setStatus(mockResponseStatus);
response.setContentType("text/xml;charset=utf-8");
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
write(getResponseBody(), response.getOutputStream());
baseRequest.setHandled(true);
}
this.mockResponseStatus = status;
}
+ public void setDelay(int delay) {
+ this.delay = delay;
+ }
+
public String getMockResponseData() {
return mockResponseData;
}