From c4bdf56ddf37a5e2444a72f3c5a1077c0ccdb440 Mon Sep 17 00:00:00 2001 From: Guilherme Werner Date: Thu, 4 Jan 2024 18:51:26 -0300 Subject: [PATCH] Add http and socket classes --- lib/src/main/java/com/tribufu/TribufuApi.java | 8 +- .../java/com/tribufu/http/TribufuHttp.java | 183 ++++++++++++++++++ .../com/tribufu/http/TribufuHttpOptions.java | 28 +++ .../com/tribufu/socket/TribufuSocket.java | 13 ++ 4 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 lib/src/main/java/com/tribufu/http/TribufuHttp.java create mode 100644 lib/src/main/java/com/tribufu/http/TribufuHttpOptions.java create mode 100644 lib/src/main/java/com/tribufu/socket/TribufuSocket.java diff --git a/lib/src/main/java/com/tribufu/TribufuApi.java b/lib/src/main/java/com/tribufu/TribufuApi.java index c06e8cf..ddb4093 100644 --- a/lib/src/main/java/com/tribufu/TribufuApi.java +++ b/lib/src/main/java/com/tribufu/TribufuApi.java @@ -2,7 +2,7 @@ package com.tribufu; -import java.net.http.HttpClient; +import com.tribufu.http.TribufuHttp; import java.util.HashMap; import java.util.Map; @@ -23,7 +23,7 @@ public class TribufuApi { protected final String baseUrl; protected final TribufuApiOptions options; - protected final HttpClient http; + protected final TribufuHttp http; /** * Create a TribufuApi with the default options. @@ -51,9 +51,7 @@ public class TribufuApi { public TribufuApi(TribufuApiOptions options) { this.options = options; this.baseUrl = TribufuApi.getBaseUrl(); - this.http = HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_2) - .build(); + this.http = new TribufuHttp(baseUrl, TribufuApi.defaultHeaders(), true, TribufuApi.API_URL); } /** diff --git a/lib/src/main/java/com/tribufu/http/TribufuHttp.java b/lib/src/main/java/com/tribufu/http/TribufuHttp.java new file mode 100644 index 0000000..38829ca --- /dev/null +++ b/lib/src/main/java/com/tribufu/http/TribufuHttp.java @@ -0,0 +1,183 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu.http; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.URI; +import java.util.concurrent.CompletableFuture; +import java.util.Map; + +/** + * Tribufu Http + * + * Helper class to make HTTP requests to the Tribufu API. + */ +public class TribufuHttp { + private static final Gson gson = new GsonBuilder().create(); + + private final HttpClient inner; + protected final TribufuHttpOptions options; + + public TribufuHttp() { + this(new TribufuHttpOptions()); + } + + public TribufuHttp(String baseUrl, Map headers, boolean logEnabled, String logTarget) { + this(new TribufuHttpOptions(baseUrl, headers, logEnabled, logTarget)); + } + + public TribufuHttp(TribufuHttpOptions options) { + this.options = options; + this.inner = HttpClient.newBuilder().build(); + } + + /** + * Helper method to send an asynchronous HTTP request. + */ + private CompletableFuture sendRequest(HttpRequest request) { + return this.inner.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body); + } + + /** + * Helper method to send an asynchronous HTTP request. + */ + private CompletableFuture sendRequest(HttpRequest request, Class returnType) { + return this.inner.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenApply(response -> gson.fromJson(response.body(), returnType)); + } + + /** + * Helper method to build form URL-encoded data from a Map + */ + private HttpRequest.BodyPublisher buildFormDataFromMap(Map data) { + return HttpRequest.BodyPublishers.ofString( + data.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .reduce((param1, param2) -> param1 + "&" + param2) + .orElse("")); + } + + /** + * Make a GET request to the Tribufu API and deserialize the response JSON. + * + * @param path The path of the resource. + * @param headers Optional headers. + * @param returnType The type to deserialize the response into. + * @return A CompletableFuture containing the deserialized response object. + */ + public CompletableFuture get(String path, Map headers, Class returnType) { + var requestBuilder = HttpRequest.newBuilder(); + + for (var entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + + var request = requestBuilder + .uri(URI.create(this.options.baseUrl + path)) + .GET() + .build(); + + return sendRequest(request, returnType); + } + + /** + * Make a POST request to the Tribufu API and deserialize the response JSON. + * + * @param path The path of the resource. + * @param body The request body. + * @param headers Optional headers. + * @param returnType The type to deserialize the response into. + * @return A CompletableFuture containing the deserialized response object. + */ + public CompletableFuture post(String path, S body, Map headers, Class returnType) { + var requestBuilder = HttpRequest.newBuilder(); + + for (var entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + + var request = requestBuilder + .uri(URI.create(this.options.baseUrl + path)) + .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(body))) + .build(); + + return sendRequest(request, returnType); + } + + /** + * Make a POST request to the Tribufu API with form URL-encoded data + * and deserialize the response JSON. + * + * @param path The path of the resource. + * @param formData The form data as a Map. + * @param headers Optional headers. + * @param returnType The type to deserialize the response into. + * @return A CompletableFuture containing the deserialized response object. + */ + public CompletableFuture postFormUrlEncoded(String path, Map formData, + Map headers, Class returnType) { + var requestBuilder = HttpRequest.newBuilder(); + + for (var entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + + var request = requestBuilder + .uri(URI.create(this.options.baseUrl + path)) + .POST(buildFormDataFromMap(formData)) + .build(); + + return sendRequest(request, returnType); + } + + /** + * Make a PUT request to the Tribufu API and deserialize the response JSON. + * + * @param path The path of the resource. + * @param body The request body. + * @param headers Optional headers. + * @param returnType The type to deserialize the response into. + * @return A CompletableFuture containing the deserialized response object. + */ + public CompletableFuture put(String path, S body, Map headers, Class returnType) { + var requestBuilder = HttpRequest.newBuilder(); + + for (var entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + + var request = requestBuilder + .uri(URI.create(this.options.baseUrl + path)) + .PUT(HttpRequest.BodyPublishers.ofString(gson.toJson(body))) + .build(); + + return sendRequest(request, returnType); + } + + /** + * Make a DELETE request to the Tribufu API. + * + * @param path The path of the resource. + * @param headers Optional headers. + * @return A CompletableFuture containing the response body as a String. + */ + public CompletableFuture delete(String path, Map headers) { + var requestBuilder = HttpRequest.newBuilder(); + + for (var entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + + var request = requestBuilder + .uri(URI.create(this.options.baseUrl + path)) + .DELETE() + .build(); + + return sendRequest(request); + } +} diff --git a/lib/src/main/java/com/tribufu/http/TribufuHttpOptions.java b/lib/src/main/java/com/tribufu/http/TribufuHttpOptions.java new file mode 100644 index 0000000..83be6d9 --- /dev/null +++ b/lib/src/main/java/com/tribufu/http/TribufuHttpOptions.java @@ -0,0 +1,28 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu.http; + +import java.util.HashMap; +import java.util.Map; + +public class TribufuHttpOptions { + public String baseUrl; + public Map headers; + public boolean logEnabled; + public String logTarget; + + public TribufuHttpOptions() { + this(null); + } + + public TribufuHttpOptions(String baseUrl) { + this(baseUrl, new HashMap<>(), false, "TribufuHttp"); + } + + public TribufuHttpOptions(String baseUrl, Map headers, boolean logEnabled, String logTarget) { + this.baseUrl = baseUrl; + this.headers = headers; + this.logEnabled = logEnabled; + this.logTarget = logTarget; + } +} diff --git a/lib/src/main/java/com/tribufu/socket/TribufuSocket.java b/lib/src/main/java/com/tribufu/socket/TribufuSocket.java new file mode 100644 index 0000000..0ec84d4 --- /dev/null +++ b/lib/src/main/java/com/tribufu/socket/TribufuSocket.java @@ -0,0 +1,13 @@ +// Copyright (c) Tribufu. All Rights Reserved. + +package com.tribufu.socket; + +/** + * Tribufu Socket + * + * Helper class to connect to the Tribufu Socket API. + */ +public class TribufuSocket { + public TribufuSocket() { + } +}