org.ovirt.engine.sdk.web.ConnectionsPoolBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ovirt-engine-sdk-java Show documentation
Show all versions of ovirt-engine-sdk-java Show documentation
This is Java SDK for the oVirt virtualization
//
// Copyright (c) 2012 Red Hat, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.ovirt.engine.sdk.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.ovirt.engine.sdk.exceptions.ProtocolException;
import org.ovirt.engine.sdk.exceptions.SocketFactoryException;
import org.ovirt.engine.sdk.utils.StringUtils;
/**
* Provides ConnectionsPool building services
*/
public class ConnectionsPoolBuilder {
private static final String DEFAULT_KEYSTORE_TRUSTSTORE = "ovirtsdk-keystore.truststore";
private static final String BAD_PROTOCOL_ERROR = "Unsupported protocol ";
private static final String BAD_KEY_ERROR = "SSL context initiation has failed because of key error.";
private static final String NO_TLS_ERROR = "SSL context initiation has failed locating TLS slgorithm.";
private static final String KEY_STORE_ERROR = "CA certeficate keysotore initiation has failed.";
private static final String KEY_STORE_FILE_NOT_FOUND_ERROR = "CA certeficate keysotore was not found.";
private static final String CERTEFICATE_ERROR = "CA certeficate error.";
private static final String IO_ERROR = "I/O error occured, is your keysotore password correct?";
private static final String UNRECOVERABLE_KEY_ERROR = "Unrecoverable key error has occured.";
private static int MAX_CONNECTIONS = 20;
private static int MAX_CONNECTIONS_PER_HOST = 50;
private static int MAX_CONNECTIONS_PER_ROUTE = 5;
private static long WAIT_IDLE_CHECK_TTL = 5000;
private static long WAIT_IDLE_CLOSE_TTL = 30;
private static String HTTP_PROTOCOL = "http";
private static String HTTPS_PROTOCOL = "https";
private String url;
private String username;
private String password;
private String key_file;
private String cert_file;
private String ca_file;
private int port = -1;
private Integer requestTimeout;
private Integer sessionTimeout;
private boolean noHostVerification = false;
private String keyStorePath;
private String keyStorePassword;
private URL urlobj = null;
/**
* @param url
* oVirt API url
* @param username
* oVirt API user name
* @param password
* oVirt API password
*
* @throws MalformedURLException
*/
public ConnectionsPoolBuilder(String url, String username, String password) throws MalformedURLException {
url(url);
username(username);
password(password);
}
/**
* @param url
* oVirt API url
*
* @throws MalformedURLException
*/
public ConnectionsPoolBuilder(String url) throws MalformedURLException {
url(url);
}
/**
*
* @param url
* oVirt API url
*
* @throws MalformedURLException
*/
private ConnectionsPoolBuilder url(String url) throws MalformedURLException {
this.url = url;
this.urlobj = createURL(url);
return this;
}
/**
* @param username
* oVirt API user name
*/
private ConnectionsPoolBuilder username(String username) {
this.username = username;
return this;
}
/**
* @param password
* oVirt API password
*/
private ConnectionsPoolBuilder password(String password) {
this.password = password;
return this;
}
/**
* @param key_file
* client key
*/
public ConnectionsPoolBuilder key_file(String key_file) {
this.key_file = key_file;
return this;
}
/**
* @param cert_file
* client cert file
*/
public ConnectionsPoolBuilder cert_file(String cert_file) {
this.cert_file = cert_file;
return this;
}
/**
* @param ca_file
* server CA cert.
*/
public ConnectionsPoolBuilder ca_file(String ca_file) {
this.ca_file = ca_file;
return this;
}
/**
* @param keyStorePath
* path to server CA KeyStore
*/
public ConnectionsPoolBuilder keyStorePath(String keyStorePath) {
this.keyStorePath = keyStorePath;
return this;
}
/**
* @param keyStorePassword
* server CA KeyStore password
*/
public ConnectionsPoolBuilder keyStorePassword(String keyStorePassword) {
this.keyStorePassword = keyStorePassword;
return this;
}
/**
* @param port
* oVirt API port
*
*/
public ConnectionsPoolBuilder port(Integer port) {
if (port != null) {
this.port = port.intValue();
}
return this;
}
/**
* @param requestTimeout
* request timeout
*/
public ConnectionsPoolBuilder requestTimeout(Integer requestTimeout) {
if (requestTimeout != null) {
this.requestTimeout = requestTimeout;
}
return this;
}
/**
* @param sessionTimeout
* authentication session inactivity timeout
*/
public ConnectionsPoolBuilder sessionTimeout(Integer sessionTimeout) {
if (sessionTimeout != null) {
this.sessionTimeout = sessionTimeout;
}
return this;
}
/**
* @param noHostVerification
* flag
*/
public ConnectionsPoolBuilder noHostVerification(Boolean noHostVerification) {
if (noHostVerification != null) {
this.noHostVerification = noHostVerification.booleanValue();
}
return this;
}
/**
* Creates DefaultHttpClient
*
* @param url
* @param username
* @param password
* @param key_file
* @param cert_file
* @param ca_file
* @param port
* @param requestTimeout
*
* @return {@link DefaultHttpClient}
*/
private DefaultHttpClient createDefaultHttpClient(String url, String username, String password, String key_file,
String cert_file, String ca_file, Integer port, Integer requestTimeout) {
int port_ = getPort(url, port);
DefaultHttpClient client =
new DefaultHttpClient(createPoolingClientConnectionManager(url, port_));
if (requestTimeout != null && requestTimeout.intValue() != -1) {
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, requestTimeout.intValue());
DefaultHttpClient.setDefaultHttpParams(httpParams);
}
if (!StringUtils.isNulOrEmpty(username))
client.getCredentialsProvider().setCredentials(
new AuthScope(getHost(url), port_),
new UsernamePasswordCredentials(username, password));
// FIXME: use all .ctr params
return client;
}
/**
* Creates PoolingClientConnectionManager
*
* @param url
* @param port
*
* @return {@link ClientConnectionManager}
*/
private ClientConnectionManager createPoolingClientConnectionManager(String url, int port) {
SchemeRegistry schemeRegistry = createSchemeRegistry(url, port);
PoolingClientConnectionManager cm =
new PoolingClientConnectionManager(schemeRegistry);
cm.setMaxTotal(MAX_CONNECTIONS);
cm.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE);
cm.setMaxPerRoute(new HttpRoute(new HttpHost(getHost(url),
getPort(url, port))),
MAX_CONNECTIONS_PER_HOST);
return cm;
}
/**
* Creates SchemeRegistry
*
* @param url
* @param port
*
* @return {@link SchemeRegistry}
*/
private SchemeRegistry createSchemeRegistry(String url, int port) {
SchemeRegistry schemeRegistry = new SchemeRegistry();
String protocol = getProtocol(url);
SSLSocketFactory sf;
if (HTTP_PROTOCOL.equals(protocol)) {
schemeRegistry.register(
new Scheme(HTTP_PROTOCOL,
port,
PlainSocketFactory.getSocketFactory()));
} else if (HTTPS_PROTOCOL.equals(protocol)) {
try {
if (this.noHostVerification) {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { noCaTrustManager }, null);
sf = new SSLSocketFactory(
sslcontext,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} else {
KeyStore truststore = null;
InputStream in = null;
if (this.keyStorePath != null) {
truststore = KeyStore.getInstance(KeyStore.getDefaultType());
try {
in = new FileInputStream(this.keyStorePath);
truststore.load(
in,
this.keyStorePassword != null ?
this.keyStorePassword.toCharArray()
:
null);
} finally {
if (in != null) {
in.close();
}
}
}
sf = new SSLSocketFactory(SSLSocketFactory.TLS,
null,
null,
truststore,
null,
null,
SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
}
schemeRegistry.register(
new Scheme(HTTPS_PROTOCOL, port, sf));
} catch (NoSuchAlgorithmException e) {
throw new SocketFactoryException(NO_TLS_ERROR, e);
} catch (KeyManagementException e) {
throw new SocketFactoryException(BAD_KEY_ERROR, e);
} catch (KeyStoreException e) {
throw new SocketFactoryException(KEY_STORE_ERROR, e);
} catch (FileNotFoundException e) {
throw new SocketFactoryException(KEY_STORE_FILE_NOT_FOUND_ERROR, e);
} catch (CertificateException e) {
throw new SocketFactoryException(CERTEFICATE_ERROR, e);
} catch (IOException e) {
throw new SocketFactoryException(IO_ERROR, e);
} catch (UnrecoverableKeyException e) {
throw new SocketFactoryException(UNRECOVERABLE_KEY_ERROR, e);
}
} else {
throw new ProtocolException(BAD_PROTOCOL_ERROR + protocol);
}
return schemeRegistry;
}
private int getPort(String url, Integer port) {
return port == null || port == -1 ? this.urlobj.getPort() : port;
}
private String getHost(String url) {
return this.urlobj.getHost();
}
private String getProtocol(String url) {
return this.urlobj.getProtocol();
}
/**
* @return entry point URI
*/
public String getUrl() {
return this.url.toString();
}
private URL createURL(String url) throws MalformedURLException {
return new URL(url);
}
/**
* Builds ConnectionPool
*
* @return ConnectionsPool
*/
public ConnectionsPool build() {
this.keyStorePath = resolveKeyStorePath();
return new ConnectionsPool(
createDefaultHttpClient(url,
username,
password,
key_file,
cert_file,
ca_file,
port,
requestTimeout
),
this.urlobj,
this.sessionTimeout,
WAIT_IDLE_CHECK_TTL,
WAIT_IDLE_CLOSE_TTL);
}
/**
* Trying to resolve keyStorePath if it's not defined
* according to the DEFAULT_KEYSTORE_TRUSTSTORE
*
* on NX environment it may look like:
* /home/mpastern/.ovirtsdk/ovirtsdk-keystore.truststore
*
* @return keyStorePath or original this.keyStorePath content
*/
private String resolveKeyStorePath() {
if (this.keyStorePath == null) {
String keyStorePathCandidate =
System.getProperty("user.home") +
File.separator + ".ovirtsdk" +
File.separator + DEFAULT_KEYSTORE_TRUSTSTORE;
try {
if (new File(keyStorePathCandidate).exists()) {
return keyStorePathCandidate;
}
} catch (SecurityException ex) {
ex.printStackTrace();
// TODO: log error when exposed logger
}
}
return this.keyStorePath;
}
/**
* This TrustManager used to ignore CA cert validation
* and should not be used unless user explicitly asks to ignore
* host identity validation.
*/
X509TrustManager noCaTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
// do nothing
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws java.security.cert.CertificateException {
// do nothing
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
}