I am using Spring RestTemplate as my HttpClient in my project and I want to
use connection pooling feature with RestTemplate. After reading more on
HttpClient and RestTemplate, I was able to come up with this example which
uses PoolingHttpClientConnectionManager class with RestTemplate but I am
pretty sure the way I am using is not right. Can anyone help me to
understand what is the right way to use these two in my below code.

I have put everything in gist here -

https://gist.github.com/TechGeeky/3f32a621bc9d8043197b

Also below is the code as well which shows how I am using.

    public class DataClient implements Client {

        // here I am setting request factory to my RestTemplate
        private RestTemplate restTemplate = new
RestTemplate(RestTemplateConnectionPooling.getInstance()
            .getRequestFactory());
        private ExecutorService executor = Executors.newFixedThreadPool(10);

        // for synchronous call
        @Override
        public DataResponse executeSynchronous(DataKey key) {
            DataResponse dataResponse = null;
            Future<DataResponse> future = null;

            try {
                future = executeAsynchronous(key);
                dataResponse = future.get(key.getTimeout(),
TimeUnit.MILLISECONDS);
            } catch (TimeoutException ex) {
                // log exception
                dataResponse = new DataResponse(null,
DataErrorEnum.TIMEOUT_ON_CLIENT, DataStatusEnum.ERROR);
                future.cancel(true); // terminating tasks that have timed
out
            } catch (Exception ex) {
                // log exception
                dataResponse = new DataResponse(null,
DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR);
            }

            return dataResponse;
        }

        //for asynchronous call
        @Override
        public Future<DataResponse> executeAsynchronous(DataKey key) {
            Future<DataResponse> future = null;

            try {
                Task task = new Task(key, restTemplate);
                future = executor.submit(task);
            } catch (Exception ex) {
                // log exception
            }

            return future;
        }
    }

A simple class which will perform the actual task:

    public class Task implements Callable<DataResponse> {

        private final DataKey key;
        private final RestTemplate restTemplate;

        public Task(DataKey key, RestTemplate restTemplate) {
            this.key = key;
            this.restTemplate = restTemplate;
        }

        @Override
        public DataResponse call() {

            // use RestTemplate here to make Http call and get the data
            // and then return the "DataResponse" back

        }
    }

Below is where I am having PoolingHttpClientConnectionManager
initialization as part of singleton class. Do I need this class at all if I
want to use RestTemplate with PoolingHttpClientConnectionManager?

    public class RestTemplateConnectionPooling {

        private final HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();

        private static class Holder {
            private static final RestTemplateConnectionPooling INSTANCE =
new RestTemplateConnectionPooling();
        }

        public static RestTemplateConnectionPooling getInstance() {
            return Holder.INSTANCE;
        }

        private RestTemplateConnectionPooling() {
            RequestConfig requestConfig =
RequestConfig.custom().setConnectTimeout(1000).setSocketTimeout(1000)
                    .setStaleConnectionCheckEnabled(false).build();
            PoolingHttpClientConnectionManager
poolingHttpClientConnectionManager = new
PoolingHttpClientConnectionManager();
            poolingHttpClientConnectionManager.setMaxTotal(200);
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);

            CloseableHttpClient httpClientBuilder =
HttpClientBuilder.create()

.setConnectionManager(poolingHttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
                    .build();

            requestFactory.setHttpClient(httpClientBuilder);
        }

        public HttpComponentsClientHttpRequestFactory getRequestFactory() {
            return requestFactory;
        }
    }

Now my question is - Does this look right the way I am using RestTemplate
with PoolingHttpClientConnectionManager? Is there any better way to use
connection pooling with RestTemplate?

I am using http-client 4.3.1 and spring-web 3.2.8.

Reply via email to