diff --git a/.gitignore b/.gitignore
index d40a9d7..6ced83a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,9 +29,10 @@ proguard/
.gradletasknamecache
.gradle
.gradle/
+gradle.properties
+
build/
bin/
-gradle.properties
/.vs/VSWorkspaceState.json
/.vs/socketlabs-java/v17/TestStore/0/testlog.manifest
/.vs/socketlabs-java/v17/TestStore/0/000.testlog
diff --git a/examples/build.gradle b/examples/build.gradle
index fcf2b44..fd674c9 100644
--- a/examples/build.gradle
+++ b/examples/build.gradle
@@ -8,13 +8,17 @@ version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
- mavenLocal()
mavenCentral()
+ maven {
+ url = uri("https://central.sonatype.com/repository/maven-snapshots/")
+ }
+ mavenLocal()
}
dependencies {
- testCompile group: 'junit', name: 'junit', version: '4.9.2'
compile 'com.fasterxml.jackson.core:jackson-core:2.14.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.14.0'
- compile group: 'com.socketlabs', name: 'injectionApi', version: '1.4.2'
+ compile 'org.apache.httpcomponents:httpclient:4.5.14'
+ compile 'org.apache.httpcomponents:httpasyncclient:4.1.5'
+ compile group: 'com.socketlabs', name: 'injectionApi', version: '2.0.1-SNAPSHOT'
}
diff --git a/examples/gradle/wrapper/gradle-wrapper.jar b/examples/gradle/wrapper/gradle-wrapper.jar
index 1948b90..457aad0 100644
Binary files a/examples/gradle/wrapper/gradle-wrapper.jar and b/examples/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/examples/gradle/wrapper/gradle-wrapper.properties b/examples/gradle/wrapper/gradle-wrapper.properties
index a833f72..75b8c7c 100644
--- a/examples/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu Jun 18 12:46:49 EDT 2020
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/examples/gradlew b/examples/gradlew
index cccdd3d..af6708f 100644
--- a/examples/gradlew
+++ b/examples/gradlew
@@ -28,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
diff --git a/examples/gradlew.bat b/examples/gradlew.bat
index f955316..6d57edc 100644
--- a/examples/gradlew.bat
+++ b/examples/gradlew.bat
@@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
diff --git a/examples/src/main/java/examples/Main.java b/examples/src/main/java/examples/Main.java
index 4de3a66..d33b1a0 100644
--- a/examples/src/main/java/examples/Main.java
+++ b/examples/src/main/java/examples/Main.java
@@ -59,22 +59,24 @@ private static void DisplayTheMenu() {
System.out.println(" 10: Basic Async With Retry");
System.out.println(" 11: Basic Send With Retry ");
System.out.println(" 12: Basic Send Complex Example ");
+ System.out.println(" 13: Basic Send With HttpClient ");
+ System.out.println(" 14: Basic Send With HttpAsyncClient ");
System.out.println();
System.out.println(" Validation Error Handling Examples: ");
- System.out.println(" 13: Basic Send With Invalid Attachment");
- System.out.println(" 14: Basic Send With Invalid From ");
- System.out.println(" 15: Basic Send With Invalid Recipients ");
+ System.out.println(" 15: Basic Send With Invalid Attachment");
+ System.out.println(" 16: Basic Send With Invalid From ");
+ System.out.println(" 17: Basic Send With Invalid Recipients ");
System.out.println();
System.out.println(" Bulk Send Examples: ");
- System.out.println(" 16: Bulk Send ");
- System.out.println(" 17: Bulk Send With MergeData ");
- System.out.println(" 18: Bulk Send With ASCII Charset And Merge Data ");
- System.out.println(" 19: Bulk Send From DataSource With Merge Data ");
- System.out.println(" 20: Bulk Send Complex Example ");
+ System.out.println(" 18: Bulk Send ");
+ System.out.println(" 19: Bulk Send With MergeData ");
+ System.out.println(" 20: Bulk Send With ASCII Charset And Merge Data ");
+ System.out.println(" 21: Bulk Send From DataSource With Merge Data ");
+ System.out.println(" 22: Bulk Send Complex Example ");
System.out.println();
System.out.println(" AMP Html Examples: ");
- System.out.println(" 21: Basic Send With Amp Body Example ");
- System.out.println(" 22: Bulk Send With Amp Body Example ");
+ System.out.println(" 23: Basic Send With Amp Body Example ");
+ System.out.println(" 24: Bulk Send With Amp Body Example ");
System.out.println();
@@ -104,17 +106,19 @@ private static String GetExampleName(String selection) {
case 10: return "examples.basic.BasicAsyncWithRetry";
case 11: return "examples.basic.BasicSendWithRetry";
case 12: return "examples.basic.BasicSendComplexExample";
- case 13: return "examples.basic.invalid.BasicSendWithInvalidAttachment";
- case 14: return "examples.basic.invalid.BasicSendWithInvalidFrom";
- case 15: return "examples.basic.invalid.BasicSendWithInvalidRecipients";
-
- case 16: return "examples.bulk.BulkSend";
- case 17: return "examples.bulk.BulkSendWithMergeData";
- case 18: return "examples.bulk.BulkSendWithASCIICharsetMergeData";
- case 19: return "examples.bulk.BulkSendFromDataSourceWithMerge";
- case 20: return "examples.bulk.BulkSendComplexExample";
- case 21: return "examples.basic.BasicSendWithAmpBodyExample";
- case 22: return "examples.bulk.BulkSendWithAmpBodyExample";
+ case 13: return "examples.basic.BasicSendWithHttpClient";
+ case 14: return "examples.basic.BasicSendWithHttpAsyncClient";
+ case 15: return "examples.basic.invalid.BasicSendWithInvalidAttachment";
+ case 16: return "examples.basic.invalid.BasicSendWithInvalidFrom";
+ case 17: return "examples.basic.invalid.BasicSendWithInvalidRecipients";
+
+ case 18: return "examples.bulk.BulkSend";
+ case 19: return "examples.bulk.BulkSendWithMergeData";
+ case 20: return "examples.bulk.BulkSendWithASCIICharsetMergeData";
+ case 21: return "examples.bulk.BulkSendFromDataSourceWithMerge";
+ case 22: return "examples.bulk.BulkSendComplexExample";
+ case 23: return "examples.basic.BasicSendWithAmpBodyExample";
+ case 24: return "examples.bulk.BulkSendWithAmpBodyExample";
default:
System.out.println("Invalid Input (Out of Range)");
return null;
diff --git a/examples/src/main/java/examples/basic/BasicAsync.java b/examples/src/main/java/examples/basic/BasicAsync.java
index 7b3fb6c..32d1dd9 100644
--- a/examples/src/main/java/examples/basic/BasicAsync.java
+++ b/examples/src/main/java/examples/basic/BasicAsync.java
@@ -8,7 +8,6 @@
import com.socketLabs.injectionApi.message.BasicMessage;
import com.socketLabs.injectionApi.message.EmailAddress;
import examples.*;
-import okhttp3.Call;
import java.io.IOException;
diff --git a/examples/src/main/java/examples/basic/BasicSendWithHttpAsyncClient.java b/examples/src/main/java/examples/basic/BasicSendWithHttpAsyncClient.java
new file mode 100644
index 0000000..eee7859
--- /dev/null
+++ b/examples/src/main/java/examples/basic/BasicSendWithHttpAsyncClient.java
@@ -0,0 +1,84 @@
+package examples.basic;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.socketLabs.injectionApi.SendResponse;
+import com.socketLabs.injectionApi.SocketLabsClient;
+import com.socketLabs.injectionApi.core.SendAsyncCallback;
+import com.socketLabs.injectionApi.message.BasicMessage;
+import com.socketLabs.injectionApi.message.EmailAddress;
+import examples.*;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
+import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+
+import java.io.IOException;
+
+public class BasicSendWithHttpAsyncClient implements Example {
+
+ @Override
+ public SendResponse RunExample() throws Exception {
+
+ BasicMessage message = new BasicMessage();
+
+ message.setSubject("Sending A Test Message (Basic Send Async)");
+ message.setHtmlBody("
Sending A Test Message
This is the Html Body of my message.
");
+ message.setPlainTextBody("This is the Plain Text Body of my message.");
+
+ message.setFrom(new EmailAddress("from@example.com"));
+ message.addToEmailAddress("recipient1@example.com");
+
+ // create the HttpClient
+ final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
+ PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
+ cm.setMaxTotal(200);
+ cm.setDefaultMaxPerRoute(20);
+
+ RequestConfig requestConfig =RequestConfig.custom()
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(5000)
+ .setSocketTimeout(5000)
+ .build();
+
+ CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
+ .setConnectionManager(cm)
+ .setDefaultRequestConfig(requestConfig)
+ .build();
+
+ // create the client
+ SocketLabsClient client = new SocketLabsClient(ExampleConfig.ServerId, ExampleConfig.ApiKey);
+
+ // send the message
+ client.sendAsync(message, httpClient, new SendAsyncCallback() {
+
+ @Override
+ public void onError(Exception ex) {
+ // Handle Exception here
+ ex.printStackTrace();
+ return;
+ }
+
+ @Override
+ public void onResponse(SendResponse response) throws IOException {
+ // Handle SendResponse here
+
+ ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
+
+ System.out.println("Response body : ");
+ System.out.println(mapper.writeValueAsString(response));
+ System.out.println();
+ System.out.println();
+ System.out.println("Enter a number (or QUIT to exit):");
+
+ return;
+
+ }
+ });
+
+ System.out.println("Waiting for response...");
+ return null;
+ }
+}
diff --git a/examples/src/main/java/examples/basic/BasicSendWithHttpClient.java b/examples/src/main/java/examples/basic/BasicSendWithHttpClient.java
new file mode 100644
index 0000000..7f7c26e
--- /dev/null
+++ b/examples/src/main/java/examples/basic/BasicSendWithHttpClient.java
@@ -0,0 +1,53 @@
+package examples.basic;
+
+import com.socketLabs.injectionApi.SendResponse;
+import com.socketLabs.injectionApi.SocketLabsClient;
+import com.socketLabs.injectionApi.message.BasicMessage;
+import com.socketLabs.injectionApi.message.EmailAddress;
+import examples.*;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+
+
+public class BasicSendWithHttpClient implements Example {
+
+ public SendResponse RunExample () throws Exception {
+
+ BasicMessage message = new BasicMessage();
+
+ message.setSubject("Sending An Email Through A Proxy");
+ message.setHtmlBody("Sending An Email Through A Proxy
This is the Html Body of my message.
");
+ message.setPlainTextBody("This is the Plain Text Body of my message.");
+
+ message.setFrom(new EmailAddress("from@example.com"));
+ message.addToEmailAddress("recipient1@example.com");
+
+ // create the HttpClient
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+ cm.setMaxTotal(200);
+ cm.setDefaultMaxPerRoute(20);
+ cm.setValidateAfterInactivity(10000);
+
+ RequestConfig requestConfig =RequestConfig.custom()
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(5000)
+ .setSocketTimeout(5000)
+ .build();
+
+ CloseableHttpClient httpClient = HttpClients.custom()
+ .setConnectionManager(cm)
+ .setDefaultRequestConfig(requestConfig)
+ .build();
+
+ // create the client
+ SocketLabsClient client = new SocketLabsClient(ExampleConfig.ServerId, ExampleConfig.ApiKey);
+
+ // send the message
+ SendResponse response = client.send(message, httpClient);
+
+ return response;
+
+ }
+}
diff --git a/injectionApi/build.gradle b/injectionApi/build.gradle
index 737b858..ae6a95a 100644
--- a/injectionApi/build.gradle
+++ b/injectionApi/build.gradle
@@ -4,40 +4,53 @@ plugins {
id 'maven-publish'
id 'signing'
}
+
+def baseTitle ="SocketLabs Java"
def baseGroupId = "com.socketlabs"
-def baseArtifactId = 'injectionApi'
-def computeVersion() {
- def baseVersion = "1.4.4"
+def baseArtifactId = "injectionApi"
+
+static def computeVersion() {
+ def baseVersion = "2.0.1"
def release = true
if (release)
return "${baseVersion}"
else
return "${baseVersion}-SNAPSHOT"
}
+
group "${baseGroupId}"
version = computeVersion()
+
sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
repositories {
mavenCentral()
mavenLocal()
}
+
compileJava {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
+
dependencies {
compile 'com.fasterxml.jackson.core:jackson-core:2.14.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.14.0'
compile group: 'com.google.guava', name: 'guava', version: '32.1.3-jre'
- compile 'com.squareup.okhttp3:okhttp:4.10.0'
-
+ compile 'org.apache.httpcomponents:httpclient:4.5.14'
+ compile 'org.apache.httpcomponents:httpasyncclient:4.1.5'
}
+
jar {
manifest {
- attributes 'Implementation-Title': 'SocketLabs Java',
+ attributes(
+ 'Implementation-Title': baseTitle,
'Implementation-Version': version
+ )
}
}
+
signing {
required { gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
@@ -59,19 +72,21 @@ artifacts {
archives sourceJar
archives packageJavadoc
}
+
+def mavenReleaseUrl = "file://projects/build/repo/release"
+def mavenSnapshotUrl = "file://projects/build/repo/snapshot"
+
+// def mavenReleaseUrl = "https://ossrh-staging-api.central.sonatype.com/service/local/"
+// def mavenSnapshotUrl = "https://central.sonatype.com/repository/maven-snapshots/"
+
uploadArchives {
repositories {
mavenDeployer {
+
beforeDeployment {
MavenDeployment deployment -> signing.signPom(deployment)
}
-
- repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
- authentication(userName: sonatypeUsername, password: sonatypePassword)
- }
- snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots") {
- authentication(userName: sonatypeUsername, password: sonatypePassword)
- }
+ repository(url: "file:///projects/build/repo/release")
pom.project {
groupId "${baseGroupId}"
@@ -81,6 +96,7 @@ uploadArchives {
packaging 'jar'
description 'SocketLabs Email Delivery Java library'
url 'https://github.com/socketlabs/socketlabs-java/'
+
organization {
name 'com.socketlabs'
url 'https://github.com/socketlabs'
diff --git a/injectionApi/gradle/wrapper/gradle-wrapper.properties b/injectionApi/gradle/wrapper/gradle-wrapper.properties
index c369bdf..85b4545 100644
--- a/injectionApi/gradle/wrapper/gradle-wrapper.properties
+++ b/injectionApi/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Oct 30 12:53:58 EDT 2018
+#Mon Jun 23 10:40:41 EDT 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
diff --git a/injectionApi/pom.xml b/injectionApi/pom.xml
index a0fc34b..a6d4754 100644
--- a/injectionApi/pom.xml
+++ b/injectionApi/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.socketlabs
injectionApi
- 1.4.2
+ 2.0.1
socketlabs-java
SocketLabs Email Delivery Java library
https://github.com/socketlabs/socketlabs-java/
@@ -23,7 +23,7 @@
david-schrenker
David Schrenker
david.schrenker@socketlabs.com
- org.apache.maven.model.Organization@f125de5
+ org.apache.maven.model.Organization@6817d1b6
Developer
@@ -31,7 +31,7 @@
rbrazuk
Ross Brazuk
- org.apache.maven.model.Organization@19eaf41b
+ org.apache.maven.model.Organization@1d14f04e
Developer
@@ -39,7 +39,7 @@
mike.boshuyzen
Mike Boshuyzen
- org.apache.maven.model.Organization@6c023990
+ org.apache.maven.model.Organization@2ef140cc
Developer
@@ -48,7 +48,7 @@
Ryan Lydzinski
- org.apache.maven.model.Organization@399b8af0
+ org.apache.maven.model.Organization@3b0ef3f7
Intern
@@ -79,13 +79,19 @@
com.google.guava
guava
- 31.1-jre
+ 32.1.3-jre
compile
- com.squareup.okhttp3
- okhttp
- 4.10.0
+ org.apache.httpcomponents
+ httpclient
+ 4.5.14
+ compile
+
+
+ org.apache.httpcomponents
+ httpasyncclient
+ 4.1.5
compile
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClient.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClient.java
index ade1864..f7038ed 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClient.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClient.java
@@ -1,23 +1,45 @@
package com.socketLabs.injectionApi;
+import com.google.common.collect.Lists;
import com.socketLabs.injectionApi.core.*;
import com.socketLabs.injectionApi.core.serialization.InjectionRequestFactory;
import com.socketLabs.injectionApi.core.serialization.InjectionResponseParser;
import com.socketLabs.injectionApi.message.*;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
import java.net.Proxy;
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.Response;
+import java.util.List;
+
+import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
+import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+
/**
* SocketLabsClient is a wrapper for the SocketLabs Injection API that makes it easy to send messages and parse responses.
*/
public class SocketLabsClient implements SocketLabsClientAPI {
- private int serverId;
- private String apiKey;
+ private final int serverId;
+ private final String apiKey;
+ private boolean useBearerAuth = false;
private String endPointUrl = "https://inject.socketlabs.com/api/v1/email";
private Proxy proxy;
private int requestTimeout = 100;
@@ -43,8 +65,19 @@ public void setEndPointUrl(String value) {
*/
public void setNumberOfRetries(int value) { this.numberOfRetries = value; }
- private final String VERSION = "1.0.0";
- private final String userAgent = String.format("SocketLabs-java/%s(%s)", VERSION, Package.getPackage("java.util").getImplementationVersion());
+ private final String VERSION = "2.0.1";
+ private final String JAVA_LANG_VERSION = Package.getPackage("java.lang").getImplementationVersion();
+ private final String JAVA_UTIL_VERSION = Package.getPackage("java.util").getImplementationVersion();
+ private final String JAVA_VERSION = (JAVA_UTIL_VERSION != null) ?JAVA_UTIL_VERSION : JAVA_LANG_VERSION;
+
+ private final String userAgent = String.format("SocketLabs-java/%s(%s)", VERSION, JAVA_VERSION);
+
+ private List getDefaultHeaders() {
+ List headers = Lists.newArrayList(new BasicHeader(HttpHeaders.USER_AGENT, this.userAgent));
+ headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json"));
+ headers.add(new BasicHeader(HttpHeaders.ACCEPT, "application/json"));
+ return headers;
+ }
/**
* Creates a new instance of the SocketLabsClient.
@@ -82,19 +115,45 @@ public SendResponse send(BasicMessage message) throws Exception {
if (result.getResult() != SendResult.Success)
return result;
- HttpRequest request = buildHttpRequest(this.proxy);
+ ApiKeyParser keyParser = new ApiKeyParser();
+ ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
+
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
+
+ CloseableHttpClient client = buildHttpClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+ CloseableHttpResponse response = retryHandler.send(client, httpPost);
+
+ InjectionResponseParser parser = new InjectionResponseParser();
+ return parser.Parse(response);
+ }
+
+ /**
+ * Synchronously sends a basic email message and returns the response from the Injection API.
+ * @param message A BasicMessage object to be sent.
+ * @return A SendResponse of an SocketLabsClient send request.
+ * @param httpClient A CloseableHttpClient instance to use when making http calls.
+ * @throws Exception exception
+ */
+ @Override
+ public SendResponse send(BasicMessage message, CloseableHttpClient httpClient) throws Exception {
+
+ SendResponse result = Validate(message);
+ if (result.getResult() != SendResult.Success)
+ return result;
ApiKeyParser keyParser = new ApiKeyParser();
ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
- if (parseResult != null && parseResult == ApiKeyParseResult.Success)
- {
- request.setHeader("Authorization", "Bearer " + this.apiKey);
- }
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
- request.setBody(new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message));
- RetryHandler retryHandler = new RetryHandler(request, this.endPointUrl, new RetrySettings(this.numberOfRetries));
- Response response = retryHandler.send();
+ CloseableHttpClient client = buildHttpClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+ CloseableHttpResponse response = retryHandler.send(client, httpPost);
InjectionResponseParser parser = new InjectionResponseParser();
return parser.Parse(response);
@@ -113,20 +172,46 @@ public SendResponse send(BulkMessage message) throws Exception {
if (result.getResult() != SendResult.Success)
return result;
- HttpRequest request = buildHttpRequest(this.proxy);
-
ApiKeyParser keyParser = new ApiKeyParser();
ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
- if (parseResult != null && parseResult == ApiKeyParseResult.Success)
- {
- request.setHeader("Authorization", "Bearer " + this.apiKey);
- }
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
+
+ CloseableHttpClient client = buildHttpClient();
+ RetryHandler retryHandler = new RetryHandler( new RetrySettings(this.numberOfRetries));
+ CloseableHttpResponse response = retryHandler.send(client, httpPost);
+
+ InjectionResponseParser parser = new InjectionResponseParser();
+ return parser.Parse(response);
+
+ }
- request.setBody(new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message));
+ /**
+ * Synchronously sends a bulk email message and returns the response from the Injection API.
+ * @param message A BulkMessage object to be sent.
+ * @return A SendResponse of an SocketLabsClient send request.
+ * @param httpClient A CloseableHttpClient instance to use when making http calls.
+ * @throws Exception exception
+ */
+ @Override
+ public SendResponse send(BulkMessage message, CloseableHttpClient httpClient) throws Exception {
- RetryHandler retryHandler = new RetryHandler(request, this.endPointUrl, new RetrySettings(this.numberOfRetries));
- Response response = retryHandler.send();
+ SendResponse result = Validate(message);
+ if (result.getResult() != SendResult.Success)
+ return result;
+
+ ApiKeyParser keyParser = new ApiKeyParser();
+ ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
+
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
+
+ CloseableHttpClient client = buildHttpClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+ CloseableHttpResponse response = retryHandler.send(client, httpPost);
InjectionResponseParser parser = new InjectionResponseParser();
return parser.Parse(response);
@@ -148,29 +233,84 @@ public void sendAsync(BasicMessage message, final SendAsyncCallback callback) th
return;
}
- HttpRequest request = buildHttpRequest(this.proxy);
-
ApiKeyParser keyParser = new ApiKeyParser();
ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
+
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
- if (parseResult != null && parseResult == ApiKeyParseResult.Success)
- {
- request.setHeader("Authorization", "Bearer " + this.apiKey);
+ InjectionResponseParser parser = new InjectionResponseParser();
+
+ CloseableHttpAsyncClient client = buildHttpAsyncClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+
+ retryHandler.sendAsync(client, httpPost, new FutureCallback() {
+ public void completed(final HttpResponse response) {
+ try {
+ callback.onResponse(parser.Parse(response));
+ } catch (IOException ex) {
+ callback.onError(ex);
+ }
+ }
+
+ public void failed(final Exception ex) {
+ callback.onError(ex);
+ }
+
+ public void cancelled() {
+ callback.onError(new Exception("sendAsync cancelled"));
+ }
+
+ });
+
+ }
+
+ /**
+ * Asynchronously sends a basic email message and returns the response from the Injection API.
+ * @param message A BasicMessage object to be sent.
+ * @param httpAsyncClient A CloseableHttpAsyncClient instance to use when making http calls.
+ * @param callback A SendAsyncCallback to handle error and response from the Injection API.
+ * @throws Exception exception
+ */
+ @Override
+ public void sendAsync(BasicMessage message, CloseableHttpAsyncClient httpAsyncClient, final SendAsyncCallback callback) throws Exception {
+
+ SendResponse result = Validate(message);
+ if (result.getResult() != SendResult.Success) {
+ callback.onResponse(result);
+ return;
}
- request.setBody(new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message));
+ ApiKeyParser keyParser = new ApiKeyParser();
+ ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
+
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
- RetryHandler retryHandler = new RetryHandler(request, this.endPointUrl, new RetrySettings(this.numberOfRetries));
InjectionResponseParser parser = new InjectionResponseParser();
- retryHandler.sendAsync(new Callback() {
- public void onResponse(Call call, Response response) throws IOException {
- callback.onResponse(parser.Parse(response));
+ CloseableHttpAsyncClient client = buildHttpAsyncClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+
+ retryHandler.sendAsync(client, httpPost, new FutureCallback() {
+ public void completed(final HttpResponse response) {
+ try {
+ callback.onResponse(parser.Parse(response));
+ } catch (IOException ex) {
+ callback.onError(ex);
+ }
}
- public void onFailure(Call call, IOException ex) {
+ public void failed(final Exception ex) {
callback.onError(ex);
}
+
+ public void cancelled() {
+ callback.onError(new Exception("sendAsync cancelled"));
+ }
+
});
}
@@ -190,31 +330,85 @@ public void sendAsync(BulkMessage message, final SendAsyncCallback callback) thr
return;
}
- HttpRequest request = buildHttpRequest(this.proxy);
-
ApiKeyParser keyParser = new ApiKeyParser();
ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
- if (parseResult != null && parseResult == ApiKeyParseResult.Success)
- {
- request.setHeader("Authorization", "Bearer " + this.apiKey);
- }
-
- request.setBody(new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message));
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
- RetryHandler retryHandler = new RetryHandler(request, this.endPointUrl, new RetrySettings(this.numberOfRetries));
InjectionResponseParser parser = new InjectionResponseParser();
- retryHandler.sendAsync(new Callback() {
- public void onResponse(Call call, Response response) throws IOException {
- callback.onResponse(parser.Parse(response));
+ CloseableHttpAsyncClient client = buildHttpAsyncClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+
+ retryHandler.sendAsync(client, httpPost, new FutureCallback() {
+ public void completed(final HttpResponse response) {
+ try {
+ callback.onResponse(parser.Parse(response));
+ } catch (IOException ex) {
+ callback.onError(ex);
+ }
}
- public void onFailure(Call call, IOException ex) {
+ public void failed(final Exception ex) {
callback.onError(ex);
}
+
+ public void cancelled() {
+ callback.onError(new Exception("sendAsync cancelled"));
+ }
+
});
+ }
+
+ /**
+ * Asynchronously sends a bulk email message and returns the response from the Injection API.
+ * @param message A BulkMessage object to be sent.
+ * @param httpAsyncClient A CloseableHttpAsyncClient instance to use when making http calls.
+ * @param callback A SendAsyncCallback to handle error and response from the Injection API.
+ * @throws Exception exception
+ */
+ @Override
+ public void sendAsync(BulkMessage message, CloseableHttpAsyncClient httpAsyncClient, final SendAsyncCallback callback) throws Exception {
+
+ SendResponse result = Validate(message);
+ if (result.getResult() != SendResult.Success) {
+ callback.onResponse(result);
+ return;
+ }
+
+ ApiKeyParser keyParser = new ApiKeyParser();
+ ApiKeyParseResult parseResult = keyParser.Parse(this.apiKey);
+ this.useBearerAuth = (parseResult == ApiKeyParseResult.Success);
+
+ String body = new InjectionRequestFactory(this.serverId, this.apiKey).GenerateRequest(message);
+ HttpPost httpPost = getHttpPost(body);
+
+ InjectionResponseParser parser = new InjectionResponseParser();
+
+ CloseableHttpAsyncClient client = buildHttpAsyncClient();
+ RetryHandler retryHandler = new RetryHandler(new RetrySettings(this.numberOfRetries));
+
+ retryHandler.sendAsync(client, httpPost, new FutureCallback() {
+ public void completed(final HttpResponse response) {
+ try {
+ callback.onResponse(parser.Parse(response));
+ } catch (IOException ex) {
+ callback.onError(ex);
+ }
+ }
+
+ public void failed(final Exception ex) {
+ callback.onError(ex);
+ }
+
+ public void cancelled() {
+ callback.onError(new Exception("sendAsync cancelled"));
+ }
+
+ });
}
@@ -242,19 +436,60 @@ private SendResponse Validate(BulkMessage message) {
}
- private HttpRequest buildHttpRequest(Proxy optionalProxy) {
+ private CloseableHttpClient buildHttpClient() {
+
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+ cm.setMaxTotal(200);
+ cm.setDefaultMaxPerRoute(20);
+ cm.setValidateAfterInactivity(10000);
- HttpRequest request = new HttpRequest(HttpRequest.HttpRequestMethod.POST, this.endPointUrl, this.requestTimeout);
+ return HttpClients.custom()
+ .setConnectionManager(cm)
+ .setDefaultRequestConfig(getDefaultRequestConfig())
+ .build();
+ }
- request.setHeader("User-Agent", this.userAgent);
- request.setHeader("content-type", "application/json");
- request.setHeader("Accept", "application/json");
+ private CloseableHttpAsyncClient buildHttpAsyncClient() throws Exception {
- if(optionalProxy != null) {
- request.setProxy(optionalProxy);
- }
+ final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
+ PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
+ cm.setMaxTotal(200);
+ cm.setDefaultMaxPerRoute(20);
- return request;
+ return HttpAsyncClients.custom()
+ .setConnectionManager(cm)
+ .setDefaultRequestConfig(getDefaultRequestConfig())
+ .build();
}
+ private RequestConfig getDefaultRequestConfig() {
+ return RequestConfig.custom()
+ .setConnectTimeout(this.requestTimeout)
+ .setConnectionRequestTimeout(this.requestTimeout)
+ .setSocketTimeout(this.requestTimeout)
+ .build();
+ }
+
+ private HttpPost getHttpPost(String body) throws UnsupportedEncodingException {
+ HttpPost httpPost = new HttpPost(this.endPointUrl);
+ StringEntity entity = new StringEntity(body);
+ httpPost.setEntity(entity);
+
+ List headers = getDefaultHeaders();
+ for (Header header : headers) {
+ httpPost.addHeader(header);
+ }
+ if(this.useBearerAuth) {
+ httpPost.addHeader(new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + this.apiKey));
+ }
+
+ if (this.proxy != null) {
+ InetSocketAddress address = (InetSocketAddress) this.proxy.address();
+ RequestConfig requestConfig = RequestConfig.copy(getDefaultRequestConfig())
+ .setProxy(new HttpHost(address.getHostName(), address.getPort()))
+ .build();
+ httpPost.setConfig(requestConfig);
+ }
+ return httpPost;
+ }
}
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClientAPI.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClientAPI.java
index 25fa695..e4c381b 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClientAPI.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/SocketLabsClientAPI.java
@@ -3,6 +3,8 @@
import com.socketLabs.injectionApi.core.SendAsyncCallback;
import com.socketLabs.injectionApi.message.BasicMessage;
import com.socketLabs.injectionApi.message.BulkMessage;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
/**
* SocketLabsClientAPI is an interface that defines the SocketLabs Injection API client and its public methods.
@@ -17,6 +19,15 @@ public interface SocketLabsClientAPI {
*/
void sendAsync(BasicMessage message, final SendAsyncCallback callback) throws Exception;
+ /**
+ * Asynchronously sends a basic email message and returns the response from the Injection API.
+ * @param message A BasicMessage object to be sent.
+ * @param httpAsyncClient A CloseableHttpAsyncClient instance to use when making http calls.
+ * @param callback A SendAsyncCallback to handle error and response from the Injection API.
+ * @throws Exception exception
+ */
+ void sendAsync(BasicMessage message, CloseableHttpAsyncClient httpAsyncClient, final SendAsyncCallback callback) throws Exception;
+
/**
* Asynchronously sends a bulk email message and returns the response from the Injection API.
* @param message A BulkMessage object to be sent.
@@ -25,6 +36,17 @@ public interface SocketLabsClientAPI {
*/
void sendAsync(BulkMessage message, final SendAsyncCallback callback) throws Exception;
+
+ /**
+ * Asynchronously sends a bulk email message and returns the response from the Injection API.
+ * @param message A BulkMessage object to be sent.
+ * @param httpAsyncClient A CloseableHttpAsyncClient instance to use when making http calls.
+ * @param callback A SendAsyncCallback to handle error and response from the Injection API.
+ * @throws Exception exception
+ */
+ void sendAsync(BulkMessage message, CloseableHttpAsyncClient httpAsyncClient, final SendAsyncCallback callback) throws Exception;
+
+
/**
* Synchronously sends a basic email message and returns the response from the Injection API.
* @param message A BasicMessage object to be sent.
@@ -33,6 +55,15 @@ public interface SocketLabsClientAPI {
*/
SendResponse send(BasicMessage message) throws Exception;
+ /**
+ * Synchronously sends a basic email message and returns the response from the Injection API.
+ * @param message A BasicMessage object to be sent.
+ * @return A SendResponse of an SocketLabsClient send request.
+ * @param httpClient A CloseableHttpClient instance to use when making http calls.
+ * @throws Exception exception
+ */
+ SendResponse send(BasicMessage message, CloseableHttpClient httpClient) throws Exception;
+
/**
* Synchronously sends a bulk email message and returns the response from the Injection API.
* @param message A BulkMessage object to be sent.
@@ -40,4 +71,14 @@ public interface SocketLabsClientAPI {
* @throws Exception exception
*/
SendResponse send(BulkMessage message) throws Exception;
+
+
+ /**
+ * Synchronously sends a bulk email message and returns the response from the Injection API.
+ * @param message A BulkMessage object to be sent.
+ * @return A SendResponse of an SocketLabsClient send request.
+ * @param httpClient A CloseableHttpClient instance to use when making http calls.
+ * @throws Exception exception
+ */
+ SendResponse send(BulkMessage message, CloseableHttpClient httpClient) throws Exception;
}
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/HttpRequest.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/HttpRequest.java
index c559dcc..b6f67db 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/HttpRequest.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/HttpRequest.java
@@ -2,166 +2,65 @@
import com.socketLabs.injectionApi.SendResponse;
import com.socketLabs.injectionApi.core.serialization.InjectionResponseParser;
-import okhttp3.*;
-import okhttp3.Request.Builder;
-
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import java.io.*;
-import java.net.Proxy;
-import java.util.concurrent.TimeUnit;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.Future;
/**
*
*/
public class HttpRequest {
- /**
- * Enumeration of HTTP Request Methods
- */
- public enum HttpRequestMethod {
- GET,
- POST,
- PUT,
- DELETE;
- }
-
- /** The HTTP Request Method to use */
- private HttpRequestMethod method;
- /** The URL to use for the HTTP request */
- private String endPointUrl;
- /** The HTTP request body to send */
- private String body;
- /** The Proxy to use when making the HTTP request */
- private Proxy proxy;
- /** The headers to add to the HTTP Request */
- private Map headers = new HashMap<>();
- private int timeout;
-
-
/**
* Creates a new instance of the HTTP Request class
- * @param method HTTpRequestMethod
- * @param endPointUrl String
- * @param timeout int
- */
- public HttpRequest(HttpRequestMethod method, String endPointUrl, int timeout) {
- this.method = method;
- this.endPointUrl = endPointUrl;
- this.timeout = timeout;
- }
-
- /**
- * Sets the HTTP request body
- * @param value String
- */
- public void setBody(String value) {
- this.body = value;
- }
-
- /**
- * Sets the headers for the HTTP Request
- * @param key String
- * @param value String
*/
- public void setHeader(String key, String value) {
- this.headers.put(key, value);
- }
-
- /**
- * Sets the Proxy to use when making the HTTP request
- * @param value String
- */
- public void setProxy(Proxy value) { this.proxy = value; }
-
- /**
- * Media Type to use to force JSON
- */
- public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
+ public HttpRequest() { }
/**
* Send the HTTP Request
+ * @param httpClient A CloseableHttpClient instance to use when making http calls.
+ * @param httpPost A HttpPost instance to send.
* @return A SendResponse from the Injection Api response
* @throws IOException in case of a network error.
*/
- public Response SendRequest() throws IOException {
-
- Call call = BuildClientCall();
-
- Response response = call.execute();
-
- return response;
-
+ public CloseableHttpResponse SendRequest(CloseableHttpClient httpClient, HttpPost httpPost) throws IOException {
+ return httpClient.execute(httpPost);
}
/**
- * Send an HTTP Request asynchronously
+ * Send an HTTP Request
+ * @param httpAsyncClient A CloseableHttpAsyncClient instance to use when making http calls.
+ * @param httpPost A HttpPost instance to send.
* @param callback the SendAsyncCallback.
+ * @throws IOException in case of a network error.
*/
- public void SendAsyncRequest(final Callback callback) {
-
- Call call = BuildClientCall();
-
- call.enqueue(new Callback() {
- public void onResponse(Call call, Response response) throws IOException {
-
- callback.onResponse(call, response);
- // ...
- }
-
- public void onFailure(Call call, IOException ex) {
- callback.onFailure(call, ex);
- }
- });
-
- }
-
-
- /**
- * Build the HTTP Client call
- * @return Call
- */
- private Call BuildClientCall() {
+ public void SendAsyncRequest(CloseableHttpAsyncClient httpAsyncClient, HttpPost httpPost, final FutureCallback callback) throws IOException {
- OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
- .connectTimeout(this.timeout, TimeUnit.SECONDS)
- .writeTimeout(this.timeout, TimeUnit.SECONDS)
- .readTimeout(this.timeout, TimeUnit.SECONDS)
- .callTimeout(this.timeout, TimeUnit.SECONDS);
+ httpAsyncClient.start();
+ final Future future = httpAsyncClient.execute(httpPost,
+ new FutureCallback() {
- OkHttpClient client = clientBuilder.build();
+ public void completed(final HttpResponse response) {
+ callback.completed(response);
+ }
- if (this.proxy != null)
- client = clientBuilder
- .proxy(this.proxy)
- .build();
+ public void failed(final Exception exception) {
+ callback.failed(exception);
+ }
- Builder builder = new Builder().url(this.endPointUrl);
+ public void cancelled() {
+ callback.cancelled();
+ }
- //add request method
- RequestBody reqBody = RequestBody.create(JSON, this.body);
- switch (this.method) {
- case POST:
- builder.post(reqBody);
- break;
- case GET:
- builder.get();
- break;
- case PUT:
- builder.put(reqBody);
- break;
- case DELETE:
- builder.delete(reqBody);
- break;
- }
+ });
- //add request header
- for (Map.Entry header : this.headers.entrySet()) {
- builder.addHeader(header.getKey(), header.getValue());
- }
-
- return client.newCall(builder.build());
+ httpAsyncClient.close();
}
@@ -169,10 +68,8 @@ private Call BuildClientCall() {
* Parse the Response into a SendResponse
* @param response the response from the HTTP request
* @return SendResponse
- * @throws IOException
*/
- private SendResponse ParseResponse(Response response) throws IOException {
-
+ private SendResponse ParseResponse(HttpResponse response) throws IOException {
InjectionResponseParser parser = new InjectionResponseParser();
return parser.Parse(response);
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/RetryHandler.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/RetryHandler.java
index c0115e2..bd63499 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/RetryHandler.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/RetryHandler.java
@@ -1,11 +1,12 @@
package com.socketLabs.injectionApi.core;
-
import com.socketLabs.injectionApi.RetrySettings;
-import com.socketLabs.injectionApi.core.serialization.InjectionResponseParser;
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.Response;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -14,38 +15,34 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class RetryHandler {
- private HttpRequest httpRequest;
- private String endPointUrl;
- private RetrySettings retrySettings;
+ private final RetrySettings retrySettings;
private int attempts = 0;
- private Set ErrorStatusCodes = new HashSet<>(Arrays.asList(500, 502, 503, 504));
- private Set> Exceptions = new HashSet>(Arrays.asList(
+ private final Set ErrorStatusCodes = new HashSet<>(Arrays.asList(500, 502, 503, 504));
+ private final Set> Exceptions = new HashSet>(Arrays.asList(
SocketTimeoutException.class,
InterruptedIOException.class
));
- ///
- /// Creates a new instance of the RetryHandler.
- ///
- /// A HttpRequest instance
- /// The SocketLabs Injection API endpoint Url
- /// A RetrySettings instance
- public RetryHandler(HttpRequest request, String endpointUrl, RetrySettings settings){
- httpRequest = request;
- endPointUrl = endpointUrl;
- retrySettings = settings;
+ /**
+ *
+ * Creates a new instance of the RetryHandler.
+ * @param settings A RetrySettings instance.
+ */
+ public RetryHandler(RetrySettings settings){
+ this.retrySettings = settings;
}
- public Response send() throws IOException, InterruptedException {
+
+ public CloseableHttpResponse send(CloseableHttpClient httpClient, HttpPost httpPost) throws IOException, InterruptedException {
if (retrySettings.getMaximumNumberOfRetries() == 0) {
- Response response = httpRequest.SendRequest();
- return response;
+ return httpClient.execute(httpPost);
}
do {
@@ -53,10 +50,9 @@ public Response send() throws IOException, InterruptedException {
Duration waitInterval = retrySettings.getNextWaitInterval(attempts);
try{
-
- Response response = httpRequest.SendRequest();
- if (ErrorStatusCodes.contains(response.networkResponse().code()))
- throw new IOException("Received Http Status Code : " + response.networkResponse().code());
+ CloseableHttpResponse response = httpClient.execute(httpPost);
+ if (ErrorStatusCodes.contains(response.getStatusLine().getStatusCode()))
+ throw new IOException("Received Http Status Code : " + response.getStatusLine().getStatusCode());
return response;
}
@@ -83,66 +79,80 @@ public Response send() throws IOException, InterruptedException {
}
- public void sendAsync (final Callback callback) throws IOException, InterruptedException{
+ public void sendAsync (CloseableHttpAsyncClient httpAsyncClient, HttpPost httpPost, final FutureCallback callback) throws IOException, InterruptedException{
- InjectionResponseParser parser = new InjectionResponseParser();
Duration waitInterval = retrySettings.getNextWaitInterval(attempts);
- httpRequest.SendAsyncRequest(new Callback() {
+ // Create a default CloseableHttpAsyncClient instance
+ try {
+ // Start the client
+ httpAsyncClient.start();
+
+ // Use a CountDownLatch to wait for the asynchronous operation to complete
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ // Execute the request asynchronously with a FutureCallback
+ httpAsyncClient.execute(httpPost, new FutureCallback() {
+ @Override
+ public void completed(final HttpResponse response) {
+ if (ErrorStatusCodes.contains(response.getStatusLine().getStatusCode()) && attempts <= retrySettings.getMaximumNumberOfRetries()){
+ attempts++;
+
+ try {
+ TimeUnit.MILLISECONDS.sleep(waitInterval.toMillis());
+ sendAsync(httpAsyncClient, httpPost, callback);
+ }
+ catch (IOException | InterruptedException ioException) {
+ callback.failed(ioException);
+ }
+ }
- @Override
- public void onResponse(Call call, Response response) throws IOException {
+ else {
+ callback.completed(response);
+ }
+ latch.countDown(); // Signal completion
+ }
- if (ErrorStatusCodes.contains(response.networkResponse().code()) && attempts <= retrySettings.getMaximumNumberOfRetries()){
+ @Override
+ public void failed(final Exception exception) {
+ if(Exceptions.contains(exception.getClass()) && attempts <= retrySettings.getMaximumNumberOfRetries()) {
+ attempts++;
- attempts++;
+ try {
+ TimeUnit.MILLISECONDS.sleep(waitInterval.toMillis());
+ sendAsync(httpAsyncClient, httpPost, callback);
+ }
+ catch (IOException | InterruptedException ioException) {
+ callback.failed(ioException);
+ }
- try {
- TimeUnit.MILLISECONDS.sleep(waitInterval.toMillis());
- sendAsync(callback);
}
- catch (InterruptedException interruptedException) {
- interruptedException.printStackTrace();
+ else {
+ attempts = retrySettings.getMaximumNumberOfRetries() + 1;
+ callback.failed(exception);
}
-
+ latch.countDown(); // Signal completion even on failure
}
- else {
- callback.onResponse(call, response);
+ @Override
+ public void cancelled() {
+ callback.cancelled();
+ latch.countDown(); // Signal completion on cancellation
}
+ });
- }
-
- @Override
- public void onFailure(Call call, IOException exception) {
-
- if(Exceptions.contains(exception.getClass()) && attempts <= retrySettings.getMaximumNumberOfRetries()) {
-
- attempts++;
+ // Wait for the asynchronous operation to complete
+ latch.await();
- try {
- TimeUnit.MILLISECONDS.sleep(waitInterval.toMillis());
- sendAsync(callback);
- }
-
- catch (IOException ioException) {
- ioException.printStackTrace();
- }
-
- catch (InterruptedException interruptedException) {
- interruptedException.printStackTrace();
- }
-
- }
- else {
- attempts = retrySettings.getMaximumNumberOfRetries() + 1;
- callback.onFailure(call, exception);
- }
+ } catch (Exception exception) {
+ callback.failed(exception);
+ } finally {
+ httpAsyncClient.close();
+ }
- }
- });
}
+
}
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/SendAsyncCallback.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/SendAsyncCallback.java
index e438b05..6e64b93 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/SendAsyncCallback.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/SendAsyncCallback.java
@@ -1,7 +1,6 @@
package com.socketLabs.injectionApi.core;
import com.socketLabs.injectionApi.SendResponse;
-import okhttp3.Call;
import java.io.IOException;
diff --git a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/serialization/InjectionResponseParser.java b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/serialization/InjectionResponseParser.java
index fc0912e..8a9a131 100644
--- a/injectionApi/src/main/java/com/socketLabs/injectionApi/core/serialization/InjectionResponseParser.java
+++ b/injectionApi/src/main/java/com/socketLabs/injectionApi/core/serialization/InjectionResponseParser.java
@@ -2,7 +2,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.socketLabs.injectionApi.*;
-import okhttp3.Response;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.util.EntityUtils;
import java.io.IOException;
@@ -17,12 +20,46 @@ public class InjectionResponseParser {
* @return A SendResponse from the Injection Api response
* @throws IOException in case of a network error.
*/
- public SendResponse Parse(Response response) throws IOException {
+ public SendResponse Parse(HttpResponse response) throws IOException {
ObjectMapper mapper = new ObjectMapper();
- InjectionResponseDto injectionResponse = mapper.readValue(response.body().string(), InjectionResponseDto.class);
+ HttpEntity body = response.getEntity();
+ String responseBody = EntityUtils.toString(body, "UTF-8");
- SendResult resultEnum = DetermineSendResult(injectionResponse, response.networkResponse().code());
+ InjectionResponseDto injectionResponse = mapper.readValue(responseBody, InjectionResponseDto.class);
+
+ SendResult resultEnum = DetermineSendResult(injectionResponse, response.getStatusLine().getStatusCode());
+ SendResponse newResponse = new SendResponse(resultEnum);
+ newResponse.setTransactionReceipt(injectionResponse.getTransactionReceipt());
+
+ if (resultEnum == SendResult.Warning && (injectionResponse.getMessageResults() != null && injectionResponse.getMessageResults().size() > 0))
+ {
+ SendResult r = SendResult.fromString(injectionResponse.getMessageResults().get(0).getErrorCode());
+ newResponse.setResult(r);
+ }
+
+ if (injectionResponse.getMessageResults() != null && injectionResponse.getMessageResults().size() > 0)
+ newResponse.setAddressResults(injectionResponse.getMessageResults().get(0).getAddressResults());
+
+ return newResponse;
+
+ }
+
+ /**
+ * Parse the response from theInjection Api into SendResponse
+ * @param response The response from the Injection Api request
+ * @return A SendResponse from the Injection Api response
+ * @throws IOException in case of a network error.
+ */
+ public SendResponse Parse(CloseableHttpResponse response) throws IOException {
+
+ ObjectMapper mapper = new ObjectMapper();
+ HttpEntity body = response.getEntity();
+ String responseBody = EntityUtils.toString(body, "UTF-8");
+
+ InjectionResponseDto injectionResponse = mapper.readValue(responseBody, InjectionResponseDto.class);
+
+ SendResult resultEnum = DetermineSendResult(injectionResponse, response.getStatusLine().getStatusCode());
SendResponse newResponse = new SendResponse(resultEnum);
newResponse.setTransactionReceipt(injectionResponse.getTransactionReceipt());