Skip to content

Commit

Permalink
Clean up and add new utility methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chavjoh committed Dec 1, 2023
1 parent 56e184d commit 4d68777
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 29 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -6,7 +6,7 @@

<groupId>com.chavaillaz</groupId>
<artifactId>common-client</artifactId>
<version>1.0-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>${project.groupId}.${project.artifactId}</name>
Expand Down
Expand Up @@ -30,6 +30,7 @@
public abstract class AbstractHttpClient {

public static final String HEADER_COOKIE = "Cookie";
public static final String HEADER_SET_COOKIE = "Set-Cookie";
public static final String HEADER_AUTHORIZATION = "Authorization";
public static final String HEADER_CONTENT_TYPE = "Content-Type";
public static final String HEADER_CONTENT_JSON = "application/json";
Expand Down
Expand Up @@ -21,8 +21,8 @@
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.protocol.BasicHttpContext;
import org.apache.hc.core5.http.protocol.HttpContext;

/**
Expand Down Expand Up @@ -139,7 +139,7 @@ protected <T> CompletableFuture<T> sendAsync(SimpleRequestBuilder requestBuilder
* @return The corresponding context
*/
protected HttpContext createContext() {
HttpContext localContext = new BasicHttpContext();
HttpContext localContext = HttpClientContext.create();
BasicCookieStore cookieStore = new BasicCookieStore();
getAuthentication().fillCookies((key, value) -> addCookie(cookieStore, key, value));
localContext.setAttribute(COOKIE_STORE, cookieStore);
Expand Down
Expand Up @@ -3,6 +3,9 @@
import static org.apache.hc.core5.http.ContentType.DEFAULT_BINARY;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

Expand All @@ -14,10 +17,11 @@
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.util.Timeout;

/**
Expand All @@ -27,12 +31,12 @@
public class ApacheHttpUtils {

/**
* Creates a new asynchronous Apache HTTP client with default configuration (30 seconds timeout).
* Creates a new asynchronous Apache HTTP client builder with default configuration (30 seconds timeout).
*
* @param proxy The proxy configuration
* @return The corresponding client
*/
public static CloseableHttpAsyncClient newHttpClient(ProxyConfiguration proxy) {
public static HttpAsyncClientBuilder defaultHttpClientBuilder(ProxyConfiguration proxy) {
return HttpAsyncClientBuilder.create()
.useSystemProperties()
.setDefaultCookieStore(new BasicCookieStore())
Expand All @@ -47,12 +51,11 @@ public static CloseableHttpAsyncClient newHttpClient(ProxyConfiguration proxy) {
.build())
.setDefaultRequestConfig(RequestConfig.custom()
.setResponseTimeout(null)
.build())
.build();
.build());
}

/**
* Generates a new multipart entity builder with the given files.
* Creates a new multipart entity builder with the given files.
*
* @param files The list of files to include
* @return The multipart entity builder
Expand All @@ -68,4 +71,17 @@ public static MultipartEntityBuilder multipartWithFiles(File... files) {
return builder;
}

/**
* Creates the HTTP parameters for form data using a map of key value representing the data to send.
*
* @param data The data to format and send as form data
* @return The corresponding parameters
*/
public NameValuePair[] formData(Map<Object, Object> data) {
List<NameValuePair> parameters = new ArrayList<>();
data.forEach((key, value) -> parameters.add(new BasicNameValuePair(key.toString(), value.toString())));
return parameters.toArray(new NameValuePair[0]);
}


}
Expand Up @@ -29,19 +29,18 @@
public class JavaHttpUtils {

/**
* Creates a new asynchronous Java HTTP client with default configuration (30 seconds timeout).
* Creates a new asynchronous Java HTTP client builder with default configuration (30 seconds timeout).
*
* @param proxy The proxy configuration
* @return The corresponding client
*/
public static HttpClient newHttpClient(ProxyConfiguration proxy) {
public static HttpClient.Builder defaultHttpClientBuilder(ProxyConfiguration proxy) {
return HttpClient.newBuilder()
.cookieHandler(new CookieManager())
.proxy(Optional.ofNullable(proxy)
.map(config -> ProxySelector.of(new InetSocketAddress(config.getHost(), config.getPort())))
.orElse(ProxySelector.getDefault()))
.connectTimeout(Duration.ofSeconds(30))
.build();
.connectTimeout(Duration.ofSeconds(30));
}

/**
Expand All @@ -50,8 +49,8 @@ public static HttpClient newHttpClient(ProxyConfiguration proxy) {
* @param data The data to format and send as form data
* @return The corresponding body publisher
*/
public static BodyPublisher ofFormData(Map<Object, Object> data) {
return BodyPublishers.ofString(Utils.queryFromKeyValue(data));
public static BodyPublisher formData(Map<Object, Object> data) {
return BodyPublishers.ofString(Utils.encodeQuery(data));
}

/**
Expand All @@ -63,7 +62,7 @@ public static BodyPublisher ofFormData(Map<Object, Object> data) {
* @return The corresponding body publisher
* @throws IOException if an error occurs when reading files if given in the data parameter
*/
public static BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String boundary, Charset charset) throws IOException {
public static BodyPublisher mimeMultipartData(Map<Object, Object> data, String boundary, Charset charset) throws IOException {
List<byte[]> byteArrays = new ArrayList<>();
byte[] separator = ("--" + boundary + "\r\nContent-Disposition: form-data; name=").getBytes(charset);
for (Map.Entry<Object, Object> entry : data.entrySet()) {
Expand All @@ -87,7 +86,7 @@ public static BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String
}

/**
* Creates the {@link Map} for {@link #ofMimeMultipartData(Map, String, Charset)} with the given files.
* Creates the {@link Map} for {@link #mimeMultipartData(Map, String, Charset)} with the given files.
*
* @param files The files
* @return The filled map
Expand Down
Expand Up @@ -22,7 +22,9 @@
*/
public class AbstractOkHttpClient extends AbstractHttpClient implements AutoCloseable {

public static final RequestBody EMPTY_BODY = RequestBody.create(EMPTY, null);
public static final MediaType MEDIA_TYPE_JSON = MediaType.parse(HEADER_CONTENT_JSON);
public static final MediaType MEDIA_TYPE_XML = MediaType.parse(HEADER_CONTENT_XML);

protected final OkHttpClient client;

Expand Down Expand Up @@ -70,7 +72,7 @@ protected RequestBody body(Object object) {
* @return The corresponding request body
*/
protected RequestBody body() {
return RequestBody.create(EMPTY, null);
return EMPTY_BODY;
}

/**
Expand Down
39 changes: 34 additions & 5 deletions src/main/java/com/chavaillaz/client/common/okhttp/OkHttpUtils.java
Expand Up @@ -2,11 +2,13 @@

import static java.net.Proxy.Type.HTTP;
import static java.nio.file.Files.probeContentType;
import static okhttp3.MultipartBody.FORM;

import java.io.File;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;

import com.chavaillaz.client.common.utility.ProxyConfiguration;
Expand All @@ -16,6 +18,8 @@
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
* Utilities for OkHttp Client.
Expand All @@ -24,24 +28,23 @@
public class OkHttpUtils {

/**
* Creates a new asynchronous OkHttp HTTP client with default configuration (30 seconds timeout).
* Creates a new asynchronous OkHttp HTTP client builder with default configuration (30 seconds timeout).
*
* @param proxy The proxy configuration
* @return The corresponding client
*/
public static OkHttpClient newHttpClient(ProxyConfiguration proxy) {
public static OkHttpClient.Builder defaultHttpClientBuilder(ProxyConfiguration proxy) {
return new OkHttpClient.Builder()
.proxy(Optional.ofNullable(proxy)
.map(config -> new Proxy(HTTP, new InetSocketAddress(config.getHost(), config.getPort())))
.orElse(null))
.connectTimeout(Duration.ofSeconds(30))
.readTimeout(Duration.ofSeconds(30))
.callTimeout(Duration.ofSeconds(0))
.build();
.callTimeout(Duration.ofSeconds(0));
}

/**
* Generates a new multipart body with the given files.
* Creates a new multipart body with the given files.
*
* @param files The list of files to include
* @return The multipart body
Expand All @@ -59,4 +62,30 @@ public static MultipartBody multipartWithFiles(File... files) {
return multipartBuilder.build();
}

/**
* Creates the request body for form data using a map of key value representing the data to send.
*
* @param data The data to format and send as form data
* @return The corresponding request body
*/
public RequestBody formData(Map<Object, Object> data) {
MultipartBody.Builder form = new MultipartBody.Builder().setType(FORM);
data.forEach((key, value) -> form.addFormDataPart(key.toString(), value.toString()));
return form.build();
}

/**
* Gets the body of the given response.
* Note that the body can only be read once.
*
* @param response The HTTP response
* @return The body content or {@code null} if not present
*/
@SneakyThrows
public String getBody(Response response) {
try (ResponseBody body = response.body()) {
return body != null ? body.string() : null;
}
}

}
Expand Up @@ -3,7 +3,7 @@
import java.util.function.BiConsumer;

/**
* Anonymous authentication which is not adding anything to query parameters, headers or cookies.
* Anonymous authentication which is not adding anything to headers and/or cookies.
*/
public class AnonymousAuthentication extends Authentication {

Expand Down
Expand Up @@ -4,7 +4,7 @@

/**
* Hold the authentication details to access the desired services.
* Its implementation needs to fill the query parameters, headers and/or cookies.
* Its implementation needs to fill headers and/or cookies.
*/
public abstract class Authentication {

Expand Down
Expand Up @@ -64,7 +64,7 @@ public static String readInputStream(InputStream inputStream, Charset charset) {
* @param data The data to format
* @return the corresponding {@link String}
*/
public static String queryFromKeyValue(Map<Object, Object> data) {
public static String encodeQuery(Map<Object, Object> data) {
StringBuilder result = new StringBuilder();
data.forEach((key, value) -> {
if (!result.isEmpty()) {
Expand Down
Expand Up @@ -20,7 +20,7 @@
*/
public class AbstractVertxHttpClient extends AbstractHttpClient implements AutoCloseable {

protected WebClient client;
protected final WebClient client;

/**
* Creates a new abstract client based on Vert.x HTTP client.
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/com/chavaillaz/client/common/vertx/VertxUtils.java
Expand Up @@ -3,9 +3,11 @@
import static java.nio.file.Files.probeContentType;

import java.io.File;
import java.util.Map;
import java.util.Optional;

import com.chavaillaz.client.common.utility.ProxyConfiguration;
import io.vertx.core.MultiMap;
import io.vertx.core.net.ProxyOptions;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.multipart.MultipartForm;
Expand All @@ -24,7 +26,7 @@ public class VertxUtils {
* @param proxy The proxy configuration
* @return The corresponding options
*/
public static WebClientOptions newWebClientOptions(ProxyConfiguration proxy) {
public static WebClientOptions defaultWebClientOptions(ProxyConfiguration proxy) {
return new WebClientOptions()
.setProxyOptions(Optional.ofNullable(proxy)
.map(config -> new ProxyOptions()
Expand All @@ -36,7 +38,7 @@ public static WebClientOptions newWebClientOptions(ProxyConfiguration proxy) {
}

/**
* Generates a new multipart form with the given files.
* Creates a new multipart form with the given files.
*
* @param files The list of files to include
* @return The multipart form
Expand All @@ -50,4 +52,16 @@ public static MultipartForm multipartWithFiles(File... files) {
return form;
}

/**
* Creates the HTTP parameters for form data using a map of key value representing the data to send.
*
* @param data The data to format and send as form data
* @return The corresponding parameters
*/
public MultiMap formData(Map<Object, Object> data) {
MultiMap form = MultiMap.caseInsensitiveMultiMap();
data.forEach((key, value) -> form.set(key.toString(), value.toString()));
return form;
}

}

0 comments on commit 4d68777

Please sign in to comment.