From 66056648570c8e39e568b0bdb9689589c3b64308 Mon Sep 17 00:00:00 2001 From: Rainnny7 Date: Sat, 6 Apr 2024 14:40:29 -0400 Subject: [PATCH] Add web request utilities --- .../java/me/braydon/mc/common/UUIDUtils.java | 27 +++++ .../mc/common/web/JsonWebException.java | 28 +++++ .../braydon/mc/common/web/JsonWebRequest.java | 105 ++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 src/main/java/me/braydon/mc/common/UUIDUtils.java create mode 100644 src/main/java/me/braydon/mc/common/web/JsonWebException.java create mode 100644 src/main/java/me/braydon/mc/common/web/JsonWebRequest.java diff --git a/src/main/java/me/braydon/mc/common/UUIDUtils.java b/src/main/java/me/braydon/mc/common/UUIDUtils.java new file mode 100644 index 0000000..31cee82 --- /dev/null +++ b/src/main/java/me/braydon/mc/common/UUIDUtils.java @@ -0,0 +1,27 @@ +package me.braydon.mc.common; + +import lombok.NonNull; +import lombok.experimental.UtilityClass; + +import java.util.UUID; + +/** + * @author Braydon + */ +@UtilityClass +public final class UUIDUtils { + /** + * Add dashes to an untrimmed uuid. + * + * @param trimmed the untrimmed uuid + * @return the uuid with dashes + */ + @NonNull + public static UUID addDashes(@NonNull String trimmed) { + StringBuilder builder = new StringBuilder(trimmed); + for (int i = 0, pos = 20; i < 4; i++, pos -= 4) { + builder.insert(pos, "-"); + } + return UUID.fromString(builder.toString()); + } +} \ No newline at end of file diff --git a/src/main/java/me/braydon/mc/common/web/JsonWebException.java b/src/main/java/me/braydon/mc/common/web/JsonWebException.java new file mode 100644 index 0000000..35e5126 --- /dev/null +++ b/src/main/java/me/braydon/mc/common/web/JsonWebException.java @@ -0,0 +1,28 @@ +package me.braydon.mc.common.web; + +import lombok.Getter; +import lombok.NonNull; + +/** + * This exception is raised when a + * {@link JsonWebRequest} encounters an error. + * + * @author Braydon + */ +@Getter +public class JsonWebException extends RuntimeException { + /** + * The status code of the response. + */ + private final int statusCode; + + protected JsonWebException(int statusCode, @NonNull String message) { + super(message); + this.statusCode = statusCode; + } + + protected JsonWebException(int statusCode, @NonNull Throwable cause) { + super(cause); + this.statusCode = statusCode; + } +} \ No newline at end of file diff --git a/src/main/java/me/braydon/mc/common/web/JsonWebRequest.java b/src/main/java/me/braydon/mc/common/web/JsonWebRequest.java new file mode 100644 index 0000000..580f202 --- /dev/null +++ b/src/main/java/me/braydon/mc/common/web/JsonWebRequest.java @@ -0,0 +1,105 @@ +package me.braydon.mc.common.web; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import me.braydon.mc.RESTfulMC; +import org.springframework.http.HttpMethod; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * A Json web request. + * + * @author Braydon + */ +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) @Getter +public final class JsonWebRequest { + private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient(); + + /** + * The endpoint to make the request to. + */ + @NonNull private final String endpoint; + + /** + * The method to use for the request. + */ + @NonNull private final HttpMethod method; + + /** + * The headers to send with the request. + */ + private final Map headers = Collections.synchronizedMap(new HashMap<>()); + + /** + * Make a new web request. + * + * @param endpoint the endpoint to make the request to + * @param method the method of the request to make + * @return the web request + */ + @NonNull + public static JsonWebRequest makeRequest(@NonNull String endpoint, @NonNull HttpMethod method) { + return new JsonWebRequest(endpoint, method); + } + + /** + * Set a header for this request. + * + * @param name the header name + * @param value the header value + * @return the request + */ + @NonNull + public JsonWebRequest header(@NonNull String name, @NonNull String value) { + headers.put(name, value); + return this; + } + + /** + * Execute this request. + * + * @param responseType the response type + * @return the response + * @param the type of the response + * @throws JsonWebException if an error is encountered while making the request + */ + public T execute(@NonNull Class responseType) throws JsonWebException { + // Build the request + HttpRequest.Builder request = HttpRequest.newBuilder() + .uri(URI.create(endpoint)) + .method(method.name(), HttpRequest.BodyPublishers.noBody()); + // Append headers + headers.put("User-Agent", "RESTfulMC"); + headers.put("Content-Type", "application/json"); + for (Map.Entry header : headers.entrySet()) { + request.header(header.getKey(), header.getValue()); + } + + // Send the request and get the response + int status = -1; // The response status code + try { + HttpResponse response = HTTP_CLIENT.send(request.build(), HttpResponse.BodyHandlers.ofString()); + status = response.statusCode(); // Set the response status + if (status != 200) { // Status code is not OK, raise an exception + throw new IOException("Failed to make a %s request to %s: %s".formatted(method.name(), endpoint, status)); + } + // Return with the response as the type + return RESTfulMC.GSON.fromJson(response.body(), responseType); + } catch (Exception ex) { + if (!(ex instanceof JsonWebException)) { + throw new JsonWebException(status, ex); + } + throw (JsonWebException) ex; + } + } +} \ No newline at end of file