
Invokers.ApiClient Maven / Gradle / Ivy
/*
* CyberSource Flex API
* Simple PAN tokenization service
*
* OpenAPI spec version: 0.0.1
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
package Invokers;
import java.io.*;
import java.lang.reflect.Type;
import java.net.HttpRetryException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.*;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import okhttp3.Authenticator;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ConnectionPool;
import okhttp3.Credentials;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.Route;
import okhttp3.internal.http.HttpMethod;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.logging.HttpLoggingInterceptor.Level;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.cybersource.authsdk.core.Authorization;
import com.cybersource.authsdk.core.ConfigException;
import com.cybersource.authsdk.core.MerchantConfig;
import com.cybersource.authsdk.payloaddigest.PayloadDigest;
import com.cybersource.authsdk.util.GlobalLabelParameters;
import com.cybersource.authsdk.util.PrettyPrintingMap;
import com.cybersource.authsdk.util.PropertiesUtil;
import Invokers.auth.ApiKeyAuth;
import Invokers.auth.Authentication;
import Invokers.auth.HttpBasicAuth;
import Invokers.auth.OAuth;
import utilities.interceptors.RetryInterceptor;
import utilities.listeners.NetworkEventListener;
import utilities.telemetry.RequestTransactionMetrics;
public class ApiClient {
public static final double JAVA_VERSION;
public static final boolean IS_ANDROID;
public static final int ANDROID_SDK_VERSION;
static {
JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version"));
boolean isAndroid;
try {
Class.forName("android.app.Activity");
isAndroid = true;
} catch (ClassNotFoundException e) {
isAndroid = false;
}
IS_ANDROID = isAndroid;
int sdkVersion = 0;
if (IS_ANDROID) {
try {
sdkVersion = Class.forName("android.os.Build$VERSION").getField("SDK_INT").getInt(null);
} catch (Exception e) {
try {
sdkVersion = Integer
.parseInt((String) Class.forName("android.os.Build$VERSION").getField("SDK").get(null));
} catch (Exception e2) {
}
}
}
ANDROID_SDK_VERSION = sdkVersion;
}
private String basePath = "";
private boolean lenientOnJson = false;
private boolean debugging = false;
private Map defaultHeaderMap = new HashMap();
private String tempFolderPath = null;
private Map authentications;
private DateFormat dateFormat;
private DateFormat datetimeFormat;
private boolean lenientDatetimeFormat;
private int dateLength;
private InputStream sslCaCert;
private boolean verifyingSsl;
private KeyManager[] keyManagers;
private String acceptHeader = "";
private static OkHttpClient httpClient;
private final OkHttpClient classHttpClient = initializeFinalVariables();
private JSON json;
private String versionInfo;
private static ConnectionPool connectionPool = new ConnectionPool(5, 10, TimeUnit.SECONDS);
private HttpLoggingInterceptor loggingInterceptor;
private long computationStartTime;
private static Logger logger = LogManager.getLogger(ApiClient.class);
/**
* The datetime format to be used when lenientDatetimeFormat
is
* enabled.
*/
public static final String LENIENT_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
/**
* Use this field ONLY IF you have more than one instance of ApiClient.
* This field should NOT be used/accessed for a singleton object.
*/
public String responseCode;
/**
* Use this field ONLY IF you have more than one instance of ApiClient.
* This field should NOT be used/accessed for a singleton object.
*/
public String status;
public MerchantConfig merchantConfig;
public RequestTransactionMetrics apiRequestMetrics = new RequestTransactionMetrics();
public static OkHttpClient initializeFinalVariables() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.NONE);
// connectionPool = new ConnectionPool(5, 10, TimeUnit.SECONDS);
try {
return new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.connectionPool(ApiClient.connectionPool)
.addInterceptor(logging)
.build();
}
catch (Exception ex)
{
logger.error("Error in creating HTTP Client");
return null;
}
}
/*
* Constructor for ApiClient
*/
public ApiClient() {
versionInfo = getClientID();
try {
httpClient = classHttpClient.newBuilder()
.retryOnConnectionFailure(true)
.addInterceptor(new RetryInterceptor(this.apiRequestMetrics))
.eventListener(new NetworkEventListener(this.getNewRandomId(), System.nanoTime()))
.build();
}
catch (Exception ex)
{
logger.error("Error in creating HTTP Client");
}
verifyingSsl = true;
json = new JSON(this);
/*
* Use RFC3339 format for date and datetime. See
* http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14
*/
this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
initDatetimeFormat();
// Be lenient on datetime formats when parsing datetime from string.
// See parseDatetime
.
this.lenientDatetimeFormat = true;
// Set default User-Agent.
setUserAgent("Swagger-Codegen/1.0.0/java");
authentications = new HashMap();
authentications = Collections.unmodifiableMap(authentications);
}
private String getClientID() {
String propertyVersionInfo = null;
final Properties properties = new Properties();
try {
properties.load(
this.getClass().getClassLoader().getResourceAsStream("cybersource-rest-client-java.properties"));
propertyVersionInfo = properties.getProperty("sdk.version");
} catch (IOException e) {
}
return propertyVersionInfo;
}
public ApiClient(MerchantConfig merchantConfig) {
this();
final boolean useProxy = merchantConfig.isUseProxyEnabled();
final String username = merchantConfig.getProxyUser();
final String password = merchantConfig.getProxyPassword();
int proxyPort = merchantConfig.getProxyPort();
String proxyHost = merchantConfig.getProxyAddress();
// User Defined Timeout for HTTP Client
int connectionTimeout = Math.max(merchantConfig.getUserDefinedConnectionTimeout(), 1);
int readTimeout = Math.max(merchantConfig.getUserDefinedReadTimeout(), 60);
int writeTimeout = Math.max(merchantConfig.getUserDefinedWriteTimeout(), 60);
int keepAliveDuration = Math.max(merchantConfig.getUserDefinedKeepAliveDuration(), 10);
connectionPool = new ConnectionPool(5, keepAliveDuration, TimeUnit.SECONDS);
Authenticator proxyAuthenticator;
if (useProxy && (proxyHost != null && !proxyHost.isEmpty())) {
if ((username != null && !username.isEmpty()) && (password != null && !password.isEmpty())) {
proxyAuthenticator = new Authenticator() {
// private int proxyCounter = 0;
@Override
public Request authenticate(Route route, Response response) throws IOException {
// if (proxyCounter++ > 0) {
// if (response.code() == 407) {
// logger.error("HttpRetryException : 407 Proxy Authentication Missing or Incorrect");
// throw new HttpRetryException("Proxy Authentication Missing or Incorrect.", 407);
// } else {
// logger.error("IOException : " + response.message());
// throw new IOException(response.message());
// }
// }
String credential = Credentials.basic(username, password);
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
}
};
} else {
proxyAuthenticator = new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
return response.request().newBuilder().build();
}
};
}
try {
httpClient = classHttpClient.newBuilder()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(connectionTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new RetryInterceptor(this.apiRequestMetrics))
.connectionPool(ApiClient.connectionPool)
.eventListener(new NetworkEventListener(this.getNewRandomId(), System.nanoTime()))
.build();
}
catch (Exception ex)
{
logger.error("Error in creating HTTP Client");
}
this.setHttpClient(httpClient);
}
else
{
// override the custom timeout in HTTPClient
try {
httpClient = classHttpClient.newBuilder()
.connectTimeout(connectionTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.connectionPool(ApiClient.connectionPool)
.retryOnConnectionFailure(true)
.addInterceptor(new RetryInterceptor(this.apiRequestMetrics))
.eventListener(new NetworkEventListener(this.getNewRandomId(), System.nanoTime()))
.build();
}
catch (Exception ex)
{
logger.error("Error in creating HTTP Client");
}
this.setHttpClient(httpClient);
}
this.merchantConfig = merchantConfig;
// RetryInterceptor.retryDelay = merchantConfig.getRetryDelay();
// RetryInterceptor.retryEnabled = merchantConfig.isRetryEnabled();
}
/**
* Get base path
*
* @return Baes path
*/
public String getBasePath() {
return basePath;
}
/**
* @param acceptHeader the acceptHeader to set
*/
public void setAcceptHeader(String acceptHeader) {
this.acceptHeader = acceptHeader;
}
/**
* Set base path
*
* @param basePath Base path of the URL (e.g https://apitest.cybersource.com)
* @return An instance of OkHttpClient
*/
public ApiClient setBasePath(String basePath) {
this.basePath = this.basePath.concat(merchantConfig.getRequestHost().trim());
return this;
}
/**
* Get HTTP client
*
* @return An instance of OkHttpClient
*/
public OkHttpClient getHttpClient() {
return httpClient;
}
/**
* Set HTTP client
*
* @param httpClient An instance of OkHttpClient
* @return Api Client
*/
public ApiClient setHttpClient(OkHttpClient httpClient) {
ApiClient.httpClient = httpClient;
return this;
}
/**
* Get JSON
*
* @return JSON object
*/
public JSON getJSON() {
return json;
}
/**
* Set JSON
*
* @param json JSON object
* @return Api client
*/
public ApiClient setJSON(JSON json) {
this.json = json;
return this;
}
/**
* True if isVerifyingSsl flag is on
*
* @return True if isVerifySsl flag is on
*/
public boolean isVerifyingSsl() {
return verifyingSsl;
}
/**
* Configure whether to verify certificate and hostname when making https
* requests. Default to true. NOTE: Do NOT set to false in production code,
* otherwise you would face multiple types of cryptographic attacks.
*
* @param verifyingSsl True to verify TLS/SSL connection
* @return ApiClient
*/
public ApiClient setVerifyingSsl(boolean verifyingSsl) {
this.verifyingSsl = verifyingSsl;
applySslSettings();
return this;
}
/**
* Get SSL CA cert.
*
* @return Input stream to the SSL CA cert
*/
public InputStream getSslCaCert() {
return sslCaCert;
}
/**
* Configure the CA certificate to be trusted when making https requests. Use
* null to reset to default.
*
* @param sslCaCert input stream for SSL CA cert
* @return ApiClient
*/
public ApiClient setSslCaCert(InputStream sslCaCert) {
this.sslCaCert = sslCaCert;
applySslSettings();
return this;
}
public KeyManager[] getKeyManagers() {
return keyManagers;
}
/**
* Configure client keys to use for authorization in an SSL session. Use null to
* reset to default.
*
* @param managers The KeyManagers to use
* @return ApiClient
*/
public ApiClient setKeyManagers(KeyManager[] managers) {
this.keyManagers = managers;
applySslSettings();
return this;
}
public DateFormat getDateFormat() {
return dateFormat;
}
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
this.dateLength = this.dateFormat.format(new Date()).length();
return this;
}
public DateFormat getDatetimeFormat() {
return datetimeFormat;
}
public ApiClient setDatetimeFormat(DateFormat datetimeFormat) {
this.datetimeFormat = datetimeFormat;
return this;
}
/**
* Whether to allow various ISO 8601 datetime formats when parsing a datetime
* string.
*
* @see #parseDatetime(String)
* @return True if lenientDatetimeFormat flag is set to true
*/
public boolean isLenientDatetimeFormat() {
return lenientDatetimeFormat;
}
public ApiClient setLenientDatetimeFormat(boolean lenientDatetimeFormat) {
this.lenientDatetimeFormat = lenientDatetimeFormat;
return this;
}
/**
* Parse the given date string into Date object. The default
* dateFormat
supports these ISO 8601 date formats: 2015-08-16
* 2015-8-16
*
* @param str String to be parsed
* @return Date
*/
public Date parseDate(String str) {
if (str == null)
return null;
try {
return dateFormat.parse(str);
} catch (ParseException e) {
logger.error("RuntimeException : " + e);
throw new RuntimeException(e);
}
}
/**
* Parse the given datetime string into Date object.
*
* When lenientDatetimeFormat is enabled, the following ISO 8601 datetime
* formats are supported:
*
* - 2015-08-16T08:20:05Z
* - 2015-8-16T8:20:05Z
* - 2015-08-16T08:20:05+00:00
* - 2015-08-16T08:20:05+0000
* - 2015-08-16T08:20:05.376Z
* - 2015-08-16T08:20:05.376+00:00
* - 2015-08-16T08:20:05.376+00
*
*
* Note: The 3-digit milli-seconds is optional.
*
* Time zone is required and can be in one of these formats:
*
* - Z (same with +0000)
* - +08:00 (same with +0800)
* - -02 (same with -0200)
*
*
* @see ISO 8601
* @param str Date time string to be parsed
* @return Date representation of the string
*/
public Date parseDatetime(String str) {
if (str == null)
return null;
DateFormat format;
if (lenientDatetimeFormat) {
/*
* When lenientDatetimeFormat is enabled, normalize the date string into
* LENIENT_DATETIME_FORMAT
to support various formats defined by
* ISO 8601.
*/
// normalize time zone
// trailing "Z": 2015-08-16T08:20:05Z => 2015-08-16T08:20:05+0000
str = str.replaceAll("[zZ]\\z", "+0000");
// remove colon in time zone: 2015-08-16T08:20:05+00:00 =>
// 2015-08-16T08:20:05+0000
str = str.replaceAll("([+-]\\d{2}):(\\d{2})\\z", "$1$2");
// expand time zone: 2015-08-16T08:20:05+00 =>
// 2015-08-16T08:20:05+0000
str = str.replaceAll("([+-]\\d{2})\\z", "$100");
// add milliseconds when missing
// 2015-08-16T08:20:05+0000 => 2015-08-16T08:20:05.000+0000
str = str.replaceAll("(:\\d{1,2})([+-]\\d{4})\\z", "$1.000$2");
format = new SimpleDateFormat(LENIENT_DATETIME_FORMAT);
} else {
format = this.datetimeFormat;
}
try {
return format.parse(str);
} catch (ParseException e) {
logger.error("RuntimeException : " + e);
throw new RuntimeException(e);
}
}
/*
* Parse date or date time in string format into Date object.
*
* @param str Date time string to be parsed
*
* @return Date representation of the string
*/
public Date parseDateOrDatetime(String str) {
if (str == null)
return null;
else if (str.length() <= dateLength)
return parseDate(str);
else
return parseDatetime(str);
}
/**
* Format the given Date object into string (Date format).
*
* @param date Date object
* @return Formatted date in string representation
*/
public String formatDate(Date date) {
return dateFormat.format(date);
}
/**
* Format the given Date object into string (Datetime format).
*
* @param date Date object
* @return Formatted datetime in string representation
*/
public String formatDatetime(Date date) {
return datetimeFormat.format(date);
}
/**
* Get authentications (key: authentication name, value: authentication).
*
* @return Map of authentication objects
*/
public Map getAuthentications() {
return authentications;
}
/**
* Get authentication for the given name.
*
* @param authName The authentication name
* @return The authentication, null if not found
*/
public Authentication getAuthentication(String authName) {
return authentications.get(authName);
}
/**
* Helper method to set username for the first HTTP basic authentication.
*
* @param username Username
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
logger.error("RuntimeException : No HTTP basic authentication configured");
throw new RuntimeException("No HTTP basic authentication configured!");
}
/**
* Helper method to set password for the first HTTP basic authentication.
*
* @param password Password
*/
public void setPassword(String password) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setPassword(password);
return;
}
}
logger.error("RuntimeException : No HTTP basic authentication configured");
throw new RuntimeException("No HTTP basic authentication configured!");
}
/**
* Helper method to set API key value for the first API key authentication.
*
* @param apiKey API key
*/
public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKey(apiKey);
return;
}
}
logger.error("RuntimeException : No API key authentication configured");
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to set API key prefix for the first API key authentication.
*
* @param apiKeyPrefix API key prefix
*/
public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
return;
}
}
logger.error("RuntimeException : No API key authentication configured");
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to set access token for the first OAuth2 authentication.
*
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for (Authentication auth : authentications.values()) {
if (auth instanceof OAuth) {
((OAuth) auth).setAccessToken(accessToken);
return;
}
}
logger.error("RuntimeException : No OAuth2 authentication configured");
throw new RuntimeException("No OAuth2 authentication configured!");
}
/**
* Set the User-Agent header's value (by adding to the default header map).
*
* @param userAgent HTTP request's user agent
* @return ApiClient
*/
public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent);
return this;
}
/**
* Add a default header.
*
* @param key The header's key
* @param value The header's value
* @return ApiClient
*/
public ApiClient addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value);
return this;
}
/**
* @see setLenient
*
* @return True if lenientOnJson is enabled, false otherwise.
*/
public boolean isLenientOnJson() {
return lenientOnJson;
}
/**
* Set LenientOnJson
*
* @param lenient True to enable lenientOnJson
* @return ApiClient
*/
public ApiClient setLenientOnJson(boolean lenient) {
this.lenientOnJson = lenient;
return this;
}
/**
* Check that whether debugging is enabled for this API client.
*
* @return True if debugging is enabled, false otherwise.
*/
public boolean isDebugging() {
return debugging;
}
/**
* Enable/disable debugging for this API client.
*
* @param debugging To enable (true) or disable (false) debugging
* @return ApiClient
*/
public ApiClient setDebugging(boolean debugging) {
if (debugging != this.debugging) {
if (debugging) {
loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(Level.BODY);
httpClient.interceptors().add(loggingInterceptor);
} else {
httpClient.interceptors().remove(loggingInterceptor);
loggingInterceptor = null;
}
}
this.debugging = debugging;
return this;
}
/**
* The path of temporary folder used to store downloaded files from endpoints
* with file response. The default value is null
, i.e. using the
* system's default tempopary folder.
*
* @see createTempFile
* @return Temporary folder path
*/
public String getTempFolderPath() {
return tempFolderPath;
}
/**
* Set the tempoaray folder path (for downloading files)
*
* @param tempFolderPath Temporary folder path
* @return ApiClient
*/
public ApiClient setTempFolderPath(String tempFolderPath) {
this.tempFolderPath = tempFolderPath;
return this;
}
// /**
// * Get connection timeout (in milliseconds).
// *
// * @return Timeout in milliseconds
// */
// public int getConnectTimeout() {
// return httpClient.connectTimeoutMillis();
// }
// /**
// * Sets the connect timeout (in milliseconds). A value of 0 means no timeout,
// * otherwise values must be between 1 and
// *
// * @param connectionTimeout connection timeout in milliseconds
// * @return Api client
// */
// public ApiClient setConnectTimeout(int connectionTimeout) {
// ApiClient.httpClient = ApiClient.httpClient.newBuilder().connectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build();
// return this;
// }
/**
* @return the computationStartTime
*/
public long getComputationStartTime() {
return computationStartTime;
}
/**
* @param computationStartTime the computationStartTime to set
*/
public void setComputationStartTime(long computationStartTime) {
this.computationStartTime = computationStartTime;
}
public void resetInstance() {
this.defaultHeaderMap.clear();
}
/**
* Format the given parameter object into string.
*
* @param param Parameter
* @return String representation of the parameter
*/
public String parameterToString(Object param) {
if (param == null) {
return "";
} else if (param instanceof Date) {
return formatDatetime((Date) param);
} else if (param instanceof Collection) {
StringBuilder b = new StringBuilder();
for (Object o : (Collection>) param) {
if (b.length() > 0) {
b.append(",");
}
b.append(String.valueOf(o));
}
return b.toString();
} else {
return String.valueOf(param);
}
}
/**
* Format to {@code Pair} objects.
*
* @param collectionFormat collection format (e.g. csv, tsv)
* @param name Name
* @param value Value
* @return A list of Pair objects
*/
public List parameterToPairs(String collectionFormat, String name, Object value) {
List params = new ArrayList();
// preconditions
if (name == null || name.isEmpty() || value == null)
return params;
Collection> valueCollection = null;
if (value instanceof Collection) {
valueCollection = (Collection>) value;
} else {
params.add(new Pair(name, parameterToString(value)));
return params;
}
if (valueCollection.isEmpty()) {
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default:
// csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
return params;
}
String delimiter = ",";
if (collectionFormat.equals("csv")) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
delimiter = "|";
}
StringBuilder sb = new StringBuilder();
for (Object item : valueCollection) {
sb.append(delimiter);
sb.append(parameterToString(item));
}
params.add(new Pair(name, sb.substring(1)));
return params;
}
/**
* Sanitize filename by removing path. e.g. ../../sun.gif becomes sun.gif
*
* @param filename The filename to be sanitized
* @return The sanitized filename
*/
public String sanitizeFilename(String filename) {
return filename.replaceAll(".*[/\\\\]", "");
}
/**
* Check if the given MIME is a JSON MIME. JSON MIME examples: application/json
* application/json; charset=UTF8 APPLICATION/JSON application/vnd.company+json
*
* @param mime MIME (Multipurpose Internet Mail Extensions)
* @return True if the given MIME is JSON, false otherwise.
*/
public boolean isJsonMime(String mime) {
String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
return mime != null && (mime.matches(jsonMime) || mime.equalsIgnoreCase("application/json-patch+json"));
}
/**
* Select the Accept header's value from the given accepts array: if JSON exists
* in the given array, use it; otherwise use all of them (joining into a string)
*
* @param accepts The accepts array to select from
* @return The Accept header to use. If the given array is empty, null will be
* returned (not to set the Accept header explicitly).
*/
public String selectHeaderAccept(String[] accepts) {
if (accepts.length == 0) {
return null;
}
for (String accept : accepts) {
if (isJsonMime(accept)) {
return accept;
}
}
return StringUtil.join(accepts, ",");
}
/**
* Select the Content-Type header's value from the given array: if JSON exists
* in the given array, use it; otherwise use the first one of the array.
*
* @param contentTypes The Content-Type array to select from
* @return The Content-Type header to use. If the given array is empty, JSON
* will be used.
*/
public String selectHeaderContentType(String[] contentTypes) {
if (contentTypes.length == 0) {
return "application/json";
}
for (String contentType : contentTypes) {
if (isJsonMime(contentType)) {
return contentType;
}
}
return contentTypes[0];
}
/**
* Escape the given string to be used as URL query value.
*
* @param str String to be escaped
* @return Escaped string
*/
public String escapeString(String str) {
try {
return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) {
return str;
}
}
/**
* Deserialize response body to Java object, according to the return type and
* the Content-Type response header.
*
* @param Type
* @param response HTTP response
* @param returnType The type of the Java object
* @return The deserialized Java object
* @throws ApiException If fail to deserialize response body, i.e. cannot read
* response body or the Content-Type of the response is not
* supported.
*/
@SuppressWarnings("unchecked")
public T deserialize(Response response, Type returnType) throws ApiException {
if (response == null) {
return null;
}
if ((returnType == null && response != null) || ("byte[]".equals(returnType.toString()))) {
T respBody = (T) response.body().byteStream();
return respBody;
} else if (returnType.equals(File.class)) {
// Handle file downloading.
return (T) downloadFileFromResponse(response);
}
String respBody = null;
try {
if (response.body() != null)
respBody = response.body().string();
else
respBody = null;
} catch (IOException e) {
logger.error("ApiException : " + e);
throw new ApiException(e);
}
if (respBody == null || "".equals(respBody)) {
return null;
}
String contentType = response.headers().get("Content-Type");
if (contentType == null) {
// ensuring a default content type
contentType = "application/json";
}
if (isJsonMime(contentType)) {
return json.deserialize(respBody, returnType);
} else if (returnType.equals(String.class)) {
// Expecting string, return the raw response body.
return (T) respBody;
} else {
logger.error(
"ApiException : Content type \"" + contentType + "\" is not supported for type: " + returnType);
throw new ApiException("Content type \"" + contentType + "\" is not supported for type: " + returnType,
response.code(), response.headers().toMultimap(), respBody);
}
}
/**
* Serialize the given Java object into request body according to the object's
* class and the request Content-Type.
*
* @param obj The Java object
* @param contentType The request Content-Type
* @return The serialized request body
* @throws ApiException If fail to serialize the given object
*/
public RequestBody serialize(Object obj, String contentType) throws ApiException {
if (obj instanceof byte[]) {
// Binary (byte array) body parameter support.
return RequestBody.create((byte[]) obj, MediaType.parse(contentType));
} else if (obj instanceof File) {
// File body parameter support.
return RequestBody.create((File) obj, MediaType.parse(contentType));
} else if (isJsonMime(contentType)) {
String content;
if (obj != null) {
content = json.serialize(obj);
} else {
content = null;
}
return RequestBody.create(content, MediaType.parse(contentType));
} else {
logger.error("ApiException : Content type \"" + contentType + "\" is not supported");
throw new ApiException("Content type \"" + contentType + "\" is not supported");
}
}
/**
* Download file from the given response.
*
* @param response An instance of the Response object
* @throws ApiException If fail to read file content from response and write to
* disk
* @return Downloaded file
*/
public File downloadFileFromResponse(Response response) throws ApiException {
try {
File file = prepareDownloadFile(response);
BufferedSink sink = Okio.buffer(Okio.sink(file));
sink.writeAll(response.body().source());
sink.close();
return file;
} catch (IOException e) {
logger.error("ApiException : " + e);
throw new ApiException(e);
}
}
/**
* Prepare file for download
*
* @param response An instance of the Response object
* @throws IOException If fail to prepare file for download
* @return Prepared file for the download
*/
public File prepareDownloadFile(Response response) throws IOException {
String filename = null;
String contentDisposition = response.header("Content-Disposition");
if (contentDisposition != null && !"".equals(contentDisposition)) {
// Get filename from the Content-Disposition header.
Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
Matcher matcher = pattern.matcher(contentDisposition);
if (matcher.find()) {
filename = sanitizeFilename(matcher.group(1));
}
}
String prefix = null;
String suffix = null;
if (filename == null) {
prefix = "download-";
suffix = "";
} else {
int pos = filename.lastIndexOf(".");
if (pos == -1) {
prefix = filename + "-";
} else {
prefix = filename.substring(0, pos) + "-";
suffix = filename.substring(pos);
}
// File.createTempFile requires the prefix to be at least three
// characters long
if (prefix.length() < 3)
prefix = "download-";
}
if (tempFolderPath == null)
return File.createTempFile(prefix, suffix);
else
return File.createTempFile(prefix, suffix, new File(tempFolderPath));
}
/**
* {@link #execute(Call, Type)}
*
* @param Type
* @param call An instance of the Call object
* @throws ApiException If fail to execute the call
* @return ApiResponse<T>
*/
public ApiResponse execute(Call call) throws ApiException {
return execute(call, null);
}
/**
* Execute HTTP call and deserialize the HTTP response body into the given
* return type.
*
* @param returnType The return type used to deserialize HTTP response body
* @param The return type corresponding to (same with) returnType
* @param call Call
* @return ApiResponse object containing response status, headers and data,
* which is a Java object deserialized from response body and would be
* null when returnType is null.
* @throws ApiException If fail to execute the call
*/
public ApiResponse execute(Call call, Type returnType) throws ApiException {
try {
this.apiRequestMetrics.setComputeTime((System.nanoTime() - this.getComputationStartTime()) / 1000000);
Response response = call.execute();
String responseCode = String.valueOf(response.code());
this.status = response.message();
this.responseCode = responseCode;
logger.debug("Network Response :\n" + json.serialize(response.headers()));
if(returnType == new TypeToken< Model.AccessTokenResponse >(){}.getType()) {
logger.debug("Response :\n" + response.peekBody(Long.MAX_VALUE).string());
}
T data = handleResponse(response, returnType);
if (returnType != null || call.request().method().equalsIgnoreCase("DELETE") || responseCode.equalsIgnoreCase("202")) {
response.body().close();
}
logger.info("HTTP Response Body :\n{}", data);
return new ApiResponse(response.code(), response.headers().toMultimap(), response.message(), data);
} catch (IOException e) {
logger.error("ApiException : " + e.getMessage());
throw new ApiException(e);
}
catch (NullPointerException e) {
logger.error("ApiException : " + e.getMessage());
throw new ApiException(e);
}
}
/**
* {@link #executeAsync(Call, Type, ApiCallback)}
*
* @param Type
* @param call An instance of the Call object
* @param callback ApiCallback<T>
*/
public void executeAsync(Call call, ApiCallback callback) {
executeAsync(call, null, callback);
}
/**
* Execute HTTP call asynchronously.
*
* @see #execute(Call, Type)
* @param Type
* @param call The callback to be executed when the API call finishes
* @param returnType Return type
* @param callback ApiCallback
*/
@SuppressWarnings("unchecked")
public void executeAsync(Call call, final Type returnType, final ApiCallback callback) {
call.enqueue(new Callback() {
@Override
public void onFailure(Call call0, IOException e) {
callback.onFailure(new ApiException(e), 0, null);
}
@Override
public void onResponse(Call call0, Response response) throws IOException {
T result;
try {
result = (T) handleResponse(response, returnType);
} catch (ApiException e) {
callback.onFailure(e, response.code(), response.headers().toMultimap());
return;
}
callback.onSuccess(result, response.code(), response.headers().toMultimap());
}
});
}
/**
* Handle the given response, return the deserialized object when the response
* is successful.
*
* @param Type
* @param response Response
* @param returnType Return type
* @throws ApiException If the response has a unsuccessful status code or fail
* to deserialize the response body
* @return Type
*/
public T handleResponse(Response response, Type returnType) throws ApiException {
if (response.isSuccessful()) {
if (response.code() == 204) {
if (response.body() != null) {
response.body().close();
}
return null;
} else {
return deserialize(response, returnType);
}
} else {
String respBody = null;
if (response.body() != null) {
try {
respBody = response.body().string();
logger.info(respBody);
} catch (IOException e) {
logger.error("ApiException : " + e + " " + response.code() + " " + response.message());
throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
}
}
logger.error("ApiException : " + response.code() + " " + response.message());
throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody);
}
}
/**
* Build HTTP call with the given options.
*
* @param path The sub-path of the HTTP URL
* @param method The request method, one of "GET", "HEAD",
* "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
* @param queryParams The query parameters
* @param body The request body object
* @param headerParams The header parameters
* @param formParams The form parameters
* @param authNames The authentications to apply
* @param progressRequestListener Progress request listener
* @return The HTTP call
* @throws ApiException If fail to serialize the request body object
*/
public Call buildCall(String path, String method, List queryParams, Object body,
Map headerParams, Map formParams, String[] authNames,
ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
//create reqHeader parameter here
Map requestHeaderMap = new HashMap();
if(merchantConfig.getDefaultHeaders() != null && !merchantConfig.getDefaultHeaders().isEmpty()) {
for (Entry header : merchantConfig.getDefaultHeaders().entrySet()) {
if(!header.getKey().equalsIgnoreCase("Authorization") && !header.getKey().equalsIgnoreCase("Signature")){
requestHeaderMap.put(header.getKey(), header.getValue());
}
}
}
String contentType = headerParams.get("Content-Type");
// ensuring a default content type
if (contentType == null) {
contentType = "application/json";
}
RequestBody requestbody = createRequestBody(method, body, formParams, contentType);
callAuthenticationHeader(method, path, requestbody, queryParams, requestHeaderMap);
if (merchantConfig.isEnableClientCert()) {
addClientCertToKeyStore();
}
if (acceptHeader != null && !acceptHeader.isEmpty()) {
String defaultAcceptHeader = "," + headerParams.get("Accept");
defaultAcceptHeader = acceptHeader + defaultAcceptHeader.replace("," + acceptHeader, "");
headerParams.remove("Accept");
headerParams.put("Accept", defaultAcceptHeader);
}
headerParams.putAll(requestHeaderMap);
logger.info("Request Header Parameters:\n{}", new PrettyPrintingMap(headerParams));
Request request = buildRequest(path, method, queryParams, requestbody, headerParams, formParams, authNames,
progressRequestListener);
return httpClient.newCall(request);
}
private String getRequestContentSendOverNetwork(RequestBody requestBody) throws IOException {
if(requestBody!=null) {
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
String payload = buffer.readUtf8();
return payload;
}
return null;
}
/*
* Purpose : This function calling the Authentication and making an Auth Header
*
*/
public void callAuthenticationHeader(String method, String path, RequestBody reqBody, List queryParams, Map requestHeaderMap) {
try {
String requestTarget = null;
if (queryParams != null && !queryParams.isEmpty()) {
StringBuilder url = new StringBuilder();
url.append(path);
if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.HTTP)) {
// support (constant) query string in `path`, e.g.
// "/posts?draft=1"
String prefix = path.contains("?") ? "&" : "?";
for (Pair param : queryParams) {
if (param.getValue() != null) {
if (prefix != null) {
url.append(prefix);
prefix = null;
} else {
url.append("&");
}
String value = parameterToString(param.getValue());
url.append(escapeString(param.getName())).append("=").append(escapeString(value));
}
}
requestTarget= url.toString();
}
} else {
requestTarget = path;
}
Authorization authorization = new Authorization();
String requestBody = getRequestContentSendOverNetwork(reqBody);
logger.debug("HTTP Request Body:\n" + requestBody);
boolean isMerchantDetails = merchantConfig.validateMerchantDetails(method);
if (isMerchantDetails
&& !merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.MUTUALAUTH)) {
String date = PropertiesUtil.getNewDate();
String token = authorization.getToken(merchantConfig, method, requestBody, requestTarget, date);
if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.HTTP)) {
requestHeaderMap.put("Date", date);
requestHeaderMap.put("Host", merchantConfig.getRequestHost().trim());
requestHeaderMap.put("v-c-merchant-id", merchantConfig.getMerchantID());
requestHeaderMap.put("Signature", token);
requestHeaderMap.put("User-Agent", "Mozilla/5.0");
if (method.equalsIgnoreCase("POST") || method.equalsIgnoreCase("PUT")
|| method.equalsIgnoreCase("PATCH")) {
PayloadDigest payloadDigest = new PayloadDigest(requestBody);
String digest = payloadDigest.getDigest();
requestHeaderMap.put("Digest", digest);
}
} else if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.JWT)) {
token = "Bearer " + token;
requestHeaderMap.put("Authorization", token);
} else if (merchantConfig.getAuthenticationType().equalsIgnoreCase(GlobalLabelParameters.OAUTH)) {
token = "Bearer " + token;
requestHeaderMap.put("Authorization", token);
}
}
if (versionInfo != null && !versionInfo.isEmpty()) {
requestHeaderMap.put("v-c-client-id", "cybs-rest-sdk-java-" + versionInfo);
}
} catch (ConfigException | IOException e) {
logger.error(e.getMessage());
}
}
/**
* Build an HTTP request with the given options.
*
* @param path The sub-path of the HTTP URL
* @param method The request method, one of "GET", "HEAD",
* "OPTIONS", "POST", "PUT", "PATCH" and "DELETE"
* @param queryParams The query parameters
* @param reqBody The request body object
* @param headerParams The header parameters
* @param formParams The form parameters
* @param authNames The authentications to apply
* @param progressRequestListener Progress request listener
* @return The HTTP request
* @throws ApiException If fail to serialize the request body object
*/
@SuppressWarnings({ "unchecked" })
public Request buildRequest(String path, String method, List queryParams, RequestBody reqBody,
Map headerParams, Map formParams, String[] authNames,
ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
updateParamsForAuth(authNames, queryParams, headerParams);
final String url = buildUrl(path, queryParams);
final Request.Builder reqBuilder = new Request.Builder().url(url);
processHeaderParams(headerParams, reqBuilder);
Request request = null;
if (progressRequestListener != null && reqBody != null) {
ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, progressRequestListener);
request = reqBuilder.method(method, progressRequestBody).build();
} else {
request = reqBuilder.method(method, reqBody).build();
}
return request;
}
private RequestBody createRequestBody(String method, Object body, Map formParams,
String contentType) throws ApiException {
RequestBody reqBody;
if (!HttpMethod.permitsRequestBody(method)) {
reqBody = null;
} else if ("application/x-www-form-urlencoded".equals(contentType)) {
// Convert request body to json to url encoded
Gson gson = new Gson();
String jsonString = json.serialize(body);
formParams = gson.fromJson(jsonString, HashMap.class);
reqBody = buildRequestBodyFormEncoding(formParams);
} else if ("multipart/form-data".equals(contentType)) {
reqBody = buildRequestBodyMultipart(formParams);
} else if (body == null) {
if ("DELETE".equals(method)) {
// allow calling DELETE without sending a request body
reqBody = null;
} else {
// use an empty request body (for POST, PUT and PATCH)
reqBody = RequestBody.create("",MediaType.parse(contentType));
}
} else {
if (body.equals("{}")) {
reqBody = RequestBody.create("{}", MediaType.parse(contentType));
} else {
reqBody = serialize(body, contentType);
}
}
return reqBody;
}
/**
* Build full URL by concatenating base path, the given sub path and query
* parameters.
*
* @param path The sub path
* @param queryParams The query parameters
* @return The full URL
*/
public String buildUrl(String path, List queryParams) {
final StringBuilder url = new StringBuilder();
if (StringUtils.isNotBlank(merchantConfig.getIntermediateHost())) {
if (merchantConfig.getIntermediateHost().startsWith(GlobalLabelParameters.URL_PREFIX)
|| merchantConfig.getIntermediateHost().startsWith("http://")) {
url.append(merchantConfig.getIntermediateHost().trim()).append(path);
} else {
url.append(GlobalLabelParameters.URL_PREFIX).append(merchantConfig.getIntermediateHost().trim())
.append(path);
}
} else {
url.append(GlobalLabelParameters.URL_PREFIX).append(merchantConfig.getRequestHost().trim()).append(path);
}
if (queryParams != null && !queryParams.isEmpty()) {
// support (constant) query string in `path`, e.g. "/posts?draft=1"
String prefix = path.contains("?") ? "&" : "?";
for (Pair param : queryParams) {
if (param.getValue() != null) {
if (prefix != null) {
url.append(prefix);
prefix = null;
} else {
url.append("&");
}
String value = parameterToString(param.getValue());
url.append(escapeString(param.getName())).append("=").append(escapeString(value));
}
}
}
return url.toString();
}
/**
* Set header parameters to the request builder, including default headers.
*
* @param headerParams Header parameters in the ofrm of Map
* @param reqBuilder Reqeust.Builder
*/
public void processHeaderParams(Map headerParams, Request.Builder reqBuilder) {
for (Entry param : headerParams.entrySet()) {
reqBuilder.header(param.getKey(), parameterToString(param.getValue()));
}
for (Entry header : defaultHeaderMap.entrySet()) {
if (!headerParams.containsKey(header.getKey())) {
reqBuilder.header(header.getKey(), parameterToString(header.getValue()));
}
}
reqBuilder.header("Connection", "keep-alive");
}
/**
* Update query and header parameters based on authentication settings.
*
* @param authNames The authentications to apply
* @param queryParams List of query parameters
* @param headerParams Map of header parameters
*/
public void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) {
logger.error("RuntimeException : Authentication undefined for " + authName);
throw new RuntimeException("Authentication undefined: " + authName);
}
auth.applyToParams(queryParams, headerParams);
}
}
/**
* Build a form-encoding request body with the given form parameters.
*
* @param formParams Form parameters in the form of Map
* @return RequestBody
*/
public RequestBody buildRequestBodyFormEncoding(Map formParams) {
FormBody.Builder formBuilder = new FormBody.Builder();
for (Entry param : formParams.entrySet()) {
formBuilder.addEncoded(param.getKey(), parameterToString(param.getValue()));
}
return formBuilder.build();
}
/**
* Build a multipart (file uploading) request body with the given form
* parameters, which could contain text fields and file fields.
*
* @param formParams Form parameters in the form of Map
* @return RequestBody
*/
public RequestBody buildRequestBodyMultipart(Map formParams) {
MultipartBody.Builder mpBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (Entry param : formParams.entrySet()) {
if (param.getValue() instanceof File) {
File file = (File) param.getValue();
Headers partHeaders = Headers.of("Content-Disposition",
"form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\"");
MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file));
mpBuilder.addPart(partHeaders, RequestBody.create(file, mediaType));
} else {
Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"");
mpBuilder.addPart(partHeaders, RequestBody.create(parameterToString(param.getValue()), null));
}
}
return mpBuilder.build();
}
/**
* Guess Content-Type header from the given file (defaults to
* "application/octet-stream").
*
* @param file The given file
* @return The guessed Content-Type
*/
public String guessContentTypeFromFile(File file) {
String contentType = URLConnection.guessContentTypeFromName(file.getName());
if (contentType == null) {
return "application/octet-stream";
} else {
return contentType;
}
}
/**
* Initialize datetime format according to the current environment, e.g. Java
* 1.7 and Android.
*/
private void initDatetimeFormat() {
String formatWithTimeZone = null;
if (IS_ANDROID) {
if (ANDROID_SDK_VERSION >= 18) {
// The time zone format "ZZZZZ" is available since Android 4.3
// (SDK version 18)
formatWithTimeZone = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ";
}
} else if (JAVA_VERSION >= 1.7) {
// The time zone format "XXX" is available since Java 1.7
formatWithTimeZone = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
}
if (formatWithTimeZone != null) {
this.datetimeFormat = new SimpleDateFormat(formatWithTimeZone);
// NOTE: Use the system's default time zone (mainly for datetime
// formatting).
} else {
// Use a common format that works across all systems.
this.datetimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// Always use the UTC time zone as we are using a constant trailing
// "Z" here.
this.datetimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
}
/**
* Adding Client Cert (.p12) to KeyStore, Trust all site
*/
private void addClientCertToKeyStore() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
}
};
KeyStore merchantKeyStore = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
FileInputStream file = new FileInputStream(
new File(merchantConfig.getClientCertDirectory(), merchantConfig.getClientCertFile()));
merchantKeyStore.load(file, merchantConfig.getClientCertPassword().toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(merchantKeyStore, new char[] {});
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, new SecureRandom());
httpClient = httpClient.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]).build();
} catch (IOException | CertificateException | NoSuchAlgorithmException | KeyStoreException
| KeyManagementException | UnrecoverableKeyException ex) {
}
}
/**
* Apply SSL related settings to httpClient according to the current values of
* verifyingSsl and sslCaCert.
*/
@SuppressWarnings("deprecation")
private void applySslSettings() {
try {
TrustManager[] trustManagers = null;
HostnameVerifier hostnameVerifier = null;
if (!verifyingSsl) {
TrustManager trustAll = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
trustManagers = new TrustManager[] { trustAll };
hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
} else if (sslCaCert != null) {
char[] password = null; // Any password will work.
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection extends Certificate> certificates = certificateFactory.generateCertificates(sslCaCert);
if (certificates.isEmpty()) {
logger.error("IllegalArgumentException : Expected non-empty set of trusted certificates");
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
KeyStore caKeyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = "ca" + Integer.toString(index++);
caKeyStore.setCertificateEntry(certificateAlias, certificate);
}
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(caKeyStore);
trustManagers = trustManagerFactory.getTrustManagers();
}
if (keyManagers != null || trustManagers != null) {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, new SecureRandom());
httpClient = httpClient.newBuilder().sslSocketFactory(sslContext.getSocketFactory()).build();
} else {
httpClient = httpClient.newBuilder().sslSocketFactory(null).build();
}
httpClient = httpClient.newBuilder().hostnameVerifier(hostnameVerifier).build();
} catch (GeneralSecurityException e) {
logger.error("RuntimeException : " + e);
throw new RuntimeException(e);
}
}
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, password);
return keyStore;
} catch (IOException e) {
logger.error("AssertionError : " + e);
throw new AssertionError(e);
}
}
private long getNewRandomId() {
SecureRandom random = new SecureRandom();
byte sessBytes[] = new byte[32];
random.nextBytes(sessBytes);
long randomId = 0;
for (int i = 0; i < sessBytes.length; i++) {
randomId += ((long) sessBytes[i] & 0xffL) << (8 * i);
}
return randomId;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy