Add Redis caching for Minecraft servers
This commit is contained in:
parent
f99ffbf1e6
commit
3183c56d78
@ -3,6 +3,7 @@ package me.braydon.mc.controller;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import me.braydon.mc.model.MinecraftServer;
|
||||
import me.braydon.mc.model.cache.CachedMinecraftServer;
|
||||
import me.braydon.mc.service.MojangService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -38,8 +39,8 @@ public final class ServerController {
|
||||
*/
|
||||
@GetMapping("/{platform}/{hostname}")
|
||||
@ResponseBody
|
||||
public ResponseEntity<MinecraftServer> getServer(@PathVariable @NonNull String platform,
|
||||
@PathVariable @NonNull String hostname
|
||||
public ResponseEntity<CachedMinecraftServer> getServer(@PathVariable @NonNull String platform,
|
||||
@PathVariable @NonNull String hostname
|
||||
) {
|
||||
return ResponseEntity.ofNullable(mojangService.getMinecraftServer(platform, hostname));
|
||||
}
|
||||
|
@ -62,9 +62,9 @@ public class MinecraftServer {
|
||||
private final int max;
|
||||
|
||||
/**
|
||||
* A sample of players on this server.
|
||||
* A sample of players on this server, null or empty if no sample.
|
||||
*/
|
||||
@NonNull private final Sample[] sample;
|
||||
private final Sample[] sample;
|
||||
|
||||
/**
|
||||
* A sample player.
|
||||
|
31
src/main/java/me/braydon/mc/model/cache/CachedMinecraftServer.java
vendored
Normal file
31
src/main/java/me/braydon/mc/model/cache/CachedMinecraftServer.java
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package me.braydon.mc.model.cache;
|
||||
|
||||
import lombok.*;
|
||||
import me.braydon.mc.model.MinecraftServer;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.redis.core.RedisHash;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor @Setter @Getter @ToString
|
||||
@RedisHash(value = "server", timeToLive = 60L) // 1 minute (in seconds)
|
||||
public final class CachedMinecraftServer implements Serializable {
|
||||
/**
|
||||
* The hostname of the cached server.
|
||||
*/
|
||||
@Id @NonNull private transient final String hostname;
|
||||
|
||||
/**
|
||||
* The cached server.
|
||||
*/
|
||||
@NonNull private final MinecraftServer value;
|
||||
|
||||
/**
|
||||
* The unix timestamp of when this
|
||||
* server was cached, -1 if not cached.
|
||||
*/
|
||||
private long cached;
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package me.braydon.mc.model.response;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -0,0 +1,11 @@
|
||||
package me.braydon.mc.repository;
|
||||
|
||||
import me.braydon.mc.model.cache.CachedMinecraftServer;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* A cache repository for {@link CachedMinecraftServer}'s.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
public interface MinecraftServerCacheRepository extends CrudRepository<CachedMinecraftServer, String> { }
|
@ -12,10 +12,12 @@ import me.braydon.mc.exception.impl.BadRequestException;
|
||||
import me.braydon.mc.exception.impl.InvalidMinecraftServerPlatform;
|
||||
import me.braydon.mc.exception.impl.ResourceNotFoundException;
|
||||
import me.braydon.mc.model.*;
|
||||
import me.braydon.mc.model.cache.CachedMinecraftServer;
|
||||
import me.braydon.mc.model.cache.CachedPlayer;
|
||||
import me.braydon.mc.model.cache.CachedPlayerName;
|
||||
import me.braydon.mc.model.token.MojangProfileToken;
|
||||
import me.braydon.mc.model.token.MojangUsernameToUUIDToken;
|
||||
import me.braydon.mc.repository.MinecraftServerCacheRepository;
|
||||
import me.braydon.mc.repository.PlayerCacheRepository;
|
||||
import me.braydon.mc.repository.PlayerNameCacheRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -49,10 +51,17 @@ public final class MojangService {
|
||||
*/
|
||||
@NonNull private final PlayerCacheRepository playerCache;
|
||||
|
||||
/**
|
||||
* The cache repository for {@link MinecraftServer}'s.
|
||||
*/
|
||||
@NonNull private final MinecraftServerCacheRepository minecraftServerCache;
|
||||
|
||||
@Autowired
|
||||
public MojangService(@NonNull PlayerNameCacheRepository playerNameCache, @NonNull PlayerCacheRepository playerCache) {
|
||||
public MojangService(@NonNull PlayerNameCacheRepository playerNameCache, @NonNull PlayerCacheRepository playerCache,
|
||||
@NonNull MinecraftServerCacheRepository minecraftServerCache) {
|
||||
this.playerNameCache = playerNameCache;
|
||||
this.playerCache = playerCache;
|
||||
this.minecraftServerCache = minecraftServerCache;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,19 +152,37 @@ public final class MojangService {
|
||||
* @throws ResourceNotFoundException if the server isn't found
|
||||
*/
|
||||
@NonNull
|
||||
public MinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname)
|
||||
public CachedMinecraftServer getMinecraftServer(@NonNull String platformName, @NonNull String hostname)
|
||||
throws BadRequestException, InvalidMinecraftServerPlatform, ResourceNotFoundException {
|
||||
MinecraftServer.Platform platform = EnumUtils.getEnumConstant(MinecraftServer.Platform.class, platformName.toUpperCase());
|
||||
if (platform == null) { // Invalid platform
|
||||
throw new InvalidMinecraftServerPlatform();
|
||||
}
|
||||
String lookupHostname = hostname; // The hostname used to lookup the server
|
||||
|
||||
// Check the cache for the server
|
||||
Optional<CachedMinecraftServer> cached = minecraftServerCache.findById(hostname);
|
||||
if (cached.isPresent()) { // Respond with the cache if present
|
||||
log.info("Found server in cache: {}", hostname);
|
||||
return cached.get();
|
||||
}
|
||||
|
||||
InetSocketAddress address = DNSUtils.resolveSRV(hostname); // Resolve the SRV record
|
||||
int port = platform.getDefaultPort(); // Port to ping
|
||||
if (address != null) { // SRV was resolved, use the hostname and port
|
||||
hostname = address.getHostName();
|
||||
port = address.getPort();
|
||||
}
|
||||
return platform.getPinger().ping(hostname, port); // Ping the server and return with the response
|
||||
// Build our server model, cache it, and then return it
|
||||
CachedMinecraftServer minecraftServer = new CachedMinecraftServer(
|
||||
lookupHostname,
|
||||
platform.getPinger().ping(hostname, port),
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
minecraftServerCache.save(minecraftServer);
|
||||
log.info("Cached server: {}", hostname);
|
||||
minecraftServer.setCached(-1L); // Set to -1 to indicate it's not cached in the response
|
||||
return minecraftServer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user