/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
/**
*
*/
package com.emc.cloud.http.common;
/**
* @author prabhj
*
*/
import com.emc.cloud.http.ssl.SSLHelper;
import com.emc.storageos.coordinator.client.service.impl.CoordinatorClientImpl;
import java.security.GeneralSecurityException;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BaseHttpClientFactory {
private static final Logger LOG = LoggerFactory.getLogger(BaseHttpClientFactory.class);
/** create thread-safe HTTP client instances */
protected boolean threadSafeClients = false;
/** for thread-safe clients, the maxiumum concurrent connections */
protected int maxConnections = 25;
/** for thread-safe clients, the maximum concurrent conections allows to a specific host */
protected int maxConnectionsPerHost = 5;
/** connection timeout in milliseconds used by extractor worker, configurable from command line */
protected int connectionTimeout = 10000;
/** connection read timeout in milliseconds used by extractor worker, configurable from command line */
protected int connectionReadTimeout = 150000;
/** if true allows for more permissive ssl, shouldn't be used in production */
protected boolean relaxSSL = false;
/** if set to true configures the httpClient the ViPR SSL trust manager. */
protected boolean secureSSL = false;
private CoordinatorClientImpl coordinator;
public void setRelaxSSL(boolean relaxSSL) {
this.relaxSSL = relaxSSL;
}
public boolean getRelaxSSL() {
return relaxSSL;
}
public void setThreadSafeClients(boolean threadSafeClients) {
this.threadSafeClients = threadSafeClients;
}
public boolean getThreadSafeClients() {
return threadSafeClients;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public int getMaxConnections() {
return maxConnections;
}
public void setMaxConnectionsPerHost(int maxConnectionsPerHost) {
this.maxConnectionsPerHost = maxConnectionsPerHost;
}
public int getMaxConnectionsPerHost() {
return maxConnectionsPerHost;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionReadTimeout(int connectionReadTimeout) {
this.connectionReadTimeout = connectionReadTimeout;
}
public int getConnectionReadTimeout() {
return connectionReadTimeout;
}
/**
* create a HTTPClient using the factory's default configuration
*
* @throws AuthenticationException, GeneralSecurityException, RuntimeException
*
*/
public AbstractHttpClient createHTTPClient() throws AuthenticationException, GeneralSecurityException, RuntimeException {
// use the configured defaults
return createHTTPClient(connectionTimeout, connectionReadTimeout);
}
/**
* create a HTTPClient overriding the factory's default configuration
*
* @param useConnectionTimeout - allows override of the the default connectionTimeout
* @param useConnectionReadTimeout - allows override of the default connectionReadTimeout
* @throws AuthenticationException, GeneralSecurityException, RuntimeException
*
*/
public AbstractHttpClient createHTTPClient(int useConnectionTimeout, int useConnectionReadTimeout) throws AuthenticationException,
GeneralSecurityException, RuntimeException {
return createRawHTTPClient(useConnectionTimeout, useConnectionReadTimeout);
}
/**
* Create a HTTPClient using the factories configuration without Credentials
*
* @param useConnectionTimeout - allows override of the the default connectionTimeout
* @param useConnectionReadTimeout - allows override of the default connectionReadTimeout
* @throws AuthenticationException, GeneralSecurityException, RuntimeException
*
*/
protected AbstractHttpClient createRawHTTPClient(int useConnectionTimeout, int useConnectionReadTimeout)
throws AuthenticationException, GeneralSecurityException, RuntimeException {
// select the appropriate connection manager and set options as appropriate
ClientConnectionManager cm = null;
if (threadSafeClients) {
ThreadSafeClientConnManager tscm = new ThreadSafeClientConnManager();
tscm.setMaxTotal(maxConnections);
tscm.setDefaultMaxPerRoute(maxConnectionsPerHost);
cm = tscm;
} else {
cm = new SingleClientConnManager();
}
// construct a client instance with the connection manager embedded
AbstractHttpClient httpClient = new DefaultHttpClient(cm);
if (relaxSSL) {
// !!!WARNING: This effectively turns off the authentication component of SSL, leaving only encryption
// can throw GeneralSecurityException
SSLHelper.configurePermissiveSSL(httpClient);
} else if (isSecureSSL()) {
SSLHelper.configureSSLWithTrustManger(httpClient, coordinator);
}
// see org.apache.http.client.params.AllClientPNames for a collected
// list of the available client parameters
HttpParams clientParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(clientParams, useConnectionTimeout);
HttpConnectionParams.setSoTimeout(clientParams, useConnectionReadTimeout);
// consider turning off the use of the Expect: 100-Continue response if
// your posts/puts tend to be relatively small
HttpProtocolParams.setUseExpectContinue(clientParams, false);
// TODO: reconsider this setting
// by default the client auto-retries on failures - turn that off so we can handle it manually
httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
return httpClient;
}
public void setCoordinator(CoordinatorClientImpl coordinator) {
this.coordinator = coordinator;
}
public CoordinatorClientImpl getCoordinator() {
return coordinator;
}
public boolean isSecureSSL() {
return secureSSL;
}
public void setSecureSSL(boolean secureSSL) {
this.secureSSL = secureSSL;
}
}