aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-ws-client
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2011-07-15 18:10:07 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2011-07-15 18:10:14 +0200
commitd2029a491b72ae097955cb9db474654eb60aa849 (patch)
treef91563892c016d4b9ca8fdad43860f701e84fd4a /sonar-ws-client
parentf4d600e1d0b5da539f907da89878accf187815d9 (diff)
downloadsonarqube-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')
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/Connector.java2
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient3Connector.java49
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/connectors/HttpClient4Connector.java16
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/AbstractQuery.java30
-rw-r--r--sonar-ws-client/src/main/java/org/sonar/wsclient/services/Query.java2
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> {