diff --git a/pom.xml b/pom.xml
index c6b3f6969..a3c40f11b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -313,6 +313,16 @@
${org.projectlombok.version}
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+ org.slf4j
+ slf4j-simple
+ ${org.slf4j.version}
+
mockwebserver
com.squareup.okhttp3
@@ -375,8 +385,6 @@
${org.hamcrest.version}
test
-
-
@@ -393,7 +401,7 @@
1.8
1.8
3.6.1
- 5.2.3
+ 5.4.2
4.5.14
3.1.0
3.12.1
@@ -417,6 +425,7 @@
4.5.1
0.2.0
1.18.32
+ 2.0.17
1.6.12
UTF-8
2.27.2
diff --git a/src/main/java/com/mindee/http/MindeeApi.java b/src/main/java/com/mindee/http/MindeeApi.java
index 497f060fa..051d1ffc5 100644
--- a/src/main/java/com/mindee/http/MindeeApi.java
+++ b/src/main/java/com/mindee/http/MindeeApi.java
@@ -6,7 +6,7 @@
import com.mindee.parsing.common.WorkflowResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import org.apache.http.HttpEntity;
+import org.apache.hc.core5.http.HttpEntity;
/**
* Defines required methods for an API.
diff --git a/src/main/java/com/mindee/http/MindeeHttpApi.java b/src/main/java/com/mindee/http/MindeeHttpApi.java
index 9df0e26f2..b65bc24ba 100644
--- a/src/main/java/com/mindee/http/MindeeHttpApi.java
+++ b/src/main/java/com/mindee/http/MindeeHttpApi.java
@@ -20,20 +20,20 @@
import java.util.Map;
import java.util.function.Function;
import lombok.Builder;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHeaders;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.entity.mime.HttpMultipartMode;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.apache.hc.core5.net.URIBuilder;
/**
* HTTP Client class.
@@ -152,31 +152,33 @@ public AsyncPredictResponse documentQueueGet(
}
get.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
- try (
- CloseableHttpClient httpClient = httpClientBuilder.build();
- CloseableHttpResponse response = httpClient.execute(get)
- ) {
- HttpEntity responseEntity = response.getEntity();
- int statusCode = response.getStatusLine().getStatusCode();
- if (!is2xxStatusCode(statusCode)) {
- throw getHttpError(parametricType, response);
- }
- String rawResponse = readRawResponse(responseEntity);
- AsyncPredictResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
- mappedResponse.setRawResponse(rawResponse);
- if (
- mappedResponse.getJob() != null
- && mappedResponse.getJob().getError() != null
- && mappedResponse.getJob().getError().getCode() != null
- ) {
- throw new MindeeHttpException(
- 500,
- mappedResponse.getJob().getError().getMessage(),
- mappedResponse.getJob().getError().getDetails().toString(),
- mappedResponse.getJob().getError().getCode()
- );
- }
- return mappedResponse;
+ try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
+ return httpClient.execute(
+ get, response -> {
+ HttpEntity responseEntity = response.getEntity();
+ int statusCode = response.getCode();
+ if (!is2xxStatusCode(statusCode)) {
+ throw getHttpError(parametricType, response);
+ }
+ String rawResponse = readRawResponse(responseEntity);
+ AsyncPredictResponse mappedResponse =
+ mapper.readValue(rawResponse, parametricType);
+ mappedResponse.setRawResponse(rawResponse);
+ if (
+ mappedResponse.getJob() != null
+ && mappedResponse.getJob().getError() != null
+ && mappedResponse.getJob().getError().getCode() != null
+ ) {
+ throw new MindeeHttpException(
+ 500,
+ mappedResponse.getJob().getError().getMessage(),
+ mappedResponse.getJob().getError().getDetails().toString(),
+ mappedResponse.getJob().getError().getCode()
+ );
+ }
+ return mappedResponse;
+ }
+ );
} catch (IOException err) {
throw new MindeeException(err.getMessage(), err);
}
@@ -200,22 +202,23 @@ public PredictResponse predictPost(
PredictResponse.class,
documentClass
);
- try (
- CloseableHttpClient httpClient = httpClientBuilder.build();
- CloseableHttpResponse response = httpClient.execute(post)
- ) {
- HttpEntity responseEntity = response.getEntity();
- int statusCode = response.getStatusLine().getStatusCode();
- if (!is2xxStatusCode(statusCode)) {
- throw getHttpError(parametricType, response);
- }
- if (responseEntity.getContentLength() == 0) {
- throw new MindeeException("Empty response from server.");
- }
- String rawResponse = readRawResponse(responseEntity);
- PredictResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
- mappedResponse.setRawResponse(rawResponse);
- return mappedResponse;
+ try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
+ return httpClient.execute(
+ post, response -> {
+ HttpEntity responseEntity = response.getEntity();
+ int statusCode = response.getCode();
+ if (!is2xxStatusCode(statusCode)) {
+ throw getHttpError(parametricType, response);
+ }
+ if (responseEntity.getContentLength() == 0) {
+ throw new MindeeException("Empty response from server.");
+ }
+ String rawResponse = readRawResponse(responseEntity);
+ PredictResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
+ mappedResponse.setRawResponse(rawResponse);
+ return mappedResponse;
+ }
+ );
} catch (IOException err) {
throw new MindeeException(err.getMessage(), err);
}
@@ -239,22 +242,24 @@ public AsyncPredictResponse predictAsyncPost(
AsyncPredictResponse.class,
documentClass
);
- try (
- CloseableHttpClient httpClient = httpClientBuilder.build();
- CloseableHttpResponse response = httpClient.execute(post)
- ) {
- HttpEntity responseEntity = response.getEntity();
- int statusCode = response.getStatusLine().getStatusCode();
- if (!is2xxStatusCode(statusCode)) {
- throw getHttpError(parametricType, response);
- }
- if (responseEntity.getContentLength() == 0) {
- throw new MindeeException("Empty response from server.");
- }
- String rawResponse = readRawResponse(responseEntity);
- AsyncPredictResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
- mappedResponse.setRawResponse(rawResponse);
- return mappedResponse;
+ try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
+ return httpClient.execute(
+ post, response -> {
+ HttpEntity responseEntity = response.getEntity();
+ int statusCode = response.getCode();
+ if (!is2xxStatusCode(statusCode)) {
+ throw getHttpError(parametricType, response);
+ }
+ if (responseEntity.getContentLength() == 0) {
+ throw new MindeeException("Empty response from server.");
+ }
+ String rawResponse = readRawResponse(responseEntity);
+ AsyncPredictResponse mappedResponse =
+ mapper.readValue(rawResponse, parametricType);
+ mappedResponse.setRawResponse(rawResponse);
+ return mappedResponse;
+ }
+ );
} catch (IOException err) {
throw new MindeeException(err.getMessage(), err);
}
@@ -279,22 +284,21 @@ public WorkflowResponse executeWorkflowPost(
WorkflowResponse.class,
documentClass
);
- try (
- CloseableHttpClient httpClient = httpClientBuilder.build();
- CloseableHttpResponse response = httpClient.execute(post)
- ) {
- HttpEntity responseEntity = response.getEntity();
- int statusCode = response.getStatusLine().getStatusCode();
- if (!is2xxStatusCode(statusCode)) {
- throw getHttpError(parametricType, response);
- }
- if (responseEntity.getContentLength() == 0) {
- throw new MindeeException("Empty response from server.");
- }
- String rawResponse = readRawResponse(responseEntity);
- WorkflowResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
- mappedResponse.setRawResponse(rawResponse);
- return mappedResponse;
+ try (CloseableHttpClient httpClient = httpClientBuilder.build()) {
+ return httpClient.execute(post, response -> {
+ HttpEntity responseEntity = response.getEntity();
+ int statusCode = response.getCode();
+ if (!is2xxStatusCode(statusCode)) {
+ throw getHttpError(parametricType, response);
+ }
+ if (responseEntity.getContentLength() == 0) {
+ throw new MindeeException("Empty response from server.");
+ }
+ String rawResponse = readRawResponse(responseEntity);
+ WorkflowResponse mappedResponse = mapper.readValue(rawResponse, parametricType);
+ mappedResponse.setRawResponse(rawResponse);
+ return mappedResponse;
+ });
} catch (IOException err) {
throw new MindeeException(err.getMessage(), err);
}
@@ -303,9 +307,9 @@ public WorkflowResponse executeWorkflowPost(
private MindeeHttpException getHttpError(
JavaType parametricType,
- CloseableHttpResponse response
+ ClassicHttpResponse response
) {
- int statusCode = response.getStatusLine().getStatusCode();
+ int statusCode = response.getCode();
String message = "HTTP Status " + statusCode + " - ";
String details;
String errorCode;
@@ -392,7 +396,7 @@ private HttpEntity buildHttpBody(
) throws JsonProcessingException {
if (requestParameters.getFile() != null) {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
- builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
+ builder.setMode(HttpMultipartMode.EXTENDED);
builder.addBinaryBody(
"document",
requestParameters.getFile(),
diff --git a/src/test/java/com/mindee/http/MindeeHttpApiTest.java b/src/test/java/com/mindee/http/MindeeHttpApiTest.java
index 0d08f2b1b..b3e90155a 100644
--- a/src/test/java/com/mindee/http/MindeeHttpApiTest.java
+++ b/src/test/java/com/mindee/http/MindeeHttpApiTest.java
@@ -7,6 +7,8 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.mindee.MindeeSettings;
@@ -24,13 +26,14 @@
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
-import org.apache.http.HttpHost;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
+import org.apache.hc.core5.http.HttpHost;
import org.hamcrest.collection.IsMapContaining;
import org.junit.After;
import org.junit.Assert;
@@ -41,7 +44,7 @@
public class MindeeHttpApiTest {
MockWebServer mockWebServer = new MockWebServer();
- private static ObjectMapper objectMapper = new ObjectMapper();
+ private static final ObjectMapper objectMapper = new ObjectMapper();
@Before
public void startWebServer() throws Exception {
@@ -56,10 +59,16 @@ public void stopWebServer() throws Exception {
private MindeeHttpApi getClientForResponse(Path filePath, int statusCode) throws IOException {
String url = String.format("http://localhost:%s", mockWebServer.getPort());
mockWebServer.enqueue(new MockResponse()
- .setResponseCode(statusCode)
- .setBody(new String(Files.readAllBytes(filePath)))
+ .setResponseCode(statusCode)
+ .setBody(new String(Files.readAllBytes(filePath)))
);
- return MindeeHttpApi.builder().mindeeSettings(new MindeeSettings("abc", url)).build();
+ HttpClientBuilder httpClientBuilder = HttpClients.custom()
+ .disableAutomaticRetries();
+
+ return MindeeHttpApi.builder()
+ .mindeeSettings(new MindeeSettings("abc", url))
+ .httpClientBuilder(httpClientBuilder)
+ .build();
}
private MindeeHttpApi getClientForResponse(String filePath, int statusCode) throws IOException {
@@ -69,27 +78,28 @@ private MindeeHttpApi getClientForResponse(String filePath, int statusCode) thro
@Test
void givenAResponseFromTheEndpoint_whenDeserialized_mustHaveValidSummary()
- throws IOException
- {
+ throws IOException {
MindeeHttpApi client = getClientForResponse("products/invoices/response_v4/complete.json", 200);
File file = new File("src/test/resources/products/invoices/invoice.pdf");
Document document = client.predictPost(
- InvoiceV4.class,
- new Endpoint("", ""),
- RequestParameters.builder()
- .file(Files.readAllBytes(file.toPath()))
- .fileName(file.getName())
- .build())
- .getDocument();
+ InvoiceV4.class,
+ new Endpoint("", ""),
+ RequestParameters.builder()
+ .file(Files.readAllBytes(file.toPath()))
+ .fileName(file.getName())
+ .build()
+ )
+ .getDocument();
Assertions.assertNotNull(document);
String[] actualLines = document.toString().split(System.lineSeparator());
String actualSummary = String.join(String.format("%n"), actualLines);
List expectedLines = Files
- .readAllLines(Paths.get("src/test/resources/products/invoices/response_v4/summary_full.rst"));
+ .readAllLines(
+ Paths.get("src/test/resources/products/invoices/response_v4/summary_full.rst"));
String expectedSummary = String.join(String.format("%n"), expectedLines);
Assertions.assertNotNull(document);
@@ -98,56 +108,59 @@ void givenAResponseFromTheEndpoint_whenDeserialized_mustHaveValidSummary()
@Test
void givenParseParametersWithFile_whenParsed_shouldBuildRequestCorrectly()
- throws IOException, InterruptedException
- {
+ throws IOException, InterruptedException {
MindeeHttpApi client = getClientForResponse("products/invoices/response_v4/complete.json", 200);
File file = new File("src/test/resources/products/invoices/invoice.pdf");
byte[] fileBytes = Files.readAllBytes(file.toPath());
Document document = client.predictPost(
- InvoiceV4.class,
- new Endpoint("", ""),
- RequestParameters.builder()
- .file(fileBytes)
- .fileName(file.getName())
- .build())
- .getDocument();
+ InvoiceV4.class,
+ new Endpoint("", ""),
+ RequestParameters.builder()
+ .file(fileBytes)
+ .fileName(file.getName())
+ .build()
+ )
+ .getDocument();
RecordedRequest recordedRequest = mockWebServer.takeRequest();
Assertions.assertEquals("abc", recordedRequest.getHeader("Authorization"));
- Assertions.assertEquals(Long.toString(recordedRequest.getBodySize()),
- recordedRequest.getHeader("Content-Length"));
+ Assertions.assertEquals(
+ Long.toString(recordedRequest.getBodySize()),
+ recordedRequest.getHeader("Content-Length")
+ );
Assertions.assertTrue(recordedRequest.getBodySize() > fileBytes.length);
}
@Test
void givenPredictOptions_whenParsed_shouldBuildRequestCorrectly()
- throws IOException, InterruptedException
- {
+ throws IOException, InterruptedException {
MindeeHttpApi client = getClientForResponse("products/invoices/response_v4/complete.json", 200);
File file = new File("src/test/resources/products/invoices/invoice.pdf");
byte[] fileBytes = Files.readAllBytes(file.toPath());
PredictOptions predictOptions = PredictOptions.builder()
- .cropper(true)
- .allWords(true)
- .build();
+ .cropper(true)
+ .allWords(true)
+ .build();
Document document = client.predictPost(
- InvoiceV4.class,
- new Endpoint("", ""),
- RequestParameters.builder()
- .file(fileBytes)
- .fileName(file.getName())
- .predictOptions(predictOptions)
- .build())
- .getDocument();
+ InvoiceV4.class,
+ new Endpoint("", ""),
+ RequestParameters.builder()
+ .file(fileBytes)
+ .fileName(file.getName())
+ .predictOptions(predictOptions)
+ .build()
+ )
+ .getDocument();
RecordedRequest recordedRequest = mockWebServer.takeRequest();
Assertions.assertEquals("abc", recordedRequest.getHeader("Authorization"));
Assertions.assertEquals(
- Long.toString(recordedRequest.getBodySize()),
- recordedRequest.getHeader("Content-Length")
+ Long.toString(recordedRequest.getBodySize()),
+ recordedRequest.getHeader("Content-Length")
);
+ assert recordedRequest.getRequestUrl() != null;
Assertions.assertTrue(recordedRequest.getRequestUrl().toString().contains("cropper=true"));
Assertions.assertTrue(recordedRequest.getBody().readUtf8().contains("include_mvision"));
Assertions.assertTrue(recordedRequest.getBodySize() > fileBytes.length);
@@ -155,35 +168,38 @@ void givenPredictOptions_whenParsed_shouldBuildRequestCorrectly()
@Test
void givenParseParametersWithFileUrl_whenParsed_shouldBuildRequestCorrectly()
- throws IOException, InterruptedException
- {
+ throws IOException, InterruptedException {
MindeeHttpApi client = getClientForResponse("products/invoices/response_v4/complete.json", 200);
Document document = client.predictPost(
- InvoiceV4.class,
- new Endpoint("", ""),
- RequestParameters.builder()
- .file(null)
- .fileName(null)
- .urlInputSource(new URL("https://thisfile.does.not.exist"))
- .build())
- .getDocument();
+ InvoiceV4.class,
+ new Endpoint("", ""),
+ RequestParameters.builder()
+ .file(null)
+ .fileName(null)
+ .urlInputSource(new URL("https://thisfile.does.not.exist"))
+ .build()
+ )
+ .getDocument();
RecordedRequest recordedRequest = mockWebServer.takeRequest();
Assertions.assertEquals("abc", recordedRequest.getHeader("Authorization"));
- Assertions.assertEquals(Long.toString(recordedRequest.getBodySize()),
- recordedRequest.getHeader("Content-Length"));
- Assertions.assertTrue(recordedRequest.getHeader("Content-Type").contains("application/json"));
- Map requestMap = objectMapper.readValue(recordedRequest.getBody().readUtf8(),
- Map.class);
+ Assertions.assertEquals(
+ Long.toString(recordedRequest.getBodySize()),
+ recordedRequest.getHeader("Content-Length")
+ );
+ Assertions.assertTrue(Objects.requireNonNull(recordedRequest.getHeader("Content-Type")).contains("application/json"));
+ Map requestMap = objectMapper.readValue(
+ recordedRequest.getBody().readUtf8(),
+ new TypeReference