All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Invokers.ApiClient Maven / Gradle / Ivy

There is a newer version: 0.0.8
Show newest version
/*
 * 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 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