View Javadoc

1   package com.atlassian.httpclient.apache.httpcomponents;
2   
3   import com.atlassian.event.api.EventPublisher;
4   import com.atlassian.httpclient.api.HttpClient;
5   import com.atlassian.httpclient.api.factory.HttpClientFactory;
6   import com.atlassian.httpclient.api.factory.HttpClientOptions;
7   import com.atlassian.sal.api.ApplicationProperties;
8   import com.atlassian.sal.api.executor.ThreadLocalContextManager;
9   import com.google.common.annotations.VisibleForTesting;
10  import org.springframework.beans.factory.DisposableBean;
11  
12  import javax.annotation.Nonnull;
13  import java.util.Set;
14  import java.util.concurrent.CopyOnWriteArraySet;
15  
16  import static com.google.common.base.Preconditions.checkNotNull;
17  
18  public final class DefaultHttpClientFactory<C> implements HttpClientFactory, DisposableBean {
19      private final EventPublisher eventPublisher;
20      private final ApplicationProperties applicationProperties;
21      private final ThreadLocalContextManager<C> threadLocalContextManager;
22      private final Set<ApacheAsyncHttpClient> httpClients = new CopyOnWriteArraySet<ApacheAsyncHttpClient>();
23  
24      public DefaultHttpClientFactory(
25              @Nonnull EventPublisher eventPublisher,
26              @Nonnull ApplicationProperties applicationProperties,
27              @Nonnull ThreadLocalContextManager<C> threadLocalContextManager) {
28          this.eventPublisher = checkNotNull(eventPublisher);
29          this.applicationProperties = checkNotNull(applicationProperties);
30          this.threadLocalContextManager = checkNotNull(threadLocalContextManager);
31      }
32  
33      @Override
34      @Nonnull
35      public HttpClient create(@Nonnull HttpClientOptions options) {
36          return doCreate(options, threadLocalContextManager);
37      }
38  
39      @Override
40      @Nonnull
41      public <C> HttpClient create(@Nonnull HttpClientOptions options, @Nonnull ThreadLocalContextManager<C> threadLocalContextManager) {
42          return doCreate(options, threadLocalContextManager);
43      }
44  
45      @Override
46      public void dispose(@Nonnull final HttpClient httpClient) throws Exception {
47          if (httpClient instanceof ApacheAsyncHttpClient) {
48              final ApacheAsyncHttpClient client = (ApacheAsyncHttpClient) httpClient;
49              if (httpClients.remove(client)) {
50                  client.destroy();
51              } else {
52                  throw new IllegalStateException("Client is already disposed");
53              }
54          } else {
55              throw new IllegalArgumentException("Given client is not disposable");
56          }
57      }
58  
59      private <C> HttpClient doCreate(@Nonnull HttpClientOptions options, ThreadLocalContextManager<C> threadLocalContextManager) {
60          checkNotNull(options);
61          final ApacheAsyncHttpClient<C> httpClient = new ApacheAsyncHttpClient<>(eventPublisher, applicationProperties, threadLocalContextManager, options);
62          httpClients.add(httpClient);
63          return httpClient;
64      }
65  
66      @Override
67      public void destroy() throws Exception {
68          for (ApacheAsyncHttpClient httpClient : httpClients) {
69              httpClient.destroy();
70          }
71      }
72  
73      @VisibleForTesting
74      @Nonnull
75      Iterable<ApacheAsyncHttpClient> getHttpClients() {
76          return httpClients;
77      }
78  }