diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2011-07-15 18:10:07 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2011-07-15 18:10:14 +0200 |
commit | d2029a491b72ae097955cb9db474654eb60aa849 (patch) | |
tree | f91563892c016d4b9ca8fdad43860f701e84fd4a /sonar-ws-client | |
parent | f4d600e1d0b5da539f907da89878accf187815d9 (diff) | |
download | sonarqube-d2029a491b72ae097955cb9db474654eb60aa849.tar.gz sonarqube-d2029a491b72ae097955cb9db474654eb60aa849.zip |
SONAR-2002 The Sonar WS API automatically kills an HTTP connection after 30s. This timeout parameter should be configurable
Diffstat (limited to 'sonar-ws-client')
5 files changed, 53 insertions, 46 deletions
diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java index 105bdbafbdc..cf874703859 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java @@ -29,8 +29,6 @@ import org.sonar.wsclient.services.UpdateQuery; */ public abstract class Connector { - protected static final int TIMEOUT_MS = 30000; - /** * @return JSON response or null if 404 NOT FOUND error * @throws ConnectionException if connection error or HTTP status not in (200, 404) diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java index 25545be4446..966095110bc 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java @@ -19,34 +19,14 @@ */ package org.sonar.wsclient.connectors; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; - -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.sonar.wsclient.Host; -import org.sonar.wsclient.services.AbstractQuery; -import org.sonar.wsclient.services.CreateQuery; -import org.sonar.wsclient.services.DeleteQuery; -import org.sonar.wsclient.services.Query; -import org.sonar.wsclient.services.UpdateQuery; +import org.sonar.wsclient.services.*; + +import java.io.*; /** * @since 2.1 @@ -71,8 +51,8 @@ public class HttpClient3Connector extends Connector { private void createClient() { final HttpConnectionManagerParams params = new HttpConnectionManagerParams(); - params.setConnectionTimeout(TIMEOUT_MS); - params.setSoTimeout(TIMEOUT_MS); + params.setConnectionTimeout(AbstractQuery.DEFAULT_TIMEOUT_MILLISECONDS); + params.setSoTimeout(AbstractQuery.DEFAULT_TIMEOUT_MILLISECONDS); params.setDefaultMaxConnectionsPerHost(MAX_HOST_CONNECTIONS); params.setMaxTotalConnections(MAX_TOTAL_CONNECTIONS); final MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); @@ -109,6 +89,7 @@ public class HttpClient3Connector extends Connector { String json = null; try { httpClient.executeMethod(method); + if (method.getStatusCode() == HttpStatus.SC_OK) { json = getResponseBodyAsString(method); @@ -132,26 +113,26 @@ public class HttpClient3Connector extends Connector { private HttpMethodBase newGetRequest(Query<?> query) { HttpMethodBase method = new GetMethod(server.getHost() + query.getUrl()); - setJsonHeader(method); + initRequest(method, query); return method; } private HttpMethodBase newDeleteRequest(DeleteQuery<?> query) { HttpMethodBase method = new DeleteMethod(server.getHost() + query.getUrl()); - setJsonHeader(method); + initRequest(method, query); return method; } private HttpMethodBase newPostRequest(CreateQuery<?> query) { PostMethod method = new PostMethod(server.getHost() + query.getUrl()); - setJsonHeader(method); + initRequest(method, query); setRequestEntity(method, query); return method; } private HttpMethodBase newPutRequest(UpdateQuery<?> query) { PutMethod method = new PutMethod(server.getHost() + query.getUrl()); - setJsonHeader(method); + initRequest(method, query); setRequestEntity(method, query); return method; } @@ -166,8 +147,9 @@ public class HttpClient3Connector extends Connector { } } - private void setJsonHeader(HttpMethodBase request) { + private void initRequest(HttpMethodBase request, AbstractQuery query) { request.setRequestHeader("Accept", "application/json"); + request.getParams().setSoTimeout(query.getTimeoutMilliseconds()); } private String getResponseBodyAsString(HttpMethod method) { @@ -190,9 +172,8 @@ public class HttpClient3Connector extends Connector { if (reader != null) { try { reader.close(); - } catch (Exception e) { - // TODO + throw new RuntimeException("Fail to close HTTP stream", e); } } } diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java index 382f5bd3614..471323b4fed 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java @@ -45,6 +45,7 @@ import org.apache.http.client.protocol.ClientContext; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; @@ -115,8 +116,8 @@ public class HttpClient4Connector extends Connector { private DefaultHttpClient createClient() { DefaultHttpClient client = new DefaultHttpClient(); HttpParams params = client.getParams(); - HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_MS); - HttpConnectionParams.setSoTimeout(params, TIMEOUT_MS); + HttpConnectionParams.setConnectionTimeout(params, AbstractQuery.DEFAULT_TIMEOUT_MILLISECONDS); + HttpConnectionParams.setSoTimeout(params, AbstractQuery.DEFAULT_TIMEOUT_MILLISECONDS); if (server.getUsername() != null) { client.getCredentialsProvider() .setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(server.getUsername(), server.getPassword())); @@ -141,26 +142,26 @@ public class HttpClient4Connector extends Connector { private HttpGet newGetMethod(Query<?> query) { HttpGet get = new HttpGet(server.getHost() + query.getUrl()); - setJsonHeader(get); + initRequest(get, query); return get; } private HttpDelete newDeleteMethod(DeleteQuery<?> query) { HttpDelete delete = new HttpDelete(server.getHost() + query.getUrl()); - setJsonHeader(delete); + initRequest(delete, query); return delete; } private HttpPost newPostMethod(CreateQuery<?> query) { HttpPost post = new HttpPost(server.getHost() + query.getUrl()); - setJsonHeader(post); + initRequest(post, query); setRequestEntity(post, query); return post; } private HttpPut newPutMethod(UpdateQuery<?> query) { HttpPut put = new HttpPut(server.getHost() + query.getUrl()); - setJsonHeader(put); + initRequest(put, query); setRequestEntity(put, query); return put; } @@ -175,8 +176,9 @@ public class HttpClient4Connector extends Connector { } } - private void setJsonHeader(HttpRequestBase request) { + private void initRequest(HttpRequestBase request, AbstractQuery query) { request.setHeader("Accept", "application/json"); + request.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, query.getTimeoutMilliseconds()); } static final class PreemptiveAuth implements HttpRequestInterceptor { diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java index 288dfba7ee2..141dd14fab3 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java @@ -27,11 +27,20 @@ import java.util.Date; public abstract class AbstractQuery<MODEL extends Model> { /** + * Default timeout for waiting data, in milliseconds. + * + * @since 2.10 + */ + public static final int DEFAULT_TIMEOUT_MILLISECONDS = 30 * 1000; + + private int timeoutMilliseconds = DEFAULT_TIMEOUT_MILLISECONDS; + + /** * Must start with a slash, for example: /api/metrics * <p> * IMPORTANT: In implementations of this method we must use helper methods to construct URL. * </p> - * + * * @see #encode(String) * @see #appendUrlParameter(StringBuilder, String, Object) * @see #appendUrlParameter(StringBuilder, String, Object[]) @@ -47,6 +56,25 @@ public abstract class AbstractQuery<MODEL extends Model> { } /** + * Get the timeout for waiting data, in milliseconds. A value of zero is interpreted as an infinite timeout. + * + * @since 2.10 + */ + public final int getTimeoutMilliseconds() { + return timeoutMilliseconds; + } + + /** + * Set the timeout for waiting data, in milliseconds. Avalue of zero is interpreted as an infinite timeout. + * + * @since 2.10 + */ + public final AbstractQuery<MODEL> setTimeoutMilliseconds(int i) { + this.timeoutMilliseconds = (i < 0 ? 0 : i); + return this; + } + + /** * Encodes single parameter value. */ protected static String encode(String value) { diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java index 9189b4c283b..f4203367dce 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java @@ -20,8 +20,6 @@ package org.sonar.wsclient.services; /** - * GET HTTP request - * * @since 2.1 */ public abstract class Query<MODEL extends Model> extends AbstractQuery<MODEL> { |