HTTPCLIENT-1782: [OSGi] List of tracked HTTPClients is mutable but not thread-safe

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1763285 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Julian Sedding 2016-10-04 14:41:23 +00:00
parent cee2500491
commit 2a1617b5f0
3 changed files with 36 additions and 34 deletions

View File

@ -83,11 +83,7 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M
private final List<ProxyConfiguration> proxyConfigurations = new CopyOnWriteArrayList<>();
private final List<CloseableHttpClient> trackedHttpClients;
public HttpProxyConfigurationActivator() {
trackedHttpClients = new WeakList<CloseableHttpClient>();
}
private final HttpClientTracker httpClientTracker = new HttpClientTracker();
/**
* {@inheritDoc}
@ -119,7 +115,7 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M
props.put(Constants.SERVICE_VENDOR, context.getBundle().getHeaders().get(Constants.BUNDLE_VENDOR));
props.put(Constants.SERVICE_DESCRIPTION, BUILDER_FACTORY_SERVICE_NAME);
clientFactory = context.registerService(HttpClientBuilderFactory.class,
new OSGiClientBuilderFactory(configurator, trackedHttpClients),
new OSGiClientBuilderFactory(configurator, httpClientTracker),
props);
props.clear();
@ -127,7 +123,7 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M
props.put(Constants.SERVICE_VENDOR, context.getBundle().getHeaders().get(Constants.BUNDLE_VENDOR));
props.put(Constants.SERVICE_DESCRIPTION, CACHEABLE_BUILDER_FACTORY_SERVICE_NAME);
cachingClientFactory = context.registerService(CachingHttpClientBuilderFactory.class,
new OSGiCachingClientBuilderFactory(configurator, trackedHttpClients),
new OSGiCachingClientBuilderFactory(configurator, httpClientTracker),
props);
}
@ -140,23 +136,16 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M
for (final ServiceRegistration<ProxyConfiguration> registeredConfiguration : registeredConfigurations.values()) {
safeUnregister(registeredConfiguration);
}
// remove all tracked services
registeredConfigurations.clear();
safeUnregister(configurator);
safeUnregister(clientFactory);
safeUnregister(cachingClientFactory);
safeUnregister(trustedHostConfiguration);
// ensure all http clients - generated with the - are terminated
for (final CloseableHttpClient client : trackedHttpClients) {
if (null != client) {
closeQuietly(client);
}
}
// remove all tracked services
registeredConfigurations.clear();
// remove all tracked created clients
trackedHttpClients.clear();
// ensure all http clients are closed
httpClientTracker.closeAll();
}
/**
@ -214,11 +203,28 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M
}
private static void closeQuietly(final Closeable closeable) {
try {
closeable.close();
} catch (final IOException e) {
// do nothing
if (closeable != null) {
try {
closeable.close();
} catch (final IOException e) {
// do nothing
}
}
}
static class HttpClientTracker {
private final List<CloseableHttpClient> trackedHttpClients = new WeakList<>();
synchronized void track(final CloseableHttpClient client) {
trackedHttpClients.add(client);
}
synchronized void closeAll() {
for (final CloseableHttpClient client : trackedHttpClients) {
closeQuietly(client);
}
trackedHttpClients.clear();
}
}
}

View File

@ -26,8 +26,6 @@
*/
package org.apache.hc.client5.http.osgi.impl;
import java.util.List;
import org.apache.hc.client5.http.impl.cache.CachingHttpClientBuilder;
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
import org.apache.hc.client5.http.osgi.services.CachingHttpClientBuilderFactory;
@ -39,13 +37,13 @@ final class OSGiCachingClientBuilderFactory implements CachingHttpClientBuilderF
private final HttpClientBuilderConfigurator configurator;
private List<CloseableHttpClient> trackedHttpClients;
private final HttpProxyConfigurationActivator.HttpClientTracker httpClientTracker;
OSGiCachingClientBuilderFactory(
final HttpClientBuilderConfigurator configurator,
final List<CloseableHttpClient> trackedHttpClients) {
final HttpProxyConfigurationActivator.HttpClientTracker httpClientTracker) {
this.configurator = configurator;
this.trackedHttpClients = trackedHttpClients;
this.httpClientTracker = httpClientTracker;
}
@Override
@ -54,7 +52,7 @@ final class OSGiCachingClientBuilderFactory implements CachingHttpClientBuilderF
@Override
public CloseableHttpClient build() {
final CloseableHttpClient client = super.build();
trackedHttpClients.add(client);
httpClientTracker.track(client);
return client;
}
});

View File

@ -26,8 +26,6 @@
*/
package org.apache.hc.client5.http.osgi.impl;
import java.util.List;
import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
import org.apache.hc.client5.http.osgi.services.HttpClientBuilderFactory;
@ -39,13 +37,13 @@ final class OSGiClientBuilderFactory implements HttpClientBuilderFactory {
private final HttpClientBuilderConfigurator configurator;
private final List<CloseableHttpClient> trackedHttpClients;
private final HttpProxyConfigurationActivator.HttpClientTracker httpClientTracker;
OSGiClientBuilderFactory(
final HttpClientBuilderConfigurator configurator,
final List<CloseableHttpClient> trackedHttpClients) {
final HttpProxyConfigurationActivator.HttpClientTracker httpClientTracker) {
this.configurator = configurator;
this.trackedHttpClients = trackedHttpClients;
this.httpClientTracker = httpClientTracker;
}
@Override
@ -54,7 +52,7 @@ final class OSGiClientBuilderFactory implements HttpClientBuilderFactory {
@Override
public CloseableHttpClient build() {
final CloseableHttpClient client = super.build();
trackedHttpClients.add(client);
httpClientTracker.track(client);
return client;
}
});