change how the mojang server status' are fetched
All checks were successful
Deploy App / docker (ubuntu-latest, 2.44.0, 17, 3.8.5) (push) Successful in 2m9s

This commit is contained in:
Lee 2024-07-30 21:04:37 +01:00
parent bb651bd88b
commit b7834ab389
5 changed files with 43 additions and 57 deletions

@ -15,8 +15,8 @@ import xyz.mcutils.backend.service.MojangService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@RestController @RestController
@Tag(name = "Mojang Controller", description = "The Mojang Controller is used to get information about the Mojang APIs.")
@RequestMapping(value = "/mojang/", produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/mojang/", produces = MediaType.APPLICATION_JSON_VALUE)
@Tag(name = "Mojang Controller", description = "The Mojang Controller is used to get information about the Mojang APIs.")
public class MojangController { public class MojangController {
@Autowired @Autowired
@ -25,12 +25,8 @@ public class MojangController {
@ResponseBody @ResponseBody
@GetMapping(value = "/status") @GetMapping(value = "/status")
public ResponseEntity<?> getStatus() { public ResponseEntity<?> getStatus() {
CachedEndpointStatus status = mojangService.getMojangApiStatus();
return ResponseEntity.ok() return ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES).cachePublic()) .cacheControl(CacheControl.maxAge(1, TimeUnit.MINUTES).cachePublic())
.body(status); .body(mojangService.getMojangServerStatus());
} }
} }

@ -16,8 +16,8 @@ import xyz.mcutils.backend.service.PlayerService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@RestController @RestController
@Tag(name = "Player Controller", description = "The Player Controller is used to get information about a player.")
@RequestMapping(value = "/player/") @RequestMapping(value = "/player/")
@Tag(name = "Player Controller", description = "The Player Controller is used to get information about a player.")
public class PlayerController { public class PlayerController {
private final PlayerService playerService; private final PlayerService playerService;

@ -16,8 +16,8 @@ import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@RestController @RestController
@Tag(name = "Server Controller", description = "The Server Controller is used to get information about a server.")
@RequestMapping(value = "/server/") @RequestMapping(value = "/server/")
@Tag(name = "Server Controller", description = "The Server Controller is used to get information about a server.")
public class ServerController { public class ServerController {
private final ServerService serverService; private final ServerService serverService;

@ -1,11 +0,0 @@
package xyz.mcutils.backend.repository.redis;
import org.springframework.data.repository.CrudRepository;
import xyz.mcutils.backend.model.cache.CachedEndpointStatus;
/**
* A cache repository for {@link CachedEndpointStatus}'s.
*
* @author Braydon
*/
public interface EndpointStatusRepository extends CrudRepository<CachedEndpointStatus, String> { }

@ -9,16 +9,12 @@ import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import net.jodah.expiringmap.ExpirationPolicy; import net.jodah.expiringmap.ExpirationPolicy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import xyz.mcutils.backend.common.AppConfig;
import xyz.mcutils.backend.common.ExpiringSet; import xyz.mcutils.backend.common.ExpiringSet;
import xyz.mcutils.backend.common.MojangServer; import xyz.mcutils.backend.common.MojangServer;
import xyz.mcutils.backend.common.WebRequest; import xyz.mcutils.backend.common.WebRequest;
import xyz.mcutils.backend.model.cache.CachedEndpointStatus;
import xyz.mcutils.backend.model.token.MojangProfileToken; import xyz.mcutils.backend.model.token.MojangProfileToken;
import xyz.mcutils.backend.model.token.MojangUsernameToUuidToken; import xyz.mcutils.backend.model.token.MojangUsernameToUuidToken;
import xyz.mcutils.backend.repository.redis.EndpointStatusRepository;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -27,7 +23,9 @@ import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Service @Log4j2(topic = "Mojang Service") @Getter @Service
@Log4j2(topic = "Mojang Service")
@Getter
public class MojangService { public class MojangService {
/** /**
@ -48,8 +46,10 @@ public class MojangService {
*/ */
private static final long FETCH_BLOCKED_SERVERS_INTERVAL = TimeUnit.HOURS.toMillis(1L); private static final long FETCH_BLOCKED_SERVERS_INTERVAL = TimeUnit.HOURS.toMillis(1L);
@Autowired /**
private EndpointStatusRepository mojangEndpointStatusRepository; * The interval to fetch the Mojang server status.
*/
private static final long FETCH_MOJANG_SERVERS_STATUS_INTERVAL = TimeUnit.MINUTES.toMillis(1L);
/** /**
* A list of banned server hashes provided by Mojang. * A list of banned server hashes provided by Mojang.
@ -69,6 +69,11 @@ public class MojangService {
*/ */
private final ExpiringSet<String> blockedServersCache = new ExpiringSet<>(ExpirationPolicy.CREATED, 10L, TimeUnit.MINUTES); private final ExpiringSet<String> blockedServersCache = new ExpiringSet<>(ExpirationPolicy.CREATED, 10L, TimeUnit.MINUTES);
/**
* The status of the Mojang API.
*/
private final List<Map<String, Object>> mojangServerStatus = new ArrayList<>();
public MojangService() { public MojangService() {
new Timer().scheduleAtFixedRate(new TimerTask() { new Timer().scheduleAtFixedRate(new TimerTask() {
@Override @Override
@ -76,6 +81,33 @@ public class MojangService {
fetchBlockedServers(); fetchBlockedServers();
} }
}, 0L, FETCH_BLOCKED_SERVERS_INTERVAL); }, 0L, FETCH_BLOCKED_SERVERS_INTERVAL);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
log.info("Fetching Mojang Server status...");
Map<MojangServer, MojangServer.Status> mojangServers = new HashMap<>();
Arrays.stream(MojangServer.values()).parallel().forEach(server -> {
log.info("Pinging {}...", server.getEndpoint());
MojangServer.Status status = server.getStatus(); // Retrieve the server status
log.info("Retrieved status of {}: {}", server.getEndpoint(), status.name());
mojangServers.put(server, status); // Cache the server status
});
mojangServerStatus.clear();
for (Map.Entry<MojangServer, MojangServer.Status> entry : mojangServers.entrySet()) {
MojangServer server = entry.getKey();
Map<String, Object> serverStatus = new HashMap<>();
serverStatus.put("name", server.getName());
serverStatus.put("endpoint", server.getEndpoint());
serverStatus.put("status", entry.getValue().name());
mojangServerStatus.add(serverStatus);
}
log.info("Fetched Mojang Server status for {} endpoints", mojangServers.size());
}
}, 0L, FETCH_MOJANG_SERVERS_STATUS_INTERVAL);
} }
/** /**
@ -166,37 +198,6 @@ public class MojangService {
return blocked; return blocked;
} }
/**
* Gets the status of the Mojang APIs.
*
* @return the status
*/
public CachedEndpointStatus getMojangApiStatus() {
log.info("Getting Mojang API status");
Optional<CachedEndpointStatus> endpointStatus = mojangEndpointStatusRepository.findById("mojang-servers-status");
if (endpointStatus.isPresent() && AppConfig.isProduction()) {
log.info("Got cached Mojang API status");
return endpointStatus.get();
}
Map<MojangServer, MojangServer.Status> mojangServers = new HashMap<>();
Arrays.stream(MojangServer.values()).parallel().forEach(server -> {
log.info("Pinging {}...", server.getEndpoint());
MojangServer.Status status = server.getStatus(); // Retrieve the server status
log.info("Retrieved status of {}: {}", server.getEndpoint(), status.name());
mojangServers.put(server, status); // Cache the server status
});
log.info("Fetched Mojang API status for {} endpoints", mojangServers.size());
CachedEndpointStatus status = new CachedEndpointStatus(
"mojang-servers-status",
mojangServers
);
mojangEndpointStatusRepository.save(status);
status.getCache().setCached(false);
return status;
}
/** /**
* Gets the Session Server profile of the * Gets the Session Server profile of the
* player with the given UUID. * player with the given UUID.