/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.search.solr.internal.http;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.search.solr.http.HttpClientFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.pool.PoolStats;
/**
* @author László Csontos
* @author Bruno Farache
* @author André de Oliveira
*/
public abstract class BasePoolingHttpClientFactory
implements HttpClientFactory {
@Override
public HttpClient createInstance() throws Exception {
if (_log.isDebugEnabled()) {
_log.debug("Create instance");
}
_poolingClientConnectionManager =
createPoolingHttpClientConnectionManager();
applyProperties(_poolingClientConnectionManager);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setConnectionManager(_poolingClientConnectionManager);
applyProperties(httpClientBuilder);
configure(httpClientBuilder);
return httpClientBuilder.build();
}
public void setDefaultMaxConnectionsPerRoute(
Integer defaultMaxConnectionsPerRoute) {
_defaultMaxConnectionsPerRoute = defaultMaxConnectionsPerRoute;
}
public void setMaxTotalConnections(Integer maxTotalConnections) {
_maxTotalConnections = maxTotalConnections;
}
@Override
public void shutdown() {
if (_log.isDebugEnabled()) {
_log.debug("Shut down");
}
if (_poolingClientConnectionManager == null) {
return;
}
int retry = 0;
while (retry < 10) {
PoolStats poolStats =
_poolingClientConnectionManager.getTotalStats();
int availableConnections = poolStats.getAvailable();
if (availableConnections <= 0) {
break;
}
if (_log.isDebugEnabled()) {
_log.debug(
toString() + " is waiting on " + availableConnections +
" connections");
}
_poolingClientConnectionManager.closeIdleConnections(
200, TimeUnit.MILLISECONDS);
try {
Thread.sleep(500);
}
catch (InterruptedException ie) {
}
retry++;
}
_poolingClientConnectionManager.shutdown();
_poolingClientConnectionManager = null;
if (_log.isDebugEnabled()) {
_log.debug(toString() + " was shut down");
}
}
protected void addHttpRequestInterceptor(
HttpRequestInterceptor httpRequestInterceptor) {
_httpRequestInterceptors.add(httpRequestInterceptor);
}
protected void applyProperties(HttpClientBuilder httpClientBuilder) {
for (HttpRequestInterceptor httpRequestInterceptor :
_httpRequestInterceptors) {
httpClientBuilder.addInterceptorFirst(httpRequestInterceptor);
}
}
protected void applyProperties(
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
if (_defaultMaxConnectionsPerRoute != null) {
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(
_defaultMaxConnectionsPerRoute.intValue());
}
if (_maxTotalConnections != null) {
poolingHttpClientConnectionManager.setMaxTotal(
_maxTotalConnections.intValue());
}
}
protected abstract void configure(HttpClientBuilder httpClientBuilder);
protected abstract PoolingHttpClientConnectionManager
createPoolingHttpClientConnectionManager() throws Exception;
protected void removeHttpRequestInterceptor(
HttpRequestInterceptor httpRequestInterceptor) {
_httpRequestInterceptors.remove(httpRequestInterceptor);
}
private static final Log _log = LogFactoryUtil.getLog(
BasePoolingHttpClientFactory.class);
private Integer _defaultMaxConnectionsPerRoute;
private final List<HttpRequestInterceptor> _httpRequestInterceptors =
new ArrayList<>();
private Integer _maxTotalConnections;
private PoolingHttpClientConnectionManager _poolingClientConnectionManager;
}