From 8a985b52b8138a0e0763b4ac9f818dc8577b6cf9 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 19 Apr 2024 17:21:10 +0100 Subject: [PATCH] update mojang endpoint to include the name of the service --- .../model/cache/CachedEndpointStatus.java | 8 +- .../backend/model/mojang/EndpointStatus.java | 23 +++++- .../backend/service/MojangService.java | 79 ++++++++----------- 3 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/main/java/xyz/mcutils/backend/model/cache/CachedEndpointStatus.java b/src/main/java/xyz/mcutils/backend/model/cache/CachedEndpointStatus.java index d526ec6..ead5ba6 100644 --- a/src/main/java/xyz/mcutils/backend/model/cache/CachedEndpointStatus.java +++ b/src/main/java/xyz/mcutils/backend/model/cache/CachedEndpointStatus.java @@ -12,6 +12,7 @@ import xyz.mcutils.backend.common.CachedResponse; import xyz.mcutils.backend.model.mojang.EndpointStatus; import java.io.Serializable; +import java.util.List; @Setter @Getter @ToString @RedisHash(value = "mojangEndpointStatus", timeToLive = 60L) // 1 minute (in seconds) @@ -26,12 +27,11 @@ public class CachedEndpointStatus extends CachedResponse implements Serializable /** * The endpoint cache. */ - @JsonUnwrapped - private final EndpointStatus value; + private final List endpoints; - public CachedEndpointStatus(@NonNull String id, EndpointStatus value) { + public CachedEndpointStatus(@NonNull String id, List endpoints) { super(Cache.defaultCache()); this.id = id; - this.value = value; + this.endpoints = endpoints; } } \ No newline at end of file diff --git a/src/main/java/xyz/mcutils/backend/model/mojang/EndpointStatus.java b/src/main/java/xyz/mcutils/backend/model/mojang/EndpointStatus.java index bf46307..a2d6e7a 100644 --- a/src/main/java/xyz/mcutils/backend/model/mojang/EndpointStatus.java +++ b/src/main/java/xyz/mcutils/backend/model/mojang/EndpointStatus.java @@ -2,18 +2,33 @@ package xyz.mcutils.backend.model.mojang; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; import java.util.Map; -@AllArgsConstructor -@Getter +@RequiredArgsConstructor +@Getter @Setter public class EndpointStatus { /** - * The list of endpoints and their status. + * The name of the service. */ - private final Map endpoints; + private final String name; + /** + * The hostname of the service. + */ + private final String hostname; + + /** + * The status of the service. + */ + private Status status; + + /** + * Statuses for the endpoint. + */ public enum Status { /** * The service is online and operational. diff --git a/src/main/java/xyz/mcutils/backend/service/MojangService.java b/src/main/java/xyz/mcutils/backend/service/MojangService.java index 6dba114..761b4e5 100644 --- a/src/main/java/xyz/mcutils/backend/service/MojangService.java +++ b/src/main/java/xyz/mcutils/backend/service/MojangService.java @@ -10,24 +10,21 @@ import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import net.jodah.expiringmap.ExpirationPolicy; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; -import xyz.mcutils.backend.Main; -import xyz.mcutils.backend.common.Endpoint; -import xyz.mcutils.backend.common.EnvironmentUtils; -import xyz.mcutils.backend.common.ExpiringSet; -import xyz.mcutils.backend.common.WebRequest; +import xyz.mcutils.backend.common.*; import xyz.mcutils.backend.model.cache.CachedEndpointStatus; import xyz.mcutils.backend.model.mojang.EndpointStatus; import xyz.mcutils.backend.model.token.MojangProfileToken; import xyz.mcutils.backend.model.token.MojangUsernameToUuidToken; import xyz.mcutils.backend.repository.redis.EndpointStatusRepository; +import java.io.IOException; import java.io.InputStream; +import java.net.InetAddress; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.Timer; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -56,15 +53,14 @@ public class MojangService { * Information about the Mojang API endpoints. */ private static final String MOJANG_ENDPOINT_STATUS_KEY = "mojang"; - private static final List MOJANG_ENDPOINTS = List.of( - new Endpoint("https://textures.minecraft.net", List.of(HttpStatus.BAD_REQUEST)), - new Endpoint("https://session.minecraft.net", List.of(HttpStatus.NOT_FOUND)), - new Endpoint("https://libraries.minecraft.net", List.of(HttpStatus.NOT_FOUND)), - new Endpoint("https://assets.mojang.com", List.of(HttpStatus.NOT_FOUND)), - new Endpoint("https://api.minecraftservices.com", List.of(HttpStatus.FORBIDDEN)), - new Endpoint(API_ENDPOINT, List.of(HttpStatus.OK)), - new Endpoint(SESSION_SERVER_ENDPOINT, List.of(HttpStatus.FORBIDDEN)) - ); + private static final List MOJANG_ENDPOINTS = List.of( + new EndpointStatus("Minecraft Textures", "textures.minecraft.net"), + new EndpointStatus("Minecraft Session", "session.minecraft.net"), + new EndpointStatus("Minecraft Libraries", "libraries.minecraft.net"), + new EndpointStatus("Minecraft Services", "api.minecraftservices.com"), + new EndpointStatus("Mojang Assets", "assets.mojang.com"), + new EndpointStatus("Mojang API", API_ENDPOINT), + new EndpointStatus("Mojang Session Server", SESSION_SERVER_ENDPOINT)); @Autowired private EndpointStatusRepository mojangEndpointStatusRepository; @@ -195,43 +191,32 @@ public class MojangService { return endpointStatus.get(); } - // Fetch the status of the Mojang API endpoints - List> futures = new ArrayList<>(); - for (Endpoint endpoint : MOJANG_ENDPOINTS) { - CompletableFuture future = CompletableFuture.supplyAsync(() -> { - boolean online = false; - long start = System.currentTimeMillis(); - ResponseEntity response = WebRequest.head(endpoint.getEndpoint(), String.class); - if (endpoint.getAllowedStatuses().contains(response.getStatusCode())) { - online = true; + List> futures = new ArrayList<>(); + for (EndpointStatus endpoint : MOJANG_ENDPOINTS) { + futures.add(CompletableFuture.runAsync(() -> { + try { + long start = System.currentTimeMillis(); + InetAddress address = InetAddress.getByName(endpoint.getHostname()); + if (address.isReachable(5000)) { // Check if the endpoint is reachable + endpoint.setStatus(EndpointStatus.Status.ONLINE); + return; + } + // Check if the endpoint took too long to respond + if (System.currentTimeMillis() - start > TimeUnit.SECONDS.toMillis(2)) { + endpoint.setStatus(EndpointStatus.Status.DEGRADED); + } + } catch (IOException e) { + endpoint.setStatus(EndpointStatus.Status.OFFLINE); } - if (online && System.currentTimeMillis() - start > 1000) { // If the response took longer than 1 second - return EndpointStatus.Status.DEGRADED; - } - return online ? EndpointStatus.Status.ONLINE : EndpointStatus.Status.OFFLINE; - }, Main.EXECUTOR_POOL); - - futures.add(future); - } - CompletableFuture allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); - try { - allFutures.get(5, TimeUnit.SECONDS); // Wait for the futures to complete - } catch (Exception e) { - log.error("Timeout while fetching Mojang API status: {}", e.getMessage()); + })); } - // Process the results - Map endpoints = new HashMap<>(); - for (int i = 0; i < MOJANG_ENDPOINTS.size(); i++) { - Endpoint endpoint = MOJANG_ENDPOINTS.get(i); - EndpointStatus.Status status = futures.get(i).join(); - endpoints.put(endpoint.getEndpoint(), status); - } + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); - log.info("Fetched Mojang API status for {} endpoints", endpoints.size()); + log.info("Fetched Mojang API status for {} endpoints", MOJANG_ENDPOINTS.size()); CachedEndpointStatus status = new CachedEndpointStatus( MOJANG_ENDPOINT_STATUS_KEY, - new EndpointStatus(endpoints) + MOJANG_ENDPOINTS ); mojangEndpointStatusRepository.save(status); status.getCache().setCached(false);