3434import microsoft .exchange .webservices .data .core .exception .service .local .ServiceLocalException ;
3535import microsoft .exchange .webservices .data .misc .EwsTraceListener ;
3636import microsoft .exchange .webservices .data .misc .ITraceListener ;
37+
3738import org .apache .http .client .AuthenticationStrategy ;
3839import org .apache .http .client .CookieStore ;
3940import org .apache .http .client .protocol .HttpClientContext ;
4647import org .apache .http .impl .client .CloseableHttpClient ;
4748import org .apache .http .impl .client .HttpClients ;
4849import org .apache .http .impl .conn .BasicHttpClientConnectionManager ;
50+ import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
4951
5052import javax .xml .stream .XMLStreamException ;
5153import javax .xml .stream .XMLStreamWriter ;
@@ -142,7 +144,12 @@ public abstract class ExchangeServiceBase implements Closeable {
142144
143145 protected HttpClientContext httpContext ;
144146
145- protected HttpClientWebRequest request = null ;
147+ protected CloseableHttpClient httpPoolingClient ;
148+
149+ private int maximumPoolingConnections = 10 ;
150+
151+
152+ // protected HttpClientWebRequest request = null;
146153
147154 // protected static HttpStatusCode AccountIsLocked = (HttpStatusCode)456;
148155
@@ -193,8 +200,32 @@ private void initializeHttpClient() {
193200 .build ();
194201 }
195202
203+ private void initializeHttpPoolingClient () {
204+ Registry <ConnectionSocketFactory > registry = createConnectionSocketFactoryRegistry ();
205+ PoolingHttpClientConnectionManager httpConnectionManager = new PoolingHttpClientConnectionManager (registry );
206+ httpConnectionManager .setMaxTotal (maximumPoolingConnections );
207+ httpConnectionManager .setDefaultMaxPerRoute (maximumPoolingConnections );
208+ AuthenticationStrategy authStrategy = new CookieProcessingTargetAuthenticationStrategy ();
209+
210+ httpPoolingClient = HttpClients .custom ()
211+ .setConnectionManager (httpConnectionManager )
212+ .setTargetAuthenticationStrategy (authStrategy )
213+ .build ();
214+ }
215+
216+
196217 /**
197- * Create registry with configured {@link ConnectionSocketFactory} instances.
218+ * Sets the maximum number of connections for the pooling connection manager which is used for subscriptions.
219+ * <p>
220+ * Default is 10.
221+ * @param maximumPoolConnections
222+ */
223+ public void setMaximumPoolingConnections (int maximumPoolingConnections ) {
224+ this .maximumPoolingConnections = maximumPoolingConnections ;
225+ }
226+
227+ /**
228+ * Create registry with configured {@see ConnectionSocketFactory} instances.
198229 * Override this method to change how to work with different schemas.
199230 *
200231 * @return registry object
@@ -226,6 +257,8 @@ private void initializeHttpContext() {
226257 public void close () {
227258 try {
228259 httpClient .close ();
260+ if (httpPoolingClient != null )
261+ httpPoolingClient .close ();
229262 } catch (IOException e ) {
230263 // Ignore exception while closing the HttpClient.
231264 }
@@ -274,9 +307,33 @@ protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzip
274307 throw new ServiceLocalException (strErr );
275308 }
276309
277- request = new HttpClientWebRequest (httpClient , httpContext );
278- request .setProxy (getWebProxy ());
310+ HttpClientWebRequest request = new HttpClientWebRequest (httpClient , httpContext );
311+ prepareHttpWebRequestForUrl (url , acceptGzipEncoding , allowAutoRedirect , request );
312+
313+ return request ;
314+ }
315+
316+ protected HttpWebRequest prepareHttpPoolingWebRequestForUrl (URI url , boolean acceptGzipEncoding ,
317+ boolean allowAutoRedirect ) throws ServiceLocalException , URISyntaxException {
318+ // Verify that the protocol is something that we can handle
319+ String scheme = url .getScheme ();
320+ if (!scheme .equalsIgnoreCase (EWSConstants .HTTP_SCHEME )
321+ && !scheme .equalsIgnoreCase (EWSConstants .HTTPS_SCHEME )) {
322+ String strErr = String .format ("Protocol %s isn't supported for service request." , scheme );
323+ throw new ServiceLocalException (strErr );
324+ }
279325
326+ if (httpPoolingClient == null )
327+ initializeHttpPoolingClient ();
328+ HttpClientWebRequest request = new HttpClientWebRequest (httpPoolingClient , httpContext );
329+ prepareHttpWebRequestForUrl (url , acceptGzipEncoding , allowAutoRedirect , request );
330+
331+ return request ;
332+ }
333+
334+ private void prepareHttpWebRequestForUrl (URI url , boolean acceptGzipEncoding , boolean allowAutoRedirect , HttpClientWebRequest request )
335+ throws ServiceLocalException , URISyntaxException
336+ {
280337 try {
281338 request .setUrl (url .toURL ());
282339 } catch (MalformedURLException e ) {
@@ -298,8 +355,6 @@ protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzip
298355 request .prepareConnection ();
299356
300357 httpResponseHeaders .clear ();
301-
302- return request ;
303358 }
304359
305360 protected void prepareCredentials (HttpWebRequest request ) throws ServiceLocalException , URISyntaxException {
0 commit comments