org.hpccsystems.ws.client.utils.Connection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wsclient Show documentation
Show all versions of wsclient Show documentation
This project allows a user to interact with ESP services in a controlled manner. The API calls available under org.hpccsystems.ws.client.platform allow for a user to target ESP's across multiple environments running a range of hpccsystems-platform versions. There is no guarantee that if a user utilizes org.hpccsystems.ws.client.gen generated stub code from wsdl, that the calls will be backwards compatible with older hpccsystems-platform versions.
package org.hpccsystems.ws.client.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Represents and structures connection information.
*
* Facilitates HPCC connectivity, provides several convenience methods such as credential encoding,
* connection URL parsing, and others.
*/
public class Connection
{
private class Credentials
{
private String userName = null;
private String password = null;
private boolean isPopulated = false;
/**
* Checks if is populated.
*
* @return true, if is populated
*/
public boolean isPopulated()
{
return isPopulated;
}
/**
* Gets the user name.
*
* @return the user name
*/
public String getUserName()
{
return userName;
}
/**
* Sets the user name.
*
* @param username
* the new user name
*/
public void setUserName(String username)
{
if (username != null && username.length() > 0)
{
this.userName = username;
if (password != null)
isPopulated = true;
else
isPopulated = false;
}
}
/**
* Gets the password.
*
* @return the password
*/
public String getPassword()
{
return password;
}
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(String password)
{
if (password != null)
{
this.password = password;
if (userName != null && userName.length() > 0)
isPopulated = true;
else
isPopulated = false;
}
}
/**
* Gets the encoded creds.
*
* @return the encoded creds
*/
public String getEncodedCreds()
{
if (!isPopulated)
return null;
else
{
Encoder encoder = Base64.getEncoder();
return new String(encoder.encode((userName + ":" + password).getBytes()));
}
}
/**
* Sets the encoded creds.
*
* @param encodedCreds
* the new encoded creds
* @throws Exception
* the exception
*/
public void setEncodedCreds(String encodedCreds) throws Exception
{
if (encodedCreds != null && encodedCreds.length() > 0)
{
this.password = null;
this.userName = null;
Decoder decoder = Base64.getDecoder();
String credstring = new String(decoder.decode(encodedCreds));
String[] creds = credstring.split(":");
if (creds.length != 2)
throw new Exception("Invalid credentials: Should be base64-encoded :");
this.userName = creds[0];
this.password = creds[1];
isPopulated = true;
}
}
/**
* Sets the credentials.
*
* @param username
* the username
* @param password
* the password
*/
public void setCredentials(String username, String password)
{
if (username != null && username.length() > 0 && password != null)
{
this.userName = username;
this.password = password;
isPopulated = true;
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
int result = HashCodeUtil.SEED;
result = HashCodeUtil.hash(result, getProtocol());
result = HashCodeUtil.hash(result, getHost());
result = HashCodeUtil.hash(result, getPortInt());
result = HashCodeUtil.hash(result, getUserName());
result = HashCodeUtil.hash(result, getPassword());
return result;
}
}
private final static Logger log = LogManager.getLogger(Connection.class);
/** Constant protDelimiter="://"
*/
public final static String protDelimiter = "://";
/** Constant portDelimiter=':'
*/
public final static char portDelimiter = ':';
/** Constant pathDelimiter='/'
*/
public final static char pathDelimiter = '/';
/** Constant firstOptDelimiter='?'
*/
public final static char firstOptDelimiter = '?';
/** Constant subsequentOptDelimiter='&'
*/
public final static char subsequentOptDelimiter = '&';
/** Constant protHttp="http"
*/
public final static String protHttp = "http";
/** Constant protHttps="https"
*/
public final static String protHttps = "https";
private String protocol;
private String host;
private String port;
private String path;
private String[] options;
private Credentials credentials = null;
private boolean isHttps = false;
private boolean allowInvalidCerts = false;
private StringBuffer baseUrl;
private StringBuffer uriAndParams;
/** Constant CONNECT_TIMEOUT_PARAM="connecttimeoutmillis"
*/
final static public String CONNECT_TIMEOUT_PARAM = "connecttimeoutmillis";
/** Constant READ_TIMEOUT_PARAM="readtimeoutmillis"
*/
final static public String READ_TIMEOUT_PARAM = "readtimeoutmillis";
/** Constant WRITE_TIMEOUT_PARAM="writetimeoutmillis"
*/
final static public String WRITE_TIMEOUT_PARAM = "writetimeoutmillis";
/** Constant SOCKET_TIMEOUT_PARAM="sockettimeoutmillis"
*/
final static public String SOCKET_TIMEOUT_PARAM = "sockettimeoutmillis";
/** Constant DEFAULT_CONNECT_TIMEOUT_MILLI=150000
*/
final static public int DEFAULT_CONNECT_TIMEOUT_MILLI = 150000;
/** Constant DEFAULT_SO_TIMEOUT_MILLI=150000
*/
final static public int DEFAULT_SO_TIMEOUT_MILLI = 150000;
/** Constant DEFAULT_WRITE_TIMEOUT_MILLI=150000
*/
final static public int DEFAULT_WRITE_TIMEOUT_MILLI = 150000;
/** Constant DEFAULT_READ_TIMEOUT_MILLI=180 * 1000
*/
final static public int DEFAULT_READ_TIMEOUT_MILLI = 180 * 1000;
final static boolean DEFAULT_MAINTAIN_SESSION = true;
protected int connectTimeoutMilli = DEFAULT_CONNECT_TIMEOUT_MILLI;
protected int readTimeoutMilli = DEFAULT_READ_TIMEOUT_MILLI;
protected int writeTimeoutMilli = DEFAULT_WRITE_TIMEOUT_MILLI;
protected int socketTimeoutMilli = DEFAULT_SO_TIMEOUT_MILLI;
private boolean preemptiveHTTPAuthenticate = true;
/**
* Sets option to pre-emptively process HTTP authentication
*
* @param preemtiveauth
* Flag determining if pre-emptive HTTP authentication should be processed before connection is challenged
*/
public void setPreemptiveHTTPAuthenticate(boolean preemtiveauth)
{
preemptiveHTTPAuthenticate = preemtiveauth;
}
/**
* Returns option to pre-emptively process HTTP Authentication
* @return
* Flag determining if pre-emptive HTTP authentication should be processed before connection is challenged
*/
public boolean getPreemptiveHTTPAuthenticate()
{
return preemptiveHTTPAuthenticate;
}
/**
* Gets the protocol.
*
* @param ssl
* the ssl
* @return the protocol
*/
public static String getProtocol(boolean ssl)
{
return ssl ? protHttps : protHttp;
}
/**
* Checks if is ssl protocol.
*
* @param protocol
* the protocol
* @return true, if is ssl protocol
*/
public static boolean isSslProtocol(String protocol)
{
return protHttps.equalsIgnoreCase(protocol);
}
/**
* Instantiates a new connection.
*
* @param connectionstring
* as defined by java.net.URL
* @throws java.net.MalformedURLException
* the malformed URL exception
*/
public Connection(String connectionstring) throws MalformedURLException
{
URL theurl = new URL(connectionstring);
setProtocol(theurl.getProtocol());
host = theurl.getHost();
if (theurl.getPort() < 0) throw new MalformedURLException("Invalid port encountered: '" + theurl.getPort() + "'");
setPort(Integer.toString(theurl.getPort()));
setURIPath(theurl.getPath());
options = null;
if (theurl.getQuery() != null)
{
options = theurl.getQuery().split("&");
processOptions();
}
constructUrl();
credentials = new Credentials();
}
/**
* Instantiates a new connection.
*
* @param ssl
* the ssl
* @param host
* the host
* @param port
* the port
*/
public Connection(boolean ssl, String host, int port)
{
this(getProtocol(ssl), host, String.valueOf(port), null, null);
}
/**
* Instantiates a new connection.
*
* @param protocol
* the protocol
* @param host
* the host
* @param port
* the port
*/
public Connection(String protocol, String host, String port)
{
this(protocol, host, port, null, null);
}
/**
* Instantiates a new connection.
*
* @param protocol
* the protocol
* @param host
* the host
* @param port
* the port
* @param path
* the path
*/
public Connection(String protocol, String host, String port, String path)
{
this(protocol, host, port, path, null);
}
/**
* Instantiates a new connection.
*
* @param protocol_
* the protocol
* @param host_
* the host
* @param port_
* the port
* @param path_
* the path
* @param options_
* the options
*/
public Connection(String protocol_, String host_, String port_, String path_, String[] options_)
{
setProtocol(protocol_);
host = host_;
setPort(port_);
setURIPath(path_);
options = options_;
processOptions();
constructUrl();
credentials = new Credentials();
}
/**
* Process options.
*/
private void processOptions()
{
if (options != null && options.length != 0) // look for some known options, mainly timeouts
{
for (int i = 0; i < options.length; i++)
{
String[] kvoptions = options[i].split("=");
if (kvoptions.length == 2)
{
if (kvoptions[0].equalsIgnoreCase(CONNECT_TIMEOUT_PARAM))
connectTimeoutMilli = Integer.valueOf(kvoptions[1]);
else if (kvoptions[0].equalsIgnoreCase(READ_TIMEOUT_PARAM))
readTimeoutMilli = Integer.valueOf(kvoptions[1]);
else if (kvoptions[0].equalsIgnoreCase(WRITE_TIMEOUT_PARAM))
writeTimeoutMilli = Integer.valueOf(kvoptions[1]);
else if (kvoptions[0].equalsIgnoreCase(SOCKET_TIMEOUT_PARAM)) socketTimeoutMilli = Integer.valueOf(kvoptions[1]);
}
}
}
}
private void setHTTPProtocol(boolean https)
{
if (https)
{
isHttps = true;
protocol = protHttps;
}
else
{
isHttps = false;
protocol = protHttp;
}
}
/**
* Sets the protocol. If invalid protocol detected, defaults to http
*
* @param protocol_
* the new protocol ("http" || "https")
*/
private void setProtocol(String protocol_)
{
if (protocol_ != null && protocol_.length() > 0)
{
if (protocol_.equalsIgnoreCase(protHttps))
{
setHTTPProtocol(true);
return;
}
}
setHTTPProtocol(false);
}
/**
* Sets the port.
*
* @param port_
* the new port
*/
private void setPort(String port_)
{
if (port_ != null && port_.length() > 0)
port = port_;
else
port = "";
}
/**
* Sets the URI path.
*
* @param path
* the new URI path
*/
private void setURIPath(String path)
{
if (path != null && path.length() > 0)
{
if (path.charAt(0) == pathDelimiter)
this.path = path;
else
this.path = pathDelimiter + path;
}
else
this.path = "";
}
/**
* Construct url.
*/
private void constructUrl()
{
baseUrl = new StringBuffer();
baseUrl.append(protocol).append(protDelimiter);
baseUrl.append(host);
baseUrl.append(port.length() > 0 ? portDelimiter + port : "");
uriAndParams = new StringBuffer();
uriAndParams.append(path);
if (options != null)
{
for (int i = 0; i < options.length; i++)
{
if (i == 0)
uriAndParams.append(firstOptDelimiter);
else
uriAndParams.append(subsequentOptDelimiter);
try
{
uriAndParams.append(URLEncoder.encode(options[i], "UTF-8"));
}
catch (UnsupportedEncodingException e)
{
log.warn("Warning: could not encode URL option: " + options[i]);
uriAndParams.append(options[i]);
}
}
}
}
/**
* Gets the url.
*
* @return the url
*/
public String getUrl()
{
return baseUrl.toString() + uriAndParams.toString();
}
/**
* Gets the base url.
*
* @return the base url
*/
public String getBaseUrl()
{
return baseUrl.toString();
}
/**
* Checks for credentials.
*
* @return true, if successful
*/
public boolean hasCredentials()
{
return credentials.isPopulated();
}
/**
* Sets the encoded credentials.
*
* @param encodedcreds
* the new encoded credentials
* @throws java.lang.Exception
* the exception
*/
public void setEncodedCredentials(String encodedcreds) throws Exception
{
synchronized (credentials)
{
credentials.setEncodedCreds(encodedcreds);
}
}
/**
* Gets the basic auth string.
*
* @return String - "Basic " + encoded credentials, null if no credentials set
*/
public String getBasicAuthString()
{
if (!credentials.isPopulated) return null;
synchronized (credentials)
{
return "Basic " + credentials.getEncodedCreds();
}
}
/**
* Gets the host.
*
* @return the host
*/
public String getHost()
{
return this.host;
}
/**
* Gets the port.
*
* @return the port
*/
public String getPort()
{
return this.port;
}
/**
* Gets the port int.
*
* @return the port int
*/
public int getPortInt()
{
if (port != null && !port.isEmpty())
return Integer.valueOf(port);
else
return -1;
}
/**
* Gets the user name.
*
* @return the user name
*/
public String getUserName()
{
synchronized (credentials)
{
return credentials.getUserName();
}
}
/**
* Sets the user name.
*
* @param userName
* the new user name
*/
public void setUserName(String userName)
{
synchronized (credentials)
{
credentials.setUserName(userName);
}
}
/**
* Gets the password.
*
* @return the password
*/
public String getPassword()
{
synchronized (credentials)
{
return credentials.getPassword();
}
}
/**
* Sets the password.
*
* @param password
* the new password
*/
public void setPassword(String password)
{
synchronized (credentials)
{
credentials.setPassword(password);
}
}
/**
* Gets the protocol.
*
* @return the protocol
*/
public String getProtocol()
{
return protocol;
}
/**
* Gets the checks if is https.
*
* @return the checks if is https
*/
public Boolean getIsHttps()
{
return isHttps;
}
/**
* Gets the allow invalid certs.
*
* @return the allow invalid certs
*/
public boolean getAllowInvalidCerts()
{
return allowInvalidCerts;
}
/**
* Sets the allow invalid certs.
*
* @param allowInvalidCerts
* the new allow invalid certs
*/
public void setAllowInvalidCerts(boolean allowInvalidCerts)
{
this.allowInvalidCerts = allowInvalidCerts;
}
/**
* Sets the credentials.
*
* @param username
* the username
* @param password
* the password
*/
public void setCredentials(String username, String password)
{
synchronized (credentials)
{
credentials.setCredentials(username, password);
}
}
/**
* Gets the credentials.
*
* @return the credentials
*/
public Credentials getCredentials()
{
synchronized (credentials)
{
return credentials;
}
}
/**
* Creates the connection.
*
* @return the URL connection
* @throws java.io.IOException
* Signals that an I/O exception has occurred.
*/
public URLConnection createConnection() throws java.io.IOException
{
return createConnection(new URL(baseUrl.toString()));
}
/**
* Creates a new java.net.URLConnection
object from the
* specified java.net.URL
. This is a convenience method which
* will set the doInput
, doOutput
,
* useCaches
and defaultUseCaches
fields to the
* appropriate settings in the correct order.
*
* @param url
* the url
* @return the URL connection
* @throws java.io.IOException
* Signals that an I/O exception has occurred.
*/
public static URLConnection createConnection(URL url) throws java.io.IOException
{
URLConnection urlConn = url.openConnection();
if (urlConn instanceof HttpURLConnection)
{
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.setRequestMethod("POST");
HttpURLConnection.setFollowRedirects(false);
}
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
urlConn.setDefaultUseCaches(false);
urlConn.setRequestProperty("Connection", "Keep-Alive");
urlConn.setRequestProperty("DNT", "1");
urlConn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
urlConn.setRequestProperty("ENCTYPE", "multipart/form-data");
urlConn.setAllowUserInteraction(false);
return urlConn;
}
/**
* Builds the url.
*
* @param protocol
* the protocol
* @param host
* the host
* @param port
* the port
* @return the string
*/
static public String buildUrl(String protocol, String host, String port)
{
return buildUrl(protocol, host, port, null, null);
}
/**
* Builds the url.
*
* @param protocol
* the protocol
* @param host
* the host
* @param port
* the port
* @param path
* the path
* @return the string
*/
static public String buildUrl(String protocol, String host, String port, String path)
{
return buildUrl(protocol, host, port, path, null);
}
/**
* Builds the url.
*
* @param protocol
* the protocol
* @param host
* the host
* @param port
* the port
* @param path
* the path
* @param options
* the options
* @return the string
*/
static public String buildUrl(String protocol, String host, String port, String path, String[] options)
{
StringBuffer url = new StringBuffer();
url.append((protocol != null && protocol.length() > 0) ? protocol : protHttp).append(protDelimiter);
url.append(host);
url.append((port != null && port.length() > 0) ? portDelimiter + port : "");
url.append((path != null && path.length() > 0) ? (path.charAt(0) == pathDelimiter) ? path : pathDelimiter + path : "");
if (options != null)
{
for (int i = 0; i < options.length; i++)
{
if (i == 0)
url.append(firstOptDelimiter);
else
url.append(subsequentOptDelimiter);
try
{
url.append(URLEncoder.encode(options[i], "UTF-8"));
}
catch (UnsupportedEncodingException e)
{
log.warn("Warning: could not encode URL option: " + options[i]);
url.append(options[i]);
}
}
}
return url.toString();
}
/**
* Gets the connect timeout milli.
*
* @return the connectTimeoutMilli
*/
public int getConnectTimeoutMilli()
{
return connectTimeoutMilli;
}
/**
* Sets the connect timeout milli.
*
* @param connectTimeoutMilli
* the connectTimeoutMilli to set
*/
public void setConnectTimeoutMilli(int connectTimeoutMilli)
{
this.connectTimeoutMilli = connectTimeoutMilli;
}
/**
* Gets the read timeout milli.
*
* @return the readTimeoutMilli
*/
public int getReadTimeoutMilli()
{
return readTimeoutMilli;
}
/**
* Sets the read timeout milli.
*
* @param readTimeoutMilli
* the readTimeoutMilli to set
*/
public void setReadTimeoutMilli(int readTimeoutMilli)
{
this.readTimeoutMilli = readTimeoutMilli;
}
/**
* Gets the write timeout milli.
*
* @return the writeTimeoutMilli
*/
public int getWriteTimeoutMilli()
{
return writeTimeoutMilli;
}
/**
* Sets the write timeout milli.
*
* @param writeTimeoutMilli
* the writeTimeoutMilli to set
*/
public void setWriteTimeoutMilli(int writeTimeoutMilli)
{
this.writeTimeoutMilli = writeTimeoutMilli;
}
/**
* Gets the socket timeout milli.
*
* @return the socketTimeoutMilli
*/
public int getSocketTimeoutMilli()
{
return socketTimeoutMilli;
}
/**
* Sets the socket timeout milli.
*
* @param socketTimeoutMilli
* the socketTimeoutMilli to set
*/
public void setSocketTimeoutMilli(int socketTimeoutMilli)
{
this.socketTimeoutMilli = socketTimeoutMilli;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
/** {@inheritDoc} */
@Override
public String toString()
{
return buildUrl(protocol, host, port, path, options);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
/** {@inheritDoc} */
@Override
public boolean equals(Object aThat)
{
if (this == aThat)
{
return true;
}
if (!(aThat instanceof Connection))
{
return false;
}
Connection that = (Connection) aThat;
return EqualsUtil.areEqual(getUrl(), that.getUrl()) && EqualsUtil.areEqual(credentials, that.getCredentials());
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
/** {@inheritDoc} */
@Override
public int hashCode()
{
int result = HashCodeUtil.SEED;
result = HashCodeUtil.hash(result, getUrl());
result = HashCodeUtil.hash(result, credentials);
return result;
}
/**
* Sends HTTP Get request to connection's URL + uri
* Returns entire response payload
*
* @param uri - Appended to connection URL
* @throws Exception a {@link java.lang.Exception} object.
* @return a {@link java.lang.String} object.
*/
public String sendGetRequest(String uri) throws Exception
{
return sendHTTPRequest(uri, "GET");
}
/**
* Sends HTTP request to connection's URL + uri
* Caller specifies the desired HTTP method
*
* Returns entire response payload
*
* @param uri a {@link java.lang.String} object.
* @param method - One of GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE
* @throws Exception a {@link java.lang.Exception} object.
* @return a {@link java.lang.String} object.
*/
public String sendHTTPRequest(String uri, String method) throws Exception
{
if (method == null || method.isEmpty())
throw new Exception ("Must provide valid HTTP method");
URL url = new URL (getBaseUrl() + (uri != null && uri.startsWith("/") ? "" : "/") + uri);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); //throws IOException
Connection.log.info("Sending HTTP " + method + "Request to:" + url.toString());
if (hasCredentials())
{
httpURLConnection.setRequestProperty("Authorization", getBasicAuthString());
}
httpURLConnection.setRequestMethod(method); //throws ProtocolException
int responseCode = httpURLConnection.getResponseCode(); //throws IOException
Connection.log.info("HTTP Response code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) //success
{
BufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); //throws IOException
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) // throws IOException
{
response.append(inputLine);
}
in.close(); //throws IOException
return response.toString();
}
else
{
throw new IOException("HTTP request failed! Code (" + responseCode + ") " + httpURLConnection.getResponseMessage() );
}
}
}