1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package org.metricshub.wbem.sblim.cimclient.internal.http;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 import java.net.URI;
57 import java.util.ArrayList;
58 import java.util.Iterator;
59 import java.util.List;
60 import java.util.logging.Level;
61 import javax.net.ssl.SSLContext;
62 import org.metricshub.wbem.sblim.cimclient.internal.logging.LogAndTraceBroker;
63 import org.metricshub.wbem.sblim.cimclient.internal.util.Util;
64 import org.metricshub.wbem.sblim.cimclient.internal.util.WBEMConfiguration;
65
66
67
68
69
70 public class HttpClientPool {
71
72
73
74 private List<HttpClient> iAllConnections;
75
76
77
78
79 private List<HttpClient> iAvailableConnections;
80
81
82
83
84 private boolean iClosed = false;
85
86 private final int iPoolSize;
87
88 private final WBEMConfiguration iConfiguration;
89
90
91
92
93 private SSLContext iSslContext;
94
95 private String[] iEnabledCipherSuites = null;
96
97
98
99
100
101
102
103 public HttpClientPool(WBEMConfiguration pConfiguration) {
104 super();
105 this.iConfiguration = pConfiguration;
106 this.iAllConnections = new ArrayList<HttpClient>(pConfiguration.getHttpPoolSize());
107 this.iAvailableConnections = new ArrayList<HttpClient>(pConfiguration.getHttpPoolSize());
108 this.iPoolSize = pConfiguration.getHttpPoolSize();
109 this.iSslContext = null;
110 this.iEnabledCipherSuites = null;
111 }
112
113
114
115
116
117
118
119 public synchronized int getNumberOfAllConnections() {
120 return this.iAllConnections.size();
121 }
122
123
124
125
126
127
128 public synchronized int getNumberOfAvailableConnections() {
129 return this.iAvailableConnections.size();
130 }
131
132
133
134
135
136
137 public WBEMConfiguration getConfigurationContext() {
138 return this.iConfiguration;
139 }
140
141
142
143
144
145
146
147 public synchronized SSLContext getSslContext() {
148 if (this.iSslContext == null) {
149 this.iSslContext = HttpSocketFactory.getInstance().getClientSSLContext(this.iConfiguration);
150 }
151 return this.iSslContext;
152 }
153
154
155
156
157
158
159
160
161
162
163
164 public synchronized HttpClient retrieveAvailableConnectionFromPool(URI pUri, AuthorizationHandler pHandler) {
165 if (this.iClosed) {
166 LogAndTraceBroker.getBroker().trace(Level.FINE, "Attempt to get client from closed http client pool,");
167 throw new IllegalStateException("HttpClientPool is closed. Retrieve connection failed.");
168 }
169 if (getNumberOfAvailableConnections() > 0) {
170 LogAndTraceBroker
171 .getBroker()
172 .trace(
173 Level.FINE,
174 "Reusing client (" +
175 pUri.toString() +
176 ", max: " +
177 getPoolSize() +
178 ", current:" +
179 getNumberOfAvailableConnections()
180 );
181
182 return this.iAvailableConnections.remove(0);
183 }
184
185 LogAndTraceBroker
186 .getBroker()
187 .trace(
188 Level.FINE,
189 "New client (" + pUri.toString() + ", max: " + getPoolSize() + ", current:" + getNumberOfAvailableConnections()
190 );
191 HttpClient client = new HttpClient(pUri, this, pHandler);
192 addConnectionToPool(client);
193 return client;
194 }
195
196
197
198
199
200
201
202
203
204
205 public synchronized boolean returnAvailableConnectionToPool(HttpClient httpClient) {
206 if (httpClient == null) {
207 return false;
208 }
209
210 if (this.iClosed) {
211 this.iAllConnections.remove(httpClient);
212 httpClient.disconnect();
213 return false;
214 }
215
216 if (getPoolSize() > this.iAvailableConnections.size()) {
217 if (!this.iAvailableConnections.contains(httpClient)) {
218
219
220 addConnectionToPool(httpClient);
221 this.iAvailableConnections.add(httpClient);
222 return true;
223 }
224 } else {
225 LogAndTraceBroker.getBroker().trace(Level.FINE, "Http pool size reached, discarding client.");
226 this.iAllConnections.remove(httpClient);
227 this.iAvailableConnections.remove(httpClient);
228 httpClient.disconnect();
229 }
230 return false;
231 }
232
233
234
235
236
237
238
239
240
241
242
243 public synchronized boolean addConnectionToPool(HttpClient httpClient) {
244 if (this.iClosed) {
245 LogAndTraceBroker.getBroker().trace(Level.FINE, "Attempt to add client to closed http client pool,");
246 throw new IllegalStateException("HttpClientPool is closed. Add connection failed.");
247 }
248 if (httpClient != null && !this.iAllConnections.contains(httpClient)) {
249
250 this.iAllConnections.add(httpClient);
251 return true;
252 }
253 return false;
254 }
255
256
257
258
259
260
261
262
263 public synchronized boolean removeConnectionFromPool(HttpClient httpClient) {
264 if (httpClient != null) {
265 this.iAvailableConnections.remove(httpClient);
266 if (this.iAllConnections.remove(httpClient)) {
267 return true;
268 }
269 return false;
270 }
271 return false;
272 }
273
274
275
276
277 public synchronized void closePool() {
278 this.iClosed = true;
279 Iterator<HttpClient> iter = this.iAvailableConnections.iterator();
280 while (iter.hasNext()) {
281 HttpClient httpClient = iter.next();
282 this.iAllConnections.remove(httpClient);
283 httpClient.disconnect();
284 }
285 this.iAvailableConnections.clear();
286 }
287
288 @Override
289 protected void finalize() throws Throwable {
290 closePool();
291 super.finalize();
292 }
293
294
295
296
297
298
299 public int getPoolSize() {
300 return this.iPoolSize;
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 public synchronized String[] getUpdatedCipherSuites(String[] pCurrentCipherSuites, String pDisableCipherSuites) {
320 if (this.iEnabledCipherSuites == null) {
321 this.iEnabledCipherSuites = Util.getFilteredStringArray(pCurrentCipherSuites, pDisableCipherSuites);
322 int before = pCurrentCipherSuites.length;
323 int after = this.iEnabledCipherSuites.length;
324 if (before > 0 && after == 0) LogAndTraceBroker
325 .getBroker()
326 .trace(Level.WARNING, "All cipher suites disabled for client!"); else if (before > after) LogAndTraceBroker
327 .getBroker()
328 .trace(Level.FINE, "Some (" + (before - after) + ") cipher suites disabled for client"); else if (
329 before == after
330 ) LogAndTraceBroker.getBroker().trace(Level.FINER, "No cipher suites disabled for client");
331 }
332 return this.iEnabledCipherSuites;
333 }
334 }