Add http and socket classes

This commit is contained in:
Guilherme Werner 2024-01-04 18:51:26 -03:00
parent eef87270fa
commit c4bdf56ddf
4 changed files with 227 additions and 5 deletions

View file

@ -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);
}
/**

View file

@ -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<String, String> 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<String> sendRequest(HttpRequest request) {
return this.inner.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body);
}
/**
* Helper method to send an asynchronous HTTP request.
*/
private <T> CompletableFuture<T> sendRequest(HttpRequest request, Class<T> 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<String, String> 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 <T> CompletableFuture<T> get(String path, Map<String, String> headers, Class<T> 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 <S, T> CompletableFuture<T> post(String path, S body, Map<String, String> headers, Class<T> 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 <T> CompletableFuture<T> postFormUrlEncoded(String path, Map<String, String> formData,
Map<String, String> headers, Class<T> 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 <S, T> CompletableFuture<T> put(String path, S body, Map<String, String> headers, Class<T> 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<String> delete(String path, Map<String, String> 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);
}
}

View file

@ -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<String, String> 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<String, String> headers, boolean logEnabled, String logTarget) {
this.baseUrl = baseUrl;
this.headers = headers;
this.logEnabled = logEnabled;
this.logTarget = logTarget;
}
}

View file

@ -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() {
}
}