package org.ovirt.engine.core.vdsbroker; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethodRetryHandler; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.utils.crypt.EngineEncryptionUtils; import org.ovirt.engine.core.utils.ssl.AuthSSLProtocolSocketFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HttpUtils { private static final String HTTP = "http"; private static final String HTTPS = "https"; private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); private static final Set<String> SUPPORTED_METHODS_FOR_LONG_CONVERSION = new HashSet<>(Arrays.asList("create", "hotplugDisk")); static { if (Config.getValue(ConfigValues.EncryptHostCommunication)) { try { // registering the https protocol with a socket factory that // provides client authentication. ProtocolSocketFactory factory = new AuthSSLProtocolSocketFactory(EngineEncryptionUtils.getKeyManagers(), EngineEncryptionUtils.getTrustManagers(), Config.getValue(ConfigValues.VdsmSSLProtocol)); Protocol clientAuthHTTPS = new Protocol("https", factory, 54321); Protocol.registerProtocol("https", clientAuthHTTPS); } catch (Exception e) { log.error("Failed to init AuthSSLProtocolSocketFactory. SSL connections will not work", e); } } } /** * There are places in the code where use http to communicate with vdsm or external providers * * @param connectionTimeOut * - the instance type of the interface for this connection * @param clientRetries * - Number of retries if timeout occurd * @param maxConnectionsPerHost * - maximum number of connections allowed for a given host * @param maxTotalConnections * - The maximum number of connections allowed * @return {@link HttpClient}. */ public static HttpClient getConnection( int connectionTimeOut, int clientRetries, int maxConnectionsPerHost, int maxTotalConnections) { HttpConnectionManagerParams params = new HttpConnectionManagerParams(); params.setConnectionTimeout(connectionTimeOut); params.setDefaultMaxConnectionsPerHost(maxConnectionsPerHost); params.setMaxTotalConnections(maxTotalConnections); MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager(); httpConnectionManager.setParams(params); // Create the client: HttpClient client = new HttpClient(httpConnectionManager); // Configure the HTTP client so it will retry the execution of // methods when there are IO errors: int retries = Config.getValue(ConfigValues.vdsRetries); HttpMethodRetryHandler handler = new DefaultHttpMethodRetryHandler(retries, false); HttpClientParams parameters = client.getParams(); parameters.setParameter(HttpMethodParams.RETRY_HANDLER, handler); // Done: return client; } public static Pair<String, URL> getConnectionUrl(String hostName, int port, String path, boolean isSecure) { final String protocol = isSecure ? HTTPS : HTTP; try { URL url = new URL(protocol, hostName, port, path != null ? "/" + path : ""); return new Pair<>(url.toString(), url); } catch (MalformedURLException mfue) { log.error("failed to form the xml-rpc url", mfue); throw new IllegalStateException(mfue); } } public static void shutDownConnection(HttpClient httpClient) { if (httpClient != null && httpClient.getHttpConnectionManager() != null) { ((MultiThreadedHttpConnectionManager) httpClient.getHttpConnectionManager()).shutdown(); } } }