diff --git a/build.gradle b/build.gradle
index fda17bd..84774b6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,12 +10,13 @@ plugins {
// Apply the java-library plugin to add support for Java Library
id 'java'
id 'jacoco'
- id 'org.springframework.boot' version '3.1.3'
+ id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
- id 'io.freefair.lombok' version '8.2.2'
+ id 'io.freefair.lombok' version '8.4'
id 'signing'
id 'maven-publish'
- id "org.owasp.dependencycheck" version "8.4.0"
+ id "org.owasp.dependencycheck" version "8.4.2"
+ id "org.sonarqube" version "4.4.1.3373"
}
group = 'com.siliconmtn'
@@ -25,12 +26,21 @@ group = 'com.siliconmtn'
* For 'release' publishing, use: version = n.n.n
*
*/
-//version = '2.0.1-SNAPSHOT'
-version = '2.0.1'
+//version = '2.0.2-SNAPSHOT'
+version = '2.0.2'
-sourceCompatibility = '17'
archivesBaseName = "spacelibs-java"
+
+configurations {
+ testImplementation{
+ extendsFrom compileOnly
+ }
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
+}
+
repositories {
// Use Maven Central for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
@@ -39,46 +49,48 @@ repositories {
dependencies {
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
- implementation 'commons-beanutils:commons-beanutils:1.9.4'
- implementation 'commons-io:commons-io:2.13.0'
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.13.19'
+ compileOnly 'commons-beanutils:commons-beanutils:1.9.4'
+ compileOnly 'commons-io:commons-io:2.13.0'
+ compileOnly 'com.googlecode.libphonenumber:libphonenumber:8.13.19'
- implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
- implementation 'org.apache.poi:poi:5.2.3'
+ compileOnly 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
+ compileOnly 'org.apache.poi:poi:5.2.3'
// Spring Boot (Starters -> https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter)
- implementation 'org.springframework.boot:spring-boot-starter'
- implementation 'org.springframework.boot:spring-boot-starter-web'
- implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
- implementation 'org.springframework.boot:spring-boot-starter-aop'
- implementation 'org.springframework.boot:spring-boot-starter-validation'
+ compileOnly 'org.springframework.boot:spring-boot-starter'
+ compileOnly 'org.springframework.boot:spring-boot-starter-web'
+ compileOnly 'org.springframework.boot:spring-boot-starter-data-jpa'
+ compileOnly 'org.springframework.boot:spring-boot-starter-aop'
+ compileOnly 'org.springframework.boot:spring-boot-starter-validation'
- implementation 'org.springframework.security:spring-security-crypto:6.1.3'
- implementation 'org.hibernate:hibernate-validator:8.0.1.Final'
+ compileOnly 'org.springframework.security:spring-security-crypto:6.1.3'
+ compileOnly 'org.hibernate:hibernate-validator:8.0.1.Final'
// XSS content validation/filtering
- implementation 'org.owasp.encoder:encoder:1.2.3'
- implementation 'org.jsoup:jsoup:1.16.1'
- implementation 'com.auth0:java-jwt:4.4.0'
+ compileOnly 'org.owasp.encoder:encoder:1.2.3'
+ compileOnly 'org.jsoup:jsoup:1.16.1'
+ compileOnly 'com.auth0:java-jwt:4.4.0'
// AWS Imports for the S3 Buckets
- implementation 'software.amazon.awssdk:bom:2.19.8'
- implementation 'software.amazon.awssdk:s3:2.19.8'
- implementation 'software.amazon.awssdk:sns:2.19.8'
+ compileOnly 'software.amazon.awssdk:bom:2.19.8'
+ compileOnly 'software.amazon.awssdk:s3:2.19.8'
+ compileOnly 'software.amazon.awssdk:sns:2.19.8'
// Testing
- testImplementation 'org.springframework.security:spring-security-test'
+ testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.mockito:mockito-core:5.2.0'
testImplementation 'org.mockito:mockito-inline:5.2.0'
testImplementation('org.springframework.boot:spring-boot-starter-test'){
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
//OpenAPI3 (Swagger)
- implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
+ compileOnly 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
// https://mvnrepository.com/artifact/org.apache.pulsar/pulsar-client
- implementation 'org.apache.pulsar:pulsar-client:3.1.0'
+ compileOnly 'org.apache.pulsar:pulsar-client:3.1.0'
+ testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
+ testRuntimeOnly('org.junit.platform:junit-platform-launcher:1.9.2')
}
// Prevent Spring Boot from looking for a main()
@@ -111,6 +123,7 @@ javadoc {
}
java {
+ sourceCompatibility = JavaVersion.VERSION_17
withJavadocJar()
withSourcesJar()
}
diff --git a/src/main/java/com/siliconmtn/data/util/EntityUtil.java b/src/main/java/com/siliconmtn/data/util/EntityUtil.java
index 8d8d0c4..7f3503a 100644
--- a/src/main/java/com/siliconmtn/data/util/EntityUtil.java
+++ b/src/main/java/com/siliconmtn/data/util/EntityUtil.java
@@ -96,7 +96,7 @@ public BaseEntity dtoToEntity(BaseDTO dto, BaseEntity entity) {
var entityField = entity.getClass().getDeclaredField(dtoField.getName());
if (entityField.getType() != dtoField.getType() && value != null) {
- log.info(entityField.getName());
+ log.debug(entityField.getName());
value = entityManager.getReference(entityField.getType(), value);
if (value == null)
throw new EndpointRequestException(
diff --git a/src/main/java/com/siliconmtn/io/http/SMTHttpConnectionManager.java b/src/main/java/com/siliconmtn/io/http/SMTHttpConnectionManager.java
index 387182c..30935e0 100644
--- a/src/main/java/com/siliconmtn/io/http/SMTHttpConnectionManager.java
+++ b/src/main/java/com/siliconmtn/io/http/SMTHttpConnectionManager.java
@@ -14,40 +14,48 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
-// Log4j 2.x
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
+import org.apache.pulsar.shade.org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.siliconmtn.data.text.StringUtil;
+import com.siliconmtn.io.api.EndpointResponse;
+
+import lombok.extern.log4j.Log4j2;
/****************************************************************************
* Title: SMTHttpConnectionManager.java
* Project: SpaceLibs-Java
- * Description: Wrapper class around URLs and connections. Manages the
- * sessions via cookies. This allows multiple requests to be made to the same
- * server using any cookies that were present
- * during the initial connection as well as subsequent sessions. Allow
- * for the setting of an SSLSocketFactory in support of certificate-based auth
- * connections. Redirects, timeouts, headers (both request and response) are managed.
- * Because we return byte[], any type of data can be retrieved
+ * Description: Wrapper class around URLs and connections. Manages the
+ * sessions via cookies. This allows multiple requests to be made to the same
+ * server using any cookies that were present during the initial connection as
+ * well as subsequent sessions. Allow for the setting of an SSLSocketFactory in
+ * support of certificate-based auth connections. Redirects, timeouts, headers
+ * (both request and response) are managed. Because we return byte[], any type
+ * of data can be retrieved
* Copyright: Copyright (c) 2021
* Company: Silicon Mountain Technologies
*
* @author James Camire
* @version 3.0
* @since Jan 15, 2021
- * @updates:
+ * @updates: Added capability to build a URL constructed requiring parameter
+ * replacement as well as parse/convert an EndpointResponse JSON Payload.
****************************************************************************/
@Component
+@Log4j2
public class SMTHttpConnectionManager {
-
-
+
/**
* Identifies the type of HTTP Connection
*/
@@ -59,12 +67,12 @@ public enum HttpConnectionType {
* Default connection prefix if not supplied
*/
public static final String HTTP_CONN_PREFIX = "http://";
-
+
/**
* Default connection prefix if not supplied
*/
public static final String HTTPS_CONN_PREFIX = "https://";
-
+
/**
* Socket timeout in ms
*/
@@ -91,7 +99,7 @@ public enum HttpConnectionType {
public static final String COOKIE_HEADER_NAME = "Set-Cookie";
/**
- * String representation in the header
+ * String representation in the header
*/
public static final String COOKIE_NAME = "Cookie";
@@ -109,17 +117,17 @@ public enum HttpConnectionType {
* Identifies the request method for the connection as a GET method
*/
public static final String HTTP_PUT_METHOD = "PUT";
-
+
/**
* Identifies the content type for the POST method.
*/
public static final String REQUEST_PROPERTY_CONTENT_TYPE = "Content-Type";
-
+
/**
* Identifies the length of the message when posting data
*/
public static final String REQUEST_PROPERTY_CONTENT_LENGTH = "Content-Length";
-
+
/**
* Exception message text for use when URL is not supplied.
*/
@@ -127,14 +135,13 @@ public enum HttpConnectionType {
/**
* sslSocketFactory The SSLSocketFactory that is set on the HTTPS connection
- * object just after it is instantiated and prior to any other properties being set
- * for said object. If a non-https url is passed to the connect methods, the
+ * object just after it is instantiated and prior to any other properties being
+ * set for said object. If a non-https url is passed to the connect methods, the
* SSLSocketFactory object will be ignored.
*/
private SSLSocketFactory sslSocketFactory;
-
+
// Members
- static final Logger log = LogManager.getLogger(SMTHttpConnectionManager.class);
private int connectionTimeout;
private boolean followRedirects = true;
private Map requestHeaders;
@@ -143,7 +150,7 @@ public enum HttpConnectionType {
private Map headerMap;
private int redirectLimit = 10;
private boolean useCookieHandler = false;
-
+
/**
* Initializes the manager
*/
@@ -152,99 +159,108 @@ public SMTHttpConnectionManager() {
cookies = new LinkedHashMap<>();
headerMap = new LinkedHashMap<>();
}
-
+
/**
* Specifies if the cookie handler should be utilized
+ *
* @param useCookieHandler Boolean to indicate whther or not to use the provided
- * cookie manager
+ * cookie manager
*/
public SMTHttpConnectionManager(boolean useCookieHandler) {
this();
this.useCookieHandler = useCookieHandler;
}
-
+
/**
- * Accepts an SSLSocketFactory. The SSLSocketFactory is set on an HTTPS
- * connection object (HttpsURLConnection) when the connection object is
- * created, provided that the requested url's protocol is https. Otherwise the
+ * Accepts an SSLSocketFactory. The SSLSocketFactory is set on an HTTPS
+ * connection object (HttpsURLConnection) when the connection object is created,
+ * provided that the requested url's protocol is https. Otherwise the
* SSLSocketFactory object is not used.
+ *
* @param sslSocketFactory Socket factory to utilize for SSL connections
*/
public SMTHttpConnectionManager(SSLSocketFactory sslSocketFactory) {
this();
setSslSocketFactory(sslSocketFactory);
}
-
+
/**
* Retrieves data from an HTTP server and returns the data
- * @param url fully qualified URL (http://www.somedomain.com)
+ *
+ * @param url fully qualified URL (http://www.somedomain.com)
* @param parameters HTTP POST data as a Map of key, value pairs
* @return binary data containing information retrieved from the site
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
- * Defaults to POST if type is null
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE. Defaults to POST if type is null
* @throws IOException When data can't be retrieved, this exception is thrown
*/
- public byte[] getRequestData(String url, Map parameters, HttpConnectionType type)
- throws IOException {
- if (StringUtil.isEmpty(url)) throw new IOException(MSG_URL_REQUIRED);
+ public byte[] getRequestData(String url, Map parameters, HttpConnectionType type)
+ throws IOException {
+ if (StringUtil.isEmpty(url))
+ throw new IOException(MSG_URL_REQUIRED);
return connect(createURL(url), convertPostData(parameters), type == null ? HttpConnectionType.POST : type);
}
-
+
/**
* Retrieves data from an HTTP server and returns the data
- * @param url fully qualified URL (http://www.somedomain.com)
+ *
+ * @param url fully qualified URL (http://www.somedomain.com)
* @param parameters HTTP POST data as a Map of key, value pairs
* @return binary data containing information retrieved from the site
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
- * Defaults to POST if type is null
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE. Defaults to POST if type is null
* @throws IOException When data can't be retrieved, this exception is thrown
*/
- public byte[] getRequestData(URL url, Map parameters, HttpConnectionType type)
- throws IOException {
- if (url == null) throw new IOException(MSG_URL_REQUIRED);
+ public byte[] getRequestData(URL url, Map parameters, HttpConnectionType type) throws IOException {
+ if (url == null)
+ throw new IOException(MSG_URL_REQUIRED);
return connect(url, convertPostData(parameters), type == null ? HttpConnectionType.POST : type);
}
-
- /**
- * Retrieves data from an end point via the provided HTTP Request Type
- * (GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE). Returns data as a byte array since the
- * requested data may be binary
- * @param url Url to call.
- * @param data Data sent in the body of the message
- * Do NOT include the ? in the Url or paramters
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
- * @return byte data from the end point server
- * @throws IOException
- */
- public byte[] getRequestData(URL url, byte[] data, HttpConnectionType type)
- throws IOException {
- if (url == null) throw new IOException(MSG_URL_REQUIRED);
- return connect(url, data == null ? new byte[0] : data, type == null ? HttpConnectionType.POST : type);
- }
-
- /**
- * Retrieves data from an end point via the provided HTTP Request Type
- * (GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE). Returns data as a byte array since the
- * requested data may be binary
- * @param url Url to call.
- * @param data Data sent in the body of the message
- * Do NOT include the ? in the Url or paramters
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
- * @return byte data from the end point server
- * @throws IOException
- */
-
- public byte[] getRequestData(String url, byte[] data, HttpConnectionType type)
- throws IOException {
- if (url == null) throw new IOException(MSG_URL_REQUIRED);
- return connect(createURL(url), data == null ? new byte[0] : data, type == null ? HttpConnectionType.POST : type);
- }
-
+
+ /**
+ * Retrieves data from an end point via the provided HTTP Request Type (GET,
+ * POST, HEAD, OPTIONS, PUT, DELETE, TRACE). Returns data as a byte array since
+ * the requested data may be binary
+ *
+ * @param url Url to call.
+ * @param data Data sent in the body of the message Do NOT include the ? in the
+ * Url or paramters
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
+ * @return byte data from the end point server
+ * @throws IOException
+ */
+ public byte[] getRequestData(URL url, byte[] data, HttpConnectionType type) throws IOException {
+ if (url == null)
+ throw new IOException(MSG_URL_REQUIRED);
+ return connect(url, data == null ? new byte[0] : data, type == null ? HttpConnectionType.POST : type);
+ }
+
+ /**
+ * Retrieves data from an end point via the provided HTTP Request Type (GET,
+ * POST, HEAD, OPTIONS, PUT, DELETE, TRACE). Returns data as a byte array since
+ * the requested data may be binary
+ *
+ * @param url Url to call.
+ * @param data Data sent in the body of the message Do NOT include the ? in the
+ * Url or paramters
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE
+ * @return byte data from the end point server
+ * @throws IOException
+ */
+
+ public byte[] getRequestData(String url, byte[] data, HttpConnectionType type) throws IOException {
+ if (url == null)
+ throw new IOException(MSG_URL_REQUIRED);
+ return connect(createURL(url), data == null ? new byte[0] : data,
+ type == null ? HttpConnectionType.POST : type);
+ }
/**
* Connects to a HTTP server using the supplied URL and gets the data
+ *
* @param actionUrl
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE.
* @return data for the request
* @throws IOException When data can't be retrieved, this exception is thrown
*/
@@ -258,33 +274,39 @@ private byte[] connect(URL actionUrl, byte[] postDataBytes, HttpConnectionType t
}
}
-
+
return baos.toByteArray();
}
-
+
/**
- * Connects to the end device and returns a stream so the data can be
- * processed sequentially.
- * @param url URL for the connection
+ * Connects to the end device and returns a stream so the data can be processed
+ * sequentially.
+ *
+ * @param url URL for the connection
* @param params Post data to pass as a Map key, value pairs
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE.
* @return Connection stream to the data
* @throws IOException When data can't be retrieved, this exception is thrown
*/
- public InputStream getConnectionStream(URL url, Map params, HttpConnectionType type) throws IOException {
+ public InputStream getConnectionStream(URL url, Map params, HttpConnectionType type)
+ throws IOException {
return connectStream(url, convertPostData(params), 0, type);
}
-
+
/**
- * Connects to the end device and returns a stream so the data can be processed sequentially
+ * Connects to the end device and returns a stream so the data can be processed
+ * sequentially
+ *
* @param actionUrl URL for the connection
- * @param postData Post data to pass
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
+ * @param postData Post data to pass
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE.
* @return Stream of the connection
* @throws IOException When data can't be retrieved, this exception is thrown
*/
- private InputStream connectStream(URL actionUrl, byte[] postDataBytes, int redirectAttempt, HttpConnectionType type)
- throws IOException {
+ private InputStream connectStream(URL actionUrl, byte[] postDataBytes, int redirectAttempt, HttpConnectionType type)
+ throws IOException {
log.debug("Connecting to: {}", actionUrl);
// build connection
@@ -293,8 +315,9 @@ private InputStream connectStream(URL actionUrl, byte[] postDataBytes, int redir
// execute the connection
executeConnection(conn, postDataBytes, type);
- //see if we need to follow a redirect
- if (followRedirects && (HttpURLConnection.HTTP_MOVED_PERM == responseCode || HttpURLConnection.HTTP_MOVED_TEMP == responseCode) && redirectAttempt < redirectLimit) {
+ // see if we need to follow a redirect
+ if (followRedirects && (HttpURLConnection.HTTP_MOVED_PERM == responseCode
+ || HttpURLConnection.HTTP_MOVED_TEMP == responseCode) && redirectAttempt < redirectLimit) {
String redirUrl = conn.getHeaderField("Location");
log.debug("Following redirect to: {}", redirUrl);
if (!StringUtil.isEmpty(redirUrl)) {
@@ -305,33 +328,37 @@ private InputStream connectStream(URL actionUrl, byte[] postDataBytes, int redir
log.debug("Response code: {}", responseCode);
- // return the response stream from the server - if the request failed return the error stream
+ // return the response stream from the server - if the request failed return the
+ // error stream
return (200 <= responseCode && 300 > responseCode) ? conn.getInputStream() : conn.getErrorStream();
}
-
+
/**
- * Validates and creates a URL using actionUrl. Default prototcal is http://
+ * Validates and creates a URL using actionUrl. Default prototcal is http://
+ *
* @param actionUrl Creates a URL object form the string url
* @return URL object representing the string url
- * @throws IOException When data can't be retrieved, this exception is thrown
+ * @throws IOException When data can't be retrieved, this exception is thrown
*/
public URL createURL(String actionUrl) throws IOException {
- if (StringUtil.isEmpty(actionUrl)) throw new IOException("Invalid URL");
- if (! actionUrl.startsWith("http")) {
+ if (StringUtil.isEmpty(actionUrl))
+ throw new IOException("Invalid URL");
+ if (!actionUrl.startsWith("http")) {
actionUrl = ((sslSocketFactory == null) ? HTTP_CONN_PREFIX : HTTPS_CONN_PREFIX) + actionUrl;
}
-
+
return new URL(actionUrl);
}
-
+
/**
* Returns a connection type based on the URL protocol
+ *
* @param url Pointer to the end server
* @return Http URL Connection to the end server
- * @throws IOException When data can't be retrieved, this exception is thrown
+ * @throws IOException When data can't be retrieved, this exception is thrown
*/
private HttpURLConnection createConnection(URL url) throws IOException {
- // Set the cookie handler. Since this is and accessed
+ // Set the cookie handler. Since this is and accessed
// via static method lack of use still requires action to be taken
if (useCookieHandler) {
CookieHandler.setDefault(new CookieManager());
@@ -341,22 +368,25 @@ private HttpURLConnection createConnection(URL url) throws IOException {
// build connection
if ("https".equalsIgnoreCase(url.getProtocol())) {
HttpsURLConnection sConn = (HttpsURLConnection) url.openConnection();
- if (sslSocketFactory != null) sConn.setSSLSocketFactory(sslSocketFactory);
+ if (sslSocketFactory != null)
+ sConn.setSSLSocketFactory(sslSocketFactory);
return sConn;
} else {
return (HttpURLConnection) url.openConnection();
}
}
-
/**
* Initializes and executes the connection
- * @param conn COnnection to the end server
+ *
+ * @param conn COnnection to the end server
* @param postData data to send to the server
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
- * @throws IOException When data can't be retrieved, this exception is thrown
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE.
+ * @throws IOException When data can't be retrieved, this exception is thrown
*/
- private void executeConnection(HttpURLConnection conn, byte[] postDataBytes, HttpConnectionType type) throws IOException {
+ private void executeConnection(HttpURLConnection conn, byte[] postDataBytes, HttpConnectionType type)
+ throws IOException {
// Setup the connection parameters
initConnection(conn, postDataBytes, type);
@@ -364,24 +394,26 @@ private void executeConnection(HttpURLConnection conn, byte[] postDataBytes, Htt
conn.connect();
responseCode = conn.getResponseCode();
- //Parse header information
+ // Parse header information
storeCookies(conn);
}
-
+
/**
* Initializes the Connection parameters
- * @param conn Connecton to the server to be initialized
+ *
+ * @param conn Connecton to the server to be initialized
* @param postData Data to post to the end server
- * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
- * @throws IOException When data can't be retrieved, this exception is thrown
+ * @param type Request Type. One of GET, POST, HEAD, OPTIONS, PUT, DELETE,
+ * TRACE.
+ * @throws IOException When data can't be retrieved, this exception is thrown
*/
- private void initConnection(HttpURLConnection conn, byte[] postDataBytes, HttpConnectionType type)
- throws IOException {
+ private void initConnection(HttpURLConnection conn, byte[] postDataBytes, HttpConnectionType type)
+ throws IOException {
// set additional common connection properties
conn.setDoOutput(true);
conn.setReadTimeout(connectionTimeout > 0 ? connectionTimeout : DEFAULT_SOCKET_TIMEOUT);
conn.setConnectTimeout(connectionTimeout > 0 ? connectionTimeout : DEFAULT_SOCKET_TIMEOUT);
- conn.setUseCaches (false);
+ conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
HttpURLConnection.setFollowRedirects(followRedirects);
conn.setInstanceFollowRedirects(followRedirects);
@@ -397,41 +429,43 @@ private void initConnection(HttpURLConnection conn, byte[] postDataBytes, HttpCo
conn.setRequestMethod(type.toString());
if (HttpConnectionType.POST.equals(type) || HttpConnectionType.PUT.equals(type)) {
- if (! requestHeaders.containsKey(REQUEST_PROPERTY_CONTENT_TYPE))
- conn.setRequestProperty(REQUEST_PROPERTY_CONTENT_TYPE,"application/x-www-form-urlencoded");
-
+ if (!requestHeaders.containsKey(REQUEST_PROPERTY_CONTENT_TYPE))
+ conn.setRequestProperty(REQUEST_PROPERTY_CONTENT_TYPE, "application/x-www-form-urlencoded");
+
conn.setRequestProperty(REQUEST_PROPERTY_CONTENT_LENGTH, Integer.toString(postDataBytes.length));
try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
out.write(postDataBytes);
}
}
}
-
+
/**
- * Parses the returned Set-Cookie parameter in the header into name value
- * pairs and stores them in a hash map to be used during future connections.
+ * Parses the returned Set-Cookie parameter in the header into name value pairs
+ * and stores them in a hash map to be used during future connections.
+ *
* @param conn Connection to the server to retrieve / assign cookies
*/
void storeCookies(HttpURLConnection conn) {
- //Loop all of the HTTP header info
+ // Loop all of the HTTP header info
int c = 0;
while (conn.getHeaderField(c) != null) {
// Store each header param in the headerMap collection
String key = conn.getHeaderFieldKey(c);
String value = StringUtil.defaultString(conn.getHeaderField(c));
headerMap.put(key, value);
-
+
// Find the Set-Cookie parameters
if (COOKIE_HEADER_NAME.equalsIgnoreCase(key)) {
// Parse out the data
int length = value.indexOf(COOKIE_DELIMITER);
- if (length < 0) length = value.length();
+ if (length < 0)
+ length = value.length();
value = value.substring(0, length);
// Parse out the name/value pairs
int sepVal = value.indexOf(COOKIE_VALUE_DELIMITER);
if (sepVal > -1) {
- String valueKey = value.substring(0,sepVal);
+ String valueKey = value.substring(0, sepVal);
String valueVal = value.substring(sepVal + 1, value.length());
addCookie(valueKey, valueVal);
}
@@ -443,52 +477,58 @@ void storeCookies(HttpURLConnection conn) {
// Add the Response Code
headerMap.put(RESPONSE_CODE, Integer.toString(responseCode));
}
-
+
/**
* Converts the map data into a url encoded string and converts to a byte[]
+ *
* @param postData Converts map of data elements into a delimited string
* @return URL encoded data parameters
*/
public byte[] convertPostData(Map postData) {
- if (postData == null || postData.isEmpty()) return new byte[0];
+ if (postData == null || postData.isEmpty())
+ return new byte[0];
StringBuilder sb = new StringBuilder(512);
-
- //convert the postData Map to URL-encoded UTF-8 key=value pairs
+
+ // convert the postData Map to URL-encoded UTF-8 key=value pairs
for (Entry entry : postData.entrySet()) {
- if(sb.length() > 0) sb.append('&');
-
- if(entry.getValue() instanceof Object[] || entry.getValue() instanceof Collection)
+ if (sb.length() > 0)
+ sb.append('&');
+
+ if (entry.getValue() instanceof Object[] || entry.getValue() instanceof Collection)
listParams(sb, entry);
else {
String value = StringUtil.defaultString(entry.getValue() + "", "");
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(value, StandardCharsets.UTF_8));
}
}
-
+
return sb.toString().getBytes(StandardCharsets.UTF_8);
}
/**
* Helper method ensures that multiple values for a given key get added
* correctly.
- * @param sb assigns key values into the string builder
+ *
+ * @param sb assigns key values into the string builder
* @param entry items to assign
*/
private void listParams(StringBuilder sb, Entry entry) {
Object raw = entry.getValue();
String key = entry.getKey();
- Object[] values = (raw instanceof Collection) ? ((Collection>)raw).toArray() : (Object[]) raw;
+ Object[] values = (raw instanceof Collection) ? ((Collection>) raw).toArray() : (Object[]) raw;
int i = 0;
- for(Object o : values) {
- if(i > 0) sb.append("&");
+ for (Object o : values) {
+ if (i > 0)
+ sb.append("&");
sb.append(key).append('=').append(URLEncoder.encode(o.toString(), StandardCharsets.UTF_8));
i++;
}
}
-
+
/**
* Sets the factory for the SSL connection
+ *
* @param sslSocketFactory the sslSocketFactory to set
*/
public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
@@ -497,6 +537,7 @@ public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
/**
* Returns the socket factory
+ *
* @return sslSocketFactory assigned
*/
public SSLSocketFactory getSslSocketFactory() {
@@ -505,6 +546,7 @@ public SSLSocketFactory getSslSocketFactory() {
/**
* Gets the connection timeout
+ *
* @return the connectionTimeout
*/
public int getConnectionTimeout() {
@@ -513,6 +555,7 @@ public int getConnectionTimeout() {
/**
* Determines if this class will follow redirects
+ *
* @return the followRedirects
*/
public boolean isFollowRedirects() {
@@ -521,6 +564,7 @@ public boolean isFollowRedirects() {
/**
* Gets the request headers
+ *
* @return the requestHeaders
*/
public Map getRequestHeaders() {
@@ -529,6 +573,7 @@ public Map getRequestHeaders() {
/**
* Gets the onnection response code
+ *
* @return the responseCode
*/
public int getResponseCode() {
@@ -537,6 +582,7 @@ public int getResponseCode() {
/**
* Gets the cookies
+ *
* @return the cookies
*/
public Map getCookies() {
@@ -545,6 +591,7 @@ public Map getCookies() {
/**
* Gets the header maps
+ *
* @return the headerMap
*/
public Map getHeaderMap() {
@@ -553,6 +600,7 @@ public Map getHeaderMap() {
/**
* Number of redirects to foloow
+ *
* @return the redirectLimit
*/
public int getRedirectLimit() {
@@ -561,6 +609,7 @@ public int getRedirectLimit() {
/**
* Determines if cookie handler is in use
+ *
* @return the useCookieHandler
*/
public boolean isUseCookieHandler() {
@@ -569,6 +618,7 @@ public boolean isUseCookieHandler() {
/**
* Sets the connection timeout
+ *
* @param connectionTimeout the connectionTimeout to set
*/
public void setConnectionTimeout(int connectionTimeout) {
@@ -577,6 +627,7 @@ public void setConnectionTimeout(int connectionTimeout) {
/**
* Sets whether redirects should be followed
+ *
* @param followRedirects the followRedirects to set
*/
public void setFollowRedirects(boolean followRedirects) {
@@ -585,35 +636,42 @@ public void setFollowRedirects(boolean followRedirects) {
/**
* Sets request headers for the connection
+ *
* @param requestHeaders the requestHeaders to set
*/
public void setRequestHeaders(Map requestHeaders) {
- if (requestHeaders == null) this.requestHeaders.clear();
- else this.requestHeaders = requestHeaders;
+ if (requestHeaders == null)
+ this.requestHeaders.clear();
+ else
+ this.requestHeaders = requestHeaders;
}
-
+
/**
* Adds any request headers assigned to the request connection
+ *
* @param conn Connection to the end server
*/
protected void setRequestHeaders(HttpURLConnection conn) {
- if (requestHeaders.isEmpty()) return;
- for (Map.Entry entry: requestHeaders.entrySet())
+ if (requestHeaders.isEmpty())
+ return;
+ for (Map.Entry entry : requestHeaders.entrySet())
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
-
+
/**
* Adds a request header that will be passed on the request
+ *
* @param key
* @param value
*/
public void addRequestHeader(String key, String value) {
requestHeaders.put(key, value);
}
-
+
/**
* Adds a header map value for the HTTP connection
- * @param key Cookie unique identifier
+ *
+ * @param key Cookie unique identifier
* @param value Cookie value
*/
public void addCookie(String key, String value) {
@@ -622,25 +680,30 @@ public void addCookie(String key, String value) {
/**
* Map containing multiple cookies to add
+ *
* @param cookies the cookies to set
*/
public void setCookies(Map cookies) {
- if (cookies == null) this.cookies.clear();
- else this.cookies = cookies;
+ if (cookies == null)
+ this.cookies.clear();
+ else
+ this.cookies = cookies;
}
-
+
/**
- * Adds any cookies from the collection of stored cookies and formats
- * the data into: Cookie: name=value; name=value;
- * Do not use this to initially add cookies to the cookie map on this object, rather
- * use the addCookie(key,value) method.
+ * Adds any cookies from the collection of stored cookies and formats the data
+ * into: Cookie: name=value; name=value; Do not use this to initially add
+ * cookies to the cookie map on this object, rather use the addCookie(key,value)
+ * method.
+ *
* @param conn Connection to the end server
*/
void assignCookies(HttpURLConnection conn) {
- if (cookies.isEmpty() || conn == null) return;
+ if (cookies.isEmpty() || conn == null)
+ return;
StringBuilder sb = new StringBuilder(250);
- for (Map.Entry entry: cookies.entrySet())
+ for (Map.Entry entry : cookies.entrySet())
sb.append(entry.getKey()).append(COOKIE_VALUE_DELIMITER).append(entry.getValue()).append(COOKIE_DELIMITER);
conn.addRequestProperty(COOKIE_NAME, sb.toString());
@@ -648,15 +711,19 @@ void assignCookies(HttpURLConnection conn) {
/**
* Adds parameters to the header map
+ *
* @param headerMap the headerMap to set
*/
public void setHeaderMap(Map headerMap) {
- if (headerMap == null) this.headerMap.clear();
- else this.headerMap = headerMap;
+ if (headerMap == null)
+ this.headerMap.clear();
+ else
+ this.headerMap = headerMap;
}
/**
* Number of redirects to follow before quitting
+ *
* @param redirectLimit the redirectLimit to set
*/
public void setRedirectLimit(int redirectLimit) {
@@ -665,9 +732,103 @@ public void setRedirectLimit(int redirectLimit) {
/**
* Sets whether the cookie handler should be used
+ *
* @param useCookieHandler the useCookieHandler to set
*/
public void setUseCookieHandler(boolean useCookieHandler) {
this.useCookieHandler = useCookieHandler;
}
+
+ /**
+ * Build a URI without the need for Path Parameter Replacement
+ * @param endpoint
+ * @param urlPath
+ * @return
+ * @throws IllegalArgumentException
+ */
+ public String buildUri(String endpoint, String urlPath) throws IllegalArgumentException {
+ return this.buildUriWithParams(endpoint, urlPath, null);
+ }
+
+ /**
+ * Build the Uri that requires Path Parameter Replacement
+ *
+ * @param endpoint
+ * @param urlPath
+ * @param urlParams
+ * @return Url String with all placeholders replaced with urlParams
+ * @throws OEException
+ */
+ public String buildUriWithParams(String endpoint, String urlPath, List