From 81c72a726278aa9ec6db744a5894fe645bc43ed9 Mon Sep 17 00:00:00 2001 From: bipster Date: Sat, 23 Feb 2019 23:45:50 -0500 Subject: [PATCH 1/5] Introducing telescoping constructor to ease the creation of new constructors later. --- .../com/semantics3/api/Semantics3Request.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/semantics3/api/Semantics3Request.java b/src/main/java/com/semantics3/api/Semantics3Request.java index f3c3b87..5102251 100644 --- a/src/main/java/com/semantics3/api/Semantics3Request.java +++ b/src/main/java/com/semantics3/api/Semantics3Request.java @@ -32,24 +32,9 @@ public class Semantics3Request{ private StringBuffer urlBuilder; public Semantics3Request(String apiKey, String apiSecret, String endpoint) { - if (apiKey == null) { - throw new Semantics3Exception( - "API Credentials Missing", - "You did not supply an apiKey. Please sign up at https://semantics3.com/ to obtain your api_key." - ); - } - if (apiSecret == null) { - throw new Semantics3Exception( - "API Credentials Missing", - "You did not supply an apiSecret. Please sign up at https://semantics3.com/ to obtain your api_key." - ); - } + this(apiKey, apiSecret); - this.apiKey = apiKey; - this.apiSecret = apiSecret; - this.endpoint = endpoint; - this.consumer = new DefaultOAuthConsumer(apiKey, apiSecret); - consumer.setTokenWithSecret("", ""); + this.endpoint = endpoint; } public Semantics3Request(String apiKey, String apiSecret) { From 7790c7f0ff152e1b8a4fe191db2423a1e5e43654 Mon Sep 17 00:00:00 2001 From: bipster Date: Sat, 23 Feb 2019 23:51:10 -0500 Subject: [PATCH 2/5] New constructors to allow user to pass in properties to be set to the underlying HttpURLConnection object. Using new ConnectionProperties class so that additional properties might be added later without requiring changed/new constructors. --- .../semantics3/api/ConnectionProperties.java | 25 +++++++++++++++++++ .../com/semantics3/api/Semantics3Request.java | 14 +++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/main/java/com/semantics3/api/ConnectionProperties.java diff --git a/src/main/java/com/semantics3/api/ConnectionProperties.java b/src/main/java/com/semantics3/api/ConnectionProperties.java new file mode 100644 index 0000000..472b522 --- /dev/null +++ b/src/main/java/com/semantics3/api/ConnectionProperties.java @@ -0,0 +1,25 @@ +package com.semantics3.api; + +public class ConnectionProperties { + private static final int DEFAULT_NO_TIMEOUT = 0; + + private int readTimeout = DEFAULT_NO_TIMEOUT; + private int connectionTimeout = DEFAULT_NO_TIMEOUT; + + + public int getReadTimeout() { + return readTimeout; + } + + public void setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } +} diff --git a/src/main/java/com/semantics3/api/Semantics3Request.java b/src/main/java/com/semantics3/api/Semantics3Request.java index 5102251..ede38de 100644 --- a/src/main/java/com/semantics3/api/Semantics3Request.java +++ b/src/main/java/com/semantics3/api/Semantics3Request.java @@ -16,6 +16,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; +import java.sql.Connection; import java.util.HashMap; public class Semantics3Request{ @@ -30,6 +31,19 @@ public class Semantics3Request{ private HashMap query = new HashMap(); private JSONObject queryResult; private StringBuffer urlBuilder; + private ConnectionProperties connectionProperties; + + public Semantics3Request(String apiKey, String apiSecret, String endpoint, ConnectionProperties connectionProperties) { + this(apiKey, apiSecret, endpoint); + + this.connectionProperties = connectionProperties; + } + + public Semantics3Request(String apiKey, String apiSecret, ConnectionProperties connectionProperties) { + this(apiKey, apiSecret); + + this.connectionProperties = connectionProperties; + } public Semantics3Request(String apiKey, String apiSecret, String endpoint) { this(apiKey, apiSecret); From 6e63e0e6d7499e6bdff8ced5973669f013446656 Mon Sep 17 00:00:00 2001 From: bipster Date: Sat, 23 Feb 2019 23:56:48 -0500 Subject: [PATCH 3/5] Extracted common code to builder class, and setting the new connection properties there. --- .../com/semantics3/api/ConnectionBuilder.java | 25 +++++++++++++++++++ .../com/semantics3/api/Semantics3Request.java | 14 +++-------- 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/semantics3/api/ConnectionBuilder.java diff --git a/src/main/java/com/semantics3/api/ConnectionBuilder.java b/src/main/java/com/semantics3/api/ConnectionBuilder.java new file mode 100644 index 0000000..65e11a2 --- /dev/null +++ b/src/main/java/com/semantics3/api/ConnectionBuilder.java @@ -0,0 +1,25 @@ +package com.semantics3.api; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URISyntaxException; +import java.net.URL; + +public class ConnectionBuilder { + private static final String USER_AGENT_KEY = "User-Agent"; + private static final String USER_AGENT_VALUE = "Semantics3 Java Library"; + + public HttpURLConnection buildConnection(String req, ConnectionProperties connectionProperties) + throws IOException, URISyntaxException { + URL url = new URL(req); + url = url.toURI().normalize().toURL(); + + HttpURLConnection request = (HttpURLConnection) url.openConnection(); + request.setRequestProperty(USER_AGENT_KEY, USER_AGENT_VALUE); + + request.setConnectTimeout(connectionProperties.getConnectionTimeout()); + request.setReadTimeout(connectionProperties.getReadTimeout()); + + return request; + } +} diff --git a/src/main/java/com/semantics3/api/Semantics3Request.java b/src/main/java/com/semantics3/api/Semantics3Request.java index ede38de..dfc527f 100644 --- a/src/main/java/com/semantics3/api/Semantics3Request.java +++ b/src/main/java/com/semantics3/api/Semantics3Request.java @@ -14,9 +14,7 @@ import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URISyntaxException; -import java.net.URL; import java.net.URLEncoder; -import java.sql.Connection; import java.util.HashMap; public class Semantics3Request{ @@ -38,7 +36,7 @@ public Semantics3Request(String apiKey, String apiSecret, String endpoint, Conne this.connectionProperties = connectionProperties; } - + public Semantics3Request(String apiKey, String apiSecret, ConnectionProperties connectionProperties) { this(apiKey, apiSecret); @@ -82,10 +80,7 @@ protected JSONObject fetch(String endpoint, String params) throws .append("?q=") .append(URLEncoder.encode(params, "UTF-8")) .toString(); - URL url = new URL(req); - url = url.toURI().normalize().toURL(); - HttpURLConnection request = (HttpURLConnection) url.openConnection(); - request.setRequestProperty("User-Agent", "Semantics3 Java Library"); + HttpURLConnection request = new ConnectionBuilder().buildConnection(req, this.connectionProperties); consumer.sign(request); request.connect(); try { @@ -118,10 +113,7 @@ protected JSONObject fetch(String endpoint, String method, HashMap Date: Sun, 24 Feb 2019 00:36:38 -0500 Subject: [PATCH 4/5] The telescoping constructors were in the wrong direction; reversing makes the defaults clearer. Also fixes bug wherein connection properties weren't being given a default value when using the existing constructors. --- .../com/semantics3/api/Semantics3Request.java | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/semantics3/api/Semantics3Request.java b/src/main/java/com/semantics3/api/Semantics3Request.java index dfc527f..6cc1146 100644 --- a/src/main/java/com/semantics3/api/Semantics3Request.java +++ b/src/main/java/com/semantics3/api/Semantics3Request.java @@ -32,41 +32,38 @@ public class Semantics3Request{ private ConnectionProperties connectionProperties; public Semantics3Request(String apiKey, String apiSecret, String endpoint, ConnectionProperties connectionProperties) { - this(apiKey, apiSecret, endpoint); + if (apiKey == null) { + throw new Semantics3Exception( + "API Credentials Missing", + "You did not supply an apiKey. Please sign up at https://semantics3.com/ to obtain your api_key." + ); + } + if (apiSecret == null) { + throw new Semantics3Exception( + "API Credentials Missing", + "You did not supply an apiSecret. Please sign up at https://semantics3.com/ to obtain your api_key." + ); + } + this.apiKey = apiKey; + this.apiSecret = apiSecret; + this.consumer = new DefaultOAuthConsumer(apiKey, apiSecret); + consumer.setTokenWithSecret("", ""); + + this.endpoint = endpoint; this.connectionProperties = connectionProperties; } public Semantics3Request(String apiKey, String apiSecret, ConnectionProperties connectionProperties) { - this(apiKey, apiSecret); - - this.connectionProperties = connectionProperties; + this(apiKey, apiSecret, null, connectionProperties); } public Semantics3Request(String apiKey, String apiSecret, String endpoint) { - this(apiKey, apiSecret); - - this.endpoint = endpoint; + this(apiKey, apiSecret, endpoint, new ConnectionProperties()); } public Semantics3Request(String apiKey, String apiSecret) { - if (apiKey == null) { - throw new Semantics3Exception( - "API Credentials Missing", - "You did not supply an apiKey. Please sign up at https://semantics3.com/ to obtain your api_key." - ); - } - if (apiSecret == null) { - throw new Semantics3Exception( - "API Credentials Missing", - "You did not supply an apiSecret. Please sign up at https://semantics3.com/ to obtain your api_key." - ); - } - - this.apiKey = apiKey; - this.apiSecret = apiSecret; - this.consumer = new DefaultOAuthConsumer(apiKey, apiSecret); - consumer.setTokenWithSecret("", ""); + this(apiKey, apiSecret, null, new ConnectionProperties()); } protected JSONObject fetch(String endpoint, String params) throws From 8ae654f7168ed0acfa54dc58606e9a534dc192f2 Mon Sep 17 00:00:00 2001 From: bipster Date: Sun, 24 Feb 2019 15:48:17 -0500 Subject: [PATCH 5/5] Letting SocketTimeoutException propagate (as an IOException subclass, this was resulting in an NPE instead as the exception handler attempted to process the request anyway). --- src/main/java/com/semantics3/api/Semantics3Request.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/semantics3/api/Semantics3Request.java b/src/main/java/com/semantics3/api/Semantics3Request.java index 6cc1146..eae2205 100644 --- a/src/main/java/com/semantics3/api/Semantics3Request.java +++ b/src/main/java/com/semantics3/api/Semantics3Request.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; +import java.net.SocketTimeoutException; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.HashMap; @@ -87,6 +88,9 @@ protected JSONObject fetch(String endpoint, String params) throws } return json; } + catch (SocketTimeoutException e) { + throw e; + } catch (IOException e) { InputStream error = ((HttpURLConnection) request).getErrorStream(); JSONObject json = new JSONObject(new JSONTokener(error)); @@ -136,6 +140,9 @@ protected JSONObject fetch(String endpoint, String method, HashMap