/* * Copyright (c) 2012 EMC Corporation * All Rights Reserved */ package com.emc.storageos.isilon.restapi; import java.io.IOException; import java.net.URI; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethodRetryHandler; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.protocol.Protocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; import com.sun.jersey.client.apache.ApacheHttpClient; import com.sun.jersey.client.apache.ApacheHttpClientHandler; /** * Isilon API client factory */ public class IsilonApiFactory { private Logger _log = LoggerFactory.getLogger(IsilonApiFactory.class); private static final int DEFAULT_MAX_CONN = 300; private static final int DEFAULT_MAX_CONN_PER_HOST = 100; private static final int DEFAULT_CONN_TIMEOUT = 1000 * 30; private static final int DEFAULT_CONN_MGR_TIMEOUT = 1000 * 60; private static final int DEFAULT_SOCKET_CONN_TIMEOUT = 1000 * 60 * 60; private int _maxConn = DEFAULT_MAX_CONN; private int _maxConnPerHost = DEFAULT_MAX_CONN_PER_HOST; private int _connTimeout = DEFAULT_CONN_TIMEOUT; private int _socketConnTimeout = DEFAULT_SOCKET_CONN_TIMEOUT; private int connManagerTimeout = DEFAULT_CONN_MGR_TIMEOUT; private ApacheHttpClientHandler _clientHandler; private ConcurrentMap<String, IsilonApi> _clientMap; private MultiThreadedHttpConnectionManager _connectionManager; /** * Maximum number of outstanding connections * * @param maxConn */ public void setMaxConnections(int maxConn) { _maxConn = maxConn; } /** * Maximum number of outstanding connections per host * * @param maxConnPerHost */ public void setMaxConnectionsPerHost(int maxConnPerHost) { _maxConnPerHost = maxConnPerHost; } /** * Connection timeout * * @param connectionTimeoutMs */ public void setConnectionTimeoutMs(int connectionTimeoutMs) { _connTimeout = connectionTimeoutMs; } /** * Socket connection timeout * * @param connectionTimeoutMs */ public void setSocketConnectionTimeoutMs(int connectionTimeoutMs) { _socketConnTimeout = connectionTimeoutMs; } /** * @param connManagerTimeout the connManagerTimeout to set */ public void setConnManagerTimeout(int connManagerTimeout) { this.connManagerTimeout = connManagerTimeout; } /** * Initialize HTTP client */ public void init() { _clientMap = new ConcurrentHashMap<String, IsilonApi>(); HttpConnectionManagerParams params = new HttpConnectionManagerParams(); params.setDefaultMaxConnectionsPerHost(_maxConnPerHost); params.setMaxTotalConnections(_maxConn); params.setTcpNoDelay(true); params.setConnectionTimeout(_connTimeout); params.setSoTimeout(_socketConnTimeout); _connectionManager = new MultiThreadedHttpConnectionManager(); _connectionManager.setParams(params); _connectionManager.closeIdleConnections(0); // close idle connections immediately HttpClient client = new HttpClient(_connectionManager); client.getParams().setConnectionManagerTimeout(connManagerTimeout); client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new HttpMethodRetryHandler() { @Override public boolean retryMethod(HttpMethod httpMethod, IOException e, int i) { return false; } }); _clientHandler = new ApacheHttpClientHandler(client); Protocol.registerProtocol("https", new Protocol("https", new NonValidatingSocketFactory(), 443)); } /** * shutdown http connection manager. */ protected void shutdown() { _connectionManager.shutdown(); } /** * Create Isilon API client * * @param endpoint isilon endpoint * @return */ public IsilonApi getRESTClient(URI endpoint) { IsilonApi isilonApi = _clientMap.get(endpoint.toString() + ":" + ":"); if (isilonApi == null) { Client jerseyClient = new ApacheHttpClient(_clientHandler); RESTClient restClient = new RESTClient(jerseyClient); isilonApi = new IsilonApi(endpoint, restClient); _clientMap.putIfAbsent(endpoint.toString() + ":" + ":", isilonApi); } return isilonApi; } /** * Create Isilon API client * * @param endpoint isilon endpoint * @return */ public IsilonApi getRESTClient(URI endpoint, String username, String password) { IsilonApi isilonApi = _clientMap.get(endpoint.toString() + ":" + username + ":" + password); if (isilonApi == null) { Client jerseyClient = new ApacheHttpClient(_clientHandler); jerseyClient.addFilter(new HTTPBasicAuthFilter(username, password)); RESTClient restClient = new RESTClient(jerseyClient); isilonApi = new IsilonApi(endpoint, restClient); _clientMap.putIfAbsent(endpoint.toString() + ":" + username + ":" + password, isilonApi); } return isilonApi; } }