17 |
17 |
import org.apache.http.HttpResponse;
|
18 |
18 |
import org.apache.http.client.HttpClient;
|
19 |
19 |
import org.apache.http.client.methods.HttpPost;
|
|
20 |
import org.apache.http.config.Registry;
|
|
21 |
import org.apache.http.config.RegistryBuilder;
|
|
22 |
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
|
23 |
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
|
24 |
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
|
25 |
import org.apache.http.impl.NoConnectionReuseStrategy;
|
|
26 |
import org.apache.http.impl.client.HttpClientBuilder;
|
|
27 |
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
20 |
28 |
import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
|
21 |
29 |
import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration;
|
22 |
30 |
|
23 |
31 |
import eu.etaxonomy.taxeditor.remoting.RemoteExecutionTimestampsUtil;
|
24 |
32 |
|
25 |
33 |
/**
|
|
34 |
* HttpInvokerRequestExecutor which extends the {@link HttpComponentsHttpInvokerRequestExecutor} by two functionalities:
|
|
35 |
*
|
|
36 |
* <ol>
|
|
37 |
* <li>Records time stamps when sending the request and when receiving the response.</li>
|
|
38 |
* <li>Allows custom configuration of the {@link PoolingHttpClientConnectionManager}
|
|
39 |
* (see <a href="https://dev.e-taxonomy.eu/redmine/issues/8812">https://dev.e-taxonomy.eu/redmine/issues/8812</a>).
|
|
40 |
* </ol>
|
|
41 |
*
|
26 |
42 |
* @author a.kohlbecker
|
27 |
43 |
* @since Jan 17, 2020
|
28 |
44 |
*/
|
29 |
45 |
public class TimestampingHttpInvokerRequestExecutor extends HttpComponentsHttpInvokerRequestExecutor {
|
30 |
46 |
|
|
47 |
private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;
|
|
48 |
|
|
49 |
private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
|
|
50 |
|
|
51 |
/**
|
|
52 |
* Default in PoolingHttpClientConnectionManager is 2000 milliseconds.
|
|
53 |
*
|
|
54 |
* see https://stackoverflow.com/questions/10558791/apache-httpclient-interim-error-nohttpresponseexception
|
|
55 |
*/
|
|
56 |
private static final int VALIDATE_AFTER_INACTIVITY = 2000;
|
|
57 |
|
|
58 |
public TimestampingHttpInvokerRequestExecutor() {
|
|
59 |
super(createDefaultHttpClient());
|
|
60 |
}
|
|
61 |
|
|
62 |
|
31 |
63 |
@Override
|
32 |
64 |
protected HttpResponse executeHttpPost(HttpInvokerClientConfiguration config, HttpClient httpClient,
|
33 |
65 |
HttpPost httpPost) throws IOException {
|
... | ... | |
60 |
92 |
}
|
61 |
93 |
}
|
62 |
94 |
|
|
95 |
private static HttpClient createDefaultHttpClient() {
|
|
96 |
Registry<ConnectionSocketFactory> schemeRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
|
97 |
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
|
98 |
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
|
99 |
.build();
|
|
100 |
|
|
101 |
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry);
|
|
102 |
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
|
|
103 |
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
|
|
104 |
connectionManager.setValidateAfterInactivity(VALIDATE_AFTER_INACTIVITY);
|
|
105 |
|
|
106 |
return HttpClientBuilder.create()
|
|
107 |
.setConnectionManager(connectionManager)
|
|
108 |
.setConnectionReuseStrategy(new NoConnectionReuseStrategy()) // see #8812
|
|
109 |
.build();
|
|
110 |
}
|
|
111 |
|
63 |
112 |
}
|
ref #8812 setting NoConnectionReuseStrategy for PoolingHttpClientConnectionManager to avoid NoHttpResponseExceptions