Skip to content

Commit 50845ef

Browse files
committed
1. Remove para for singleton constructor 2. fix Timeout ft
1 parent 474f092 commit 50845ef

File tree

8 files changed

+108
-82
lines changed

8 files changed

+108
-82
lines changed

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/HttpClientFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ public static IHttpClient buildClient(IClientProfile profile) {
3737
throw new IllegalStateException(String.format("%s is not assignable from com.aliyuncs.http.IHttpClient", customClientClassName));
3838
}
3939
if (ApacheHttpClient.class.equals(httpClientClass)) {
40-
return ApacheHttpClient.getInstance(clientConfig);
40+
IHttpClient client = ApacheHttpClient.getInstance();
41+
client.init(clientConfig);
42+
return client;
4143
}
4244
Constructor<? extends IHttpClient> constructor = httpClientClass.getConstructor(HttpClientConfig.class);
4345
return constructor.newInstance(clientConfig);

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/IHttpClient.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.aliyuncs.http;
22

3+
import com.aliyuncs.exceptions.ClientException;
4+
35
import java.io.Closeable;
46
import java.io.IOException;
57
import java.util.concurrent.Future;
68

7-
import com.aliyuncs.exceptions.ClientException;
8-
99
public abstract class IHttpClient implements Closeable {
1010

1111
protected boolean ignoreHttpsCert = false;
@@ -15,8 +15,12 @@ public IHttpClient(HttpClientConfig clientConfig) throws ClientException {
1515
if (clientConfig == null) {
1616
clientConfig = HttpClientConfig.getDefault();
1717
}
18-
init(clientConfig);
1918
this.clientConfig = clientConfig;
19+
init(clientConfig);
20+
}
21+
22+
public IHttpClient() {
23+
// do nothing
2024
}
2125

2226
protected abstract void init(HttpClientConfig clientConfig) throws ClientException;

aliyun-java-sdk-core/src/main/java/com/aliyuncs/http/clients/ApacheHttpClient.java

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
package com.aliyuncs.http.clients;
22

3-
import java.io.IOException;
4-
import java.security.KeyManagementException;
5-
import java.security.NoSuchAlgorithmException;
6-
import java.security.cert.CertificateException;
7-
import java.security.cert.X509Certificate;
8-
import java.util.Map;
9-
import java.util.concurrent.Callable;
10-
import java.util.concurrent.ExecutorService;
11-
import java.util.concurrent.Future;
12-
import java.util.concurrent.SynchronousQueue;
13-
import java.util.concurrent.ThreadFactory;
14-
import java.util.concurrent.ThreadPoolExecutor;
15-
import java.util.concurrent.TimeUnit;
16-
import java.util.concurrent.atomic.AtomicInteger;
17-
18-
import javax.net.ssl.SSLContext;
19-
3+
import com.aliyuncs.exceptions.ClientException;
4+
import com.aliyuncs.http.*;
5+
import com.aliyuncs.utils.IOUtils;
6+
import com.aliyuncs.utils.StringUtils;
207
import org.apache.http.Header;
218
import org.apache.http.HttpResponse;
229
import org.apache.http.client.config.RequestConfig;
@@ -41,14 +28,16 @@
4128
import org.apache.http.ssl.TrustStrategy;
4229
import org.apache.http.util.EntityUtils;
4330

44-
import com.aliyuncs.exceptions.ClientException;
45-
import com.aliyuncs.http.CallBack;
46-
import com.aliyuncs.http.FormatType;
47-
import com.aliyuncs.http.HttpClientConfig;
48-
import com.aliyuncs.http.HttpRequest;
49-
import com.aliyuncs.http.IHttpClient;
50-
import com.aliyuncs.utils.IOUtils;
51-
import com.aliyuncs.utils.StringUtils;
31+
import javax.net.ssl.SSLContext;
32+
import java.io.IOException;
33+
import java.security.KeyManagementException;
34+
import java.security.NoSuchAlgorithmException;
35+
import java.security.cert.CertificateException;
36+
import java.security.cert.X509Certificate;
37+
import java.util.Map;
38+
import java.util.concurrent.*;
39+
import java.util.concurrent.atomic.AtomicBoolean;
40+
import java.util.concurrent.atomic.AtomicInteger;
5241

5342
public class ApacheHttpClient extends IHttpClient {
5443

@@ -61,26 +50,37 @@ public class ApacheHttpClient extends IHttpClient {
6150
private ExecutorService executorService;
6251
private CloseableHttpClient httpClient;
6352
private PoolingHttpClientConnectionManager connectionManager;
64-
53+
private AtomicBoolean initialized = new AtomicBoolean(false);
54+
private CountDownLatch latch = new CountDownLatch(1);
6555
private static volatile ApacheHttpClient client;
6656

67-
public static ApacheHttpClient getInstance(HttpClientConfig config) throws ClientException {
57+
public static ApacheHttpClient getInstance() {
6858
if (client == null) {
6959
synchronized (ApacheHttpClient.class) {
7060
if (client == null) {
71-
client = new ApacheHttpClient(config);
61+
client = new ApacheHttpClient();
7262
}
7363
}
7464
}
7565
return client;
7666
}
7767

78-
private ApacheHttpClient(HttpClientConfig config) throws ClientException {
79-
super(config);
68+
private ApacheHttpClient() {
69+
super();
8070
}
8171

8272
@Override
83-
protected void init(final HttpClientConfig config) throws ClientException {
73+
protected void init(HttpClientConfig config0) throws ClientException {
74+
if (!initialized.compareAndSet(false, true)) {
75+
try {
76+
latch.await();
77+
} catch (InterruptedException e) {
78+
e.printStackTrace();
79+
}
80+
return;
81+
}
82+
final HttpClientConfig config = (config0 != null ? config0 : HttpClientConfig.getDefault());
83+
this.clientConfig = config;
8484
HttpClientBuilder builder;
8585
if (config.containsExtParam(EXT_PARAM_KEY_BUILDER)) {
8686
builder = (HttpClientBuilder) config.getExtParam(EXT_PARAM_KEY_BUILDER);
@@ -171,6 +171,7 @@ public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
171171
}
172172

173173
httpClient = builder.build();
174+
latch.countDown();
174175
}
175176

176177
private HttpUriRequest parseToHttpRequest(HttpRequest apiReq) throws IOException {
@@ -260,7 +261,7 @@ public final com.aliyuncs.http.HttpResponse syncInvoke(HttpRequest apiRequest) t
260261

261262
@Override
262263
public final Future<com.aliyuncs.http.HttpResponse> asyncInvoke(final HttpRequest apiRequest,
263-
final CallBack callback) {
264+
final CallBack callback) {
264265
return executorService.submit(new Callable<com.aliyuncs.http.HttpResponse>() {
265266
@Override
266267
public com.aliyuncs.http.HttpResponse call() throws Exception {
@@ -302,10 +303,12 @@ public boolean isSingleton() {
302303
@Override
303304
public void close() throws IOException {
304305
client = null;
305-
executorService.shutdown();
306-
ApacheIdleConnectionCleaner.removeConnectionManager(connectionManager);
307-
connectionManager.shutdown();
308-
IOUtils.closeQuietly(httpClient);
306+
if(initialized.compareAndSet(true, false)){
307+
executorService.shutdown();
308+
ApacheIdleConnectionCleaner.removeConnectionManager(connectionManager);
309+
connectionManager.shutdown();
310+
IOUtils.closeQuietly(httpClient);
311+
}
309312
}
310313

311314
private class DefaultAsyncThreadFactory implements ThreadFactory {

aliyun-java-sdk-core/src/test/java/com/aliyuncs/http/clients/ApacheHttpClientTest.java

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ private HttpClientConfig getMockHttpClientConfigWithTrueIgnoreSSLCerts() {
7777
@Test
7878
public void testApacheHttpClientConstructorFalseIgnoreSSLCerts() throws ClientException, IOException {
7979
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
80-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
80+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
81+
httpClient.init(config);
8182
Assert.assertTrue(httpClient instanceof ApacheHttpClient);
8283
httpClient.close();
8384
}
@@ -90,7 +91,8 @@ public void testApacheHttpClientFalseIgnoreSSLCertsNotNullSslSocketFactory() thr
9091
Mockito.when(config.getSslSocketFactory()).thenReturn(sslSocketFactory);
9192
Mockito.when(config.getHostnameVerifier()).thenReturn(hostnameVerifier);
9293

93-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
94+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
95+
httpClient.init(config);
9496
Assert.assertTrue(httpClient instanceof ApacheHttpClient);
9597
httpClient.close();
9698
}
@@ -101,7 +103,8 @@ public void testApacheHttpClientFalseIgnoreSSLCertsNotNullKeyManagers() throws C
101103
SecureRandom secureRandom = Mockito.mock(SecureRandom.class);
102104
Mockito.when(config.getSecureRandom()).thenReturn(secureRandom);
103105

104-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
106+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
107+
httpClient.init(config);
105108
Assert.assertTrue(httpClient instanceof ApacheHttpClient);
106109
httpClient.close();
107110
}
@@ -114,23 +117,26 @@ public void testApacheHttpClientNotNullExecutorService() throws ClientException,
114117

115118
Mockito.when(config.getKeepAliveDurationMillis()).thenReturn(0L);
116119

117-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
120+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
121+
httpClient.init(config);
118122
Assert.assertTrue(httpClient instanceof ApacheHttpClient);
119123
httpClient.close();
120124
}
121125

122126
@Test
123127
public void testApacheHttpClientConstructorIgnoreSSLCerts() throws ClientException, IOException {
124128
HttpClientConfig config = this.getMockHttpClientConfigWithTrueIgnoreSSLCerts();
125-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
129+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
130+
httpClient.init(config);
126131
Assert.assertTrue(httpClient instanceof ApacheHttpClient);
127132
httpClient.close();
128133
}
129134

130135
@Test
131136
public void testRestoreSSLCertificate() throws ClientException, IOException {
132137
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
133-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
138+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
139+
httpClient.init(config);
134140
thrown.expect(IllegalStateException.class);
135141
thrown.expectMessage("Apache httpclient does not support modify sslFactory after inited, "
136142
+ "use HttpClientConfig.setIgnoreSSLCerts(true) while building client");
@@ -141,7 +147,8 @@ public void testRestoreSSLCertificate() throws ClientException, IOException {
141147
@Test
142148
public void testIgnoreSSLCertificate() throws ClientException, IOException {
143149
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
144-
ApacheHttpClient httpClient = ApacheHttpClient.getInstance(config);
150+
ApacheHttpClient httpClient = ApacheHttpClient.getInstance();
151+
httpClient.init(config);
145152
thrown.expect(IllegalStateException.class);
146153
thrown.expectMessage("Apache httpclient does not support modify sslFactory after inited, "
147154
+ "use HttpClientConfig.setIgnoreSSLCerts(true) while building client");
@@ -192,7 +199,8 @@ private CloseableHttpResponse getMockHttpResponse() {
192199
public void testSyncInvoke() throws ClientException, IOException, NoSuchFieldException, SecurityException,
193200
IllegalArgumentException, IllegalAccessException {
194201
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
195-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
202+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
203+
apacheHttpClient.init(config);
196204
HttpRequest apiRequest = this.getMockHttpRequest();
197205
CloseableHttpResponse closeableHttpResponse = this.getMockHttpResponse();
198206
Field httpClientReflect = ApacheHttpClient.class.getDeclaredField("httpClient");
@@ -208,7 +216,8 @@ public void testSyncInvoke() throws ClientException, IOException, NoSuchFieldExc
208216
public void testAsyncInvoke() throws ClientException, IOException, NoSuchFieldException, SecurityException,
209217
IllegalArgumentException, IllegalAccessException {
210218
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
211-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
219+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
220+
apacheHttpClient.init(config);
212221
HttpRequest apiRequest = this.getMockHttpRequest();
213222

214223
CloseableHttpResponse closeableHttpResponse = this.getMockHttpResponse();
@@ -227,7 +236,8 @@ public void testAsyncInvoke() throws ClientException, IOException, NoSuchFieldEx
227236
public void testSyncInvokeNullContentType() throws ClientException, IOException, NoSuchFieldException,
228237
SecurityException, IllegalArgumentException, IllegalAccessException {
229238
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
230-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
239+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
240+
apacheHttpClient.init(config);
231241
HttpRequest apiRequest = this.getMockHttpRequest();
232242
CloseableHttpResponse closeableHttpResponse = this.getMockHttpResponse();
233243

@@ -249,7 +259,8 @@ public void testSyncInvokeNullContentType() throws ClientException, IOException,
249259
public void testSyncInvokeNullHttpResponseEntity() throws ClientException, IOException, NoSuchFieldException,
250260
SecurityException, IllegalArgumentException, IllegalAccessException {
251261
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
252-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
262+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
263+
apacheHttpClient.init(config);
253264
HttpRequest apiRequest = this.getMockHttpRequest();
254265
Mockito.when(apiRequest.getSysMethod()).thenReturn(MethodType.PUT);
255266
Mockito.when(apiRequest.getHeaderValue(Mockito.anyString())).thenReturn("contentType");
@@ -276,7 +287,8 @@ public void testSyncInvokeNullHttpResponseEntity() throws ClientException, IOExc
276287
public void testSyncInvokeNotNullHttpResponseEntityIsChunked() throws ClientException, IOException, NoSuchFieldException,
277288
SecurityException, IllegalArgumentException, IllegalAccessException {
278289
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
279-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
290+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
291+
apacheHttpClient.init(config);
280292
HttpRequest apiRequest = this.getMockHttpRequest();
281293
Mockito.when(apiRequest.getSysMethod()).thenReturn(MethodType.PUT);
282294
Mockito.when(apiRequest.getHeaderValue(Mockito.anyString())).thenReturn("contentType");
@@ -303,7 +315,8 @@ public void testSyncInvokeNotNullHttpResponseEntityIsChunked() throws ClientExce
303315
public void testSyncInvokeNotNullHttpResponseEntity() throws ClientException, IOException, NoSuchFieldException,
304316
SecurityException, IllegalArgumentException, IllegalAccessException {
305317
HttpClientConfig config = this.getMockHttpClientConfigWithFalseIgnoreSSLCerts();
306-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
318+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
319+
apacheHttpClient.init(config);
307320
HttpRequest apiRequest = this.getMockHttpRequest();
308321
Mockito.when(apiRequest.getSysMethod()).thenReturn(MethodType.PUT);
309322
Mockito.when(apiRequest.getHeaderValue(Mockito.anyString())).thenReturn("contentType");
@@ -332,9 +345,10 @@ public void testSyncInvokeNotNullHttpResponseEntity() throws ClientException, IO
332345
@Test
333346
public void testClientTimeout() throws ClientException, IOException, NoSuchFieldException, SecurityException,
334347
IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
335-
ApacheHttpClient.getInstance(HttpClientConfig.getDefault()).close();
348+
ApacheHttpClient.getInstance().close();
336349
HttpClientConfig config = HttpClientConfig.getDefault();
337-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
350+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
351+
apacheHttpClient.init(config);
338352
Method declaredMethod = ApacheHttpClient.class.getDeclaredMethod("parseToHttpRequest", HttpRequest.class);
339353
declaredMethod.setAccessible(true);
340354
HttpRequest apiReq = new HttpRequest("http://test.com");
@@ -346,7 +360,8 @@ public void testClientTimeout() throws ClientException, IOException, NoSuchField
346360

347361
config.setConnectionTimeoutMillis(5010);
348362
config.setReadTimeoutMillis(10010);
349-
apacheHttpClient = ApacheHttpClient.getInstance(config);
363+
apacheHttpClient = ApacheHttpClient.getInstance();
364+
apacheHttpClient.init(config);
350365
httpRequest = (HttpRequestBase) declaredMethod.invoke(apacheHttpClient, apiReq);
351366
Assert.assertEquals(5010, httpRequest.getConfig().getConnectTimeout());
352367
Assert.assertEquals(10010, httpRequest.getConfig().getSocketTimeout());
@@ -356,11 +371,12 @@ public void testClientTimeout() throws ClientException, IOException, NoSuchField
356371
@Test
357372
public void testRequestTimeout() throws ClientException, IOException, NoSuchFieldException, SecurityException,
358373
IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
359-
ApacheHttpClient.getInstance(HttpClientConfig.getDefault()).close();
374+
ApacheHttpClient.getInstance().close();
360375
HttpClientConfig config = HttpClientConfig.getDefault();
361376
config.setConnectionTimeoutMillis(5020);
362377
config.setReadTimeoutMillis(10020);
363-
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance(config);
378+
ApacheHttpClient apacheHttpClient = ApacheHttpClient.getInstance();
379+
apacheHttpClient.init(config);
364380
Method declaredMethod = ApacheHttpClient.class.getDeclaredMethod("parseToHttpRequest", HttpRequest.class);
365381
declaredMethod.setAccessible(true);
366382
HttpRequest apiReq = new HttpRequest("http://test.com");

0 commit comments

Comments
 (0)