Author: rfeng
Date: Sun Sep 30 15:12:41 2012
New Revision: 1392033
URL: http://svn.apache.org/viewvc?rev=1392033&view=rev
Log:
Enhance the http client configuration to make it customizable
Added:
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/org.apache.tuscany.sca.host.http.client.HttpClientFactory
Modified:
tuscany/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JsonRpcInvoker.java
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
tuscany/sca-java-2.x/trunk/modules/core-spi/META-INF/MANIFEST.MF
tuscany/sca-java-2.x/trunk/modules/host-http/META-INF/MANIFEST.MF
tuscany/sca-java-2.x/trunk/modules/host-http/src/main/java/org/apache/tuscany/sca/host/http/client/HttpClientFactory.java
Modified:
tuscany/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JsonRpcInvoker.java
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JsonRpcInvoker.java?rev=1392033&r1=1392032&r2=1392033&view=diff
==============================================================================
---
tuscany/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JsonRpcInvoker.java
(original)
+++
tuscany/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JsonRpcInvoker.java
Sun Sep 30 15:12:41 2012
@@ -122,52 +122,55 @@ public class JsonRpcInvoker implements I
response = httpClient.execute(post);
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- //success
+ try {
+ if (response.getStatusLine().getStatusCode() ==
HttpStatus.SC_OK) {
+ //success
+
+ entity = response.getEntity();
+ String entityResponse = EntityUtils.toString(entity);
+ // entity.consumeContent();
+ if (!db.equals(JSONDataBinding.NAME)) {
+ ObjectNode jsonResponse =
(ObjectNode)JacksonHelper.MAPPER.readTree(entityResponse);
- entity = response.getEntity();
- String entityResponse = EntityUtils.toString(entity);
- entity.consumeContent();
- if (!db.equals(JSONDataBinding.NAME)) {
- ObjectNode jsonResponse =
(ObjectNode)JacksonHelper.MAPPER.readTree(entityResponse);
+ if (jsonResponse.has("error") &&
jsonResponse.get("error") != NullNode.instance) {
+ processException(jsonResponse);
+ }
+ DataType<List<DataType>> outputType =
operation.getOutputType();
+ DataType returnType =
+ (outputType != null &&
!outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0)
+ : null;
+
+ if (returnType == null) {
+ msg.setBody(null);
+ return msg;
+ }
- if (jsonResponse.has("error") && jsonResponse.get("error")
!= NullNode.instance) {
- processException(jsonResponse);
- }
- DataType<List<DataType>> outputType =
operation.getOutputType();
- DataType returnType =
- (outputType != null &&
!outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0)
- : null;
-
- if (returnType == null) {
- msg.setBody(null);
- return msg;
- }
+ //check requestId
+ if
(!requestId.equalsIgnoreCase(jsonResponse.get("id").getTextValue())) {
+ throw new ServiceRuntimeException("Invalid
response id:" + requestId);
+ }
- //check requestId
- if
(!requestId.equalsIgnoreCase(jsonResponse.get("id").getTextValue())) {
- throw new ServiceRuntimeException("Invalid response
id:" + requestId);
- }
+ JsonNode rawResult = jsonResponse.get("result");
- JsonNode rawResult = jsonResponse.get("result");
+ Class<?> returnClass = returnType.getPhysical();
+ Type genericReturnType = returnType.getGenericType();
- Class<?> returnClass = returnType.getPhysical();
- Type genericReturnType = returnType.getGenericType();
+ ObjectMapper mapper = createObjectMapper(returnClass);
+ String json = mapper.writeValueAsString(rawResult);
- ObjectMapper mapper = createObjectMapper(returnClass);
- String json = mapper.writeValueAsString(rawResult);
+ Object body = mapper.readValue(json,
TypeFactory.type(genericReturnType));
- Object body = mapper.readValue(json,
TypeFactory.type(genericReturnType));
+ msg.setBody(body);
+ } else {
+ msg.setBody(entityResponse);
+ }
- msg.setBody(body);
} else {
- msg.setBody(entityResponse);
+ throw new ServiceRuntimeException("Abnormal HTTP response:
" + response.getStatusLine().toString());
}
-
- } else {
+ } finally {
// Consume the content so the connection can be released
- response.getEntity().consumeContent();
- throw new ServiceRuntimeException("Abnormal HTTP response: " +
response.getStatusLine().toString());
+ EntityUtils.consumeQuietly(response.getEntity());
}
} catch (RuntimeException e) {
throw e;
Modified:
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java?rev=1392033&r1=1392032&r2=1392033&view=diff
==============================================================================
---
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
(original)
+++
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/main/java/org/apache/tuscany/sca/binding/rest/provider/RESTBindingInvoker.java
Sun Sep 30 15:12:41 2012
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.binding.rest.provider;
+import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URI;
@@ -38,7 +39,6 @@ import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
-import javax.ws.rs.HeaderParam;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.OPTIONS;
@@ -55,6 +55,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import org.apache.http.client.HttpClient;
+import org.apache.http.entity.StringEntity;
import org.apache.tuscany.sca.assembly.EndpointReference;
import org.apache.tuscany.sca.assembly.WireFormat;
import org.apache.tuscany.sca.binding.rest.RESTBinding;
@@ -71,6 +72,8 @@ import org.apache.wink.client.ApacheHttp
import org.apache.wink.client.ClientConfig;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
+import org.apache.wink.client.ClientWebException;
+import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.handlers.BasicAuthSecurityHandler;
/**
@@ -85,7 +88,11 @@ public class RESTBindingInvoker implemen
private String httpMethod;
private Class<?> responseType;
- public RESTBindingInvoker(ExtensionPointRegistry registry,
EndpointReference endpointReference, RESTBinding binding, Operation operation,
HttpClient httpClient) {
+ public RESTBindingInvoker(ExtensionPointRegistry registry,
+ EndpointReference endpointReference,
+ RESTBinding binding,
+ Operation operation,
+ HttpClient httpClient) {
super();
this.registry = registry;
this.endpointReference = endpointReference;
@@ -134,10 +141,10 @@ public class RESTBindingInvoker implemen
}
});
-
+
config.readTimeout(binding.getReadTimeout());
RestClient client = new RestClient(config);
-
+
// Default to GET for RPC
httpMethod = HttpMethod.GET;
@@ -224,10 +231,10 @@ public class RESTBindingInvoker implemen
cookieParams.put(cookieParam.value(), args[i]);
}
- if(getAnnotation(annotations, Context.class) != null) {
+ if (getAnnotation(annotations, Context.class) != null) {
isEntity = false;
}
-
+
if (isEntity) {
entity = args[i];
}
@@ -271,8 +278,22 @@ public class RESTBindingInvoker implemen
}
}
- Object result = resource.invoke(httpMethod, responseType, entity);
- msg.setBody(result);
+ try {
+ Object result = resource.invoke(httpMethod, responseType, entity);
+ msg.setBody(result);
+ } catch (ClientWebException e) {
+ ClientResponse clientResponse = e.getResponse();
+ // Consume the entity
+ String error = clientResponse.getEntity(String.class);
+ StringEntity stringEntity;
+ try {
+ stringEntity = error == null ? null : new StringEntity(error);
+ clientResponse.setEntity(stringEntity);
+ } catch (UnsupportedEncodingException e1) {
+ // Ignore
+ }
+ throw e;
+ }
return msg;
}
Added:
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/org.apache.tuscany.sca.host.http.client.HttpClientFactory
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/org.apache.tuscany.sca.host.http.client.HttpClientFactory?rev=1392033&view=auto
==============================================================================
---
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/org.apache.tuscany.sca.host.http.client.HttpClientFactory
(added)
+++
tuscany/sca-java-2.x/trunk/modules/binding-rest-runtime/src/test/resources/META-INF/services/org.apache.tuscany.sca.host.http.client.HttpClientFactory
Sun Sep 30 15:12:41 2012
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org.apache.tuscany.sca.host.http.client.HttpClientFactory;soTimeout =
30000,connectionTimeout = 60000,staleCheckingEnabled = false,timeToLive =
30,maxPerRoute = 16,maxTotal = 256,sslHostVerificationEnabled = false
Modified: tuscany/sca-java-2.x/trunk/modules/core-spi/META-INF/MANIFEST.MF
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/core-spi/META-INF/MANIFEST.MF?rev=1392033&r1=1392032&r2=1392033&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/core-spi/META-INF/MANIFEST.MF (original)
+++ tuscany/sca-java-2.x/trunk/modules/core-spi/META-INF/MANIFEST.MF Sun Sep 30
15:12:41 2012
@@ -46,7 +46,8 @@ Import-Package: org.apache.tuscany.sca.a
org.apache.tuscany.sca.provider;version="2.0.0",
org.apache.tuscany.sca.runtime;version="2.0.0",
org.apache.tuscany.sca.work;version="2.0.0",
- org.oasisopen.sca;version="2.0.0"
+ org.oasisopen.sca;version="2.0.0",
+ org.oasisopen.sca.annotation;version="2.0.0"
Bundle-SymbolicName: org.apache.tuscany.sca.core.spi
Bundle-DocURL: http://www.apache.org/
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
Modified: tuscany/sca-java-2.x/trunk/modules/host-http/META-INF/MANIFEST.MF
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/host-http/META-INF/MANIFEST.MF?rev=1392033&r1=1392032&r2=1392033&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/host-http/META-INF/MANIFEST.MF (original)
+++ tuscany/sca-java-2.x/trunk/modules/host-http/META-INF/MANIFEST.MF Sun Sep
30 15:12:41 2012
@@ -22,6 +22,7 @@ Import-Package: javax.servlet,
org.apache.http.conn.params;resolution:=optional,
org.apache.http.conn.scheme;resolution:=optional,
org.apache.http.conn.ssl;resolution:=optional,
+ org.apache.http.impl;resolution:=optional,
org.apache.http.impl.client;resolution:=optional,
org.apache.http.impl.conn;resolution:=optional,
org.apache.http.impl.conn.tsccm;resolution:=optional,
Modified:
tuscany/sca-java-2.x/trunk/modules/host-http/src/main/java/org/apache/tuscany/sca/host/http/client/HttpClientFactory.java
URL:
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/host-http/src/main/java/org/apache/tuscany/sca/host/http/client/HttpClientFactory.java?rev=1392033&r1=1392032&r2=1392033&view=diff
==============================================================================
---
tuscany/sca-java-2.x/trunk/modules/host-http/src/main/java/org/apache/tuscany/sca/host/http/client/HttpClientFactory.java
(original)
+++
tuscany/sca-java-2.x/trunk/modules/host-http/src/main/java/org/apache/tuscany/sca/host/http/client/HttpClientFactory.java
Sun Sep 30 15:12:41 2012
@@ -19,10 +19,17 @@
package org.apache.tuscany.sca.host.http.client;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLInitializationException;
import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.NoConnectionReuseStrategy;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.SchemeRegistryFactory;
@@ -30,6 +37,7 @@ import org.apache.http.params.BasicHttpP
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.HttpContext;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.LifeCycleListener;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
@@ -38,6 +46,13 @@ import org.apache.tuscany.sca.core.Utili
* @version $Rev$ $Date$
*/
public class HttpClientFactory implements LifeCycleListener {
+ private int soTimeout = 30000;
+ private int connectionTimeout = 60000;
+ private boolean staleCheckingEnabled = false;
+ private long timeToLive = 60; // seconds
+ private int maxPerRoute = 256;
+ private int maxTotal = 1024;
+ private boolean sslHostVerificationEnabled = false;
private HttpClient httpClient;
@@ -46,12 +61,50 @@ public class HttpClientFactory implement
return utilities.getUtility(HttpClientFactory.class);
}
+ public HttpClientFactory() {
+
+ }
+
+ public HttpClientFactory(ExtensionPointRegistry registry, Map<String,
String> attributes) {
+ if (attributes != null) {
+ String val = attributes.get("soTimeout");
+ if (val != null) {
+ this.soTimeout = Integer.parseInt(val);
+ }
+ val = attributes.get("connectionTimeout");
+ if (val != null) {
+ this.connectionTimeout = Integer.parseInt(val);
+ }
+ val = attributes.get("staleCheckingEnabled");
+ if (val != null) {
+ this.staleCheckingEnabled = Boolean.parseBoolean(val);
+ }
+ val = attributes.get("timeToLive");
+ if (val != null) {
+ this.timeToLive = Long.parseLong(val);
+ }
+ val = attributes.get("sslHostVerificationEnabled");
+ if (val != null) {
+ this.sslHostVerificationEnabled = Boolean.parseBoolean(val);
+ }
+ val = attributes.get("maxTotal");
+ if (val != null) {
+ this.maxTotal = Integer.parseInt(val);
+ }
+ val = attributes.get("maxPerRoute");
+ if (val != null) {
+ this.maxPerRoute = Integer.parseInt(val);
+ }
+ }
+ }
+
public HttpClient createHttpClient() {
HttpParams defaultParameters = new BasicHttpParams();
HttpProtocolParams.setContentCharset(defaultParameters, "UTF-8");
- HttpConnectionParams.setConnectionTimeout(defaultParameters, 60000);
- HttpConnectionParams.setSoTimeout(defaultParameters, 60000);
+ HttpConnectionParams.setConnectionTimeout(defaultParameters,
connectionTimeout);
+ HttpConnectionParams.setSoTimeout(defaultParameters, soTimeout);
+ HttpConnectionParams.setStaleCheckingEnabled(defaultParameters,
staleCheckingEnabled);
// See https://issues.apache.org/jira/browse/HTTPCLIENT-1138
SchemeRegistry supportedSchemes = null;
@@ -62,17 +115,24 @@ public class HttpClientFactory implement
supportedSchemes = SchemeRegistryFactory.createDefault();
}
- // FIXME: By pass host name verification
- SSLSocketFactory socketFactory =
(SSLSocketFactory)supportedSchemes.getScheme("https").getSchemeSocketFactory();
-
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ if (!sslHostVerificationEnabled) {
+ // FIXME: By pass host name verification
+ SSLSocketFactory socketFactory =
+
(SSLSocketFactory)supportedSchemes.getScheme("https").getSchemeSocketFactory();
+
socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ }
PoolingClientConnectionManager connectionManager =
- new PoolingClientConnectionManager(supportedSchemes);
+ new PoolingClientConnectionManager(supportedSchemes, timeToLive,
TimeUnit.SECONDS);
- connectionManager.setDefaultMaxPerRoute(256);
- connectionManager.setMaxTotal(1024);
-
- return new DefaultHttpClient(connectionManager, defaultParameters);
+ connectionManager.setDefaultMaxPerRoute(maxPerRoute);
+ connectionManager.setMaxTotal(maxTotal);
+
+ DefaultHttpClient client = new DefaultHttpClient(connectionManager,
defaultParameters);
+ if (timeToLive <= 0) {
+ client.setReuseStrategy(new NoConnectionReuseStrategy());
+ }
+ return client;
}
@Override