Use of JSONCache & permission levels for JSON endpoints

This commit is contained in:
Rsl1122 2019-08-31 00:20:50 +03:00
parent 20ef9df63d
commit 58bff282eb
12 changed files with 156 additions and 70 deletions

View File

@ -106,7 +106,7 @@ public class JSONFactory {
).toJSONString();
}
public List<Map<String, Object>> networkSessionsAsJSONMap(UUID serverUUID) {
public List<Map<String, Object>> serverSessionsAsJSONMap(UUID serverUUID) {
Database db = dbSystem.getDatabase();
Integer perPageLimit = config.get(DisplaySettings.SESSIONS_PER_PAGE);

View File

@ -37,6 +37,7 @@ public enum DataID {
GRAPH_WORLD_MAP,
GRAPH_ACTIVITY,
GRAPH_PING,
GRAPH_SERVER_PIE,
GRAPH_PUNCHCARD,
SERVER_OVERVIEW,
ONLINE_OVERVIEW,

View File

@ -39,6 +39,9 @@ public class JSONCache {
return new JSONResponse(found);
}
public Response getOrCache(DataID dataID, Supplier<JSONResponse> jsonResponseSupplier) {
return getOrCache(dataID.name(), jsonResponseSupplier);
}
public Response getOrCache(DataID dataID, UUID serverUUID, Supplier<JSONResponse> jsonResponseSupplier) {
return getOrCache(dataID.of(serverUUID), jsonResponseSupplier);
}

View File

@ -47,6 +47,19 @@ public abstract class TreePageHandler implements PageHandler {
pages.put(targetPage, handler);
}
public void registerPage(String targetPage, PageHandler handler, int requiredPerm) {
pages.put(targetPage, new PageHandler() {
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
return handler.getResponse(request, target);
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= requiredPerm;
}
});
}
public void registerPage(String targetPage, Response response, int requiredPerm) {
pages.put(targetPage, new PageHandler() {
@Override

View File

@ -20,6 +20,8 @@ import com.djrapitops.plan.delivery.rendering.json.graphs.GraphJSONParser;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
@ -30,6 +32,7 @@ import com.djrapitops.plan.identification.Identifiers;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Collections;
import java.util.UUID;
/**
@ -42,14 +45,17 @@ public class GraphsJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final GraphJSONParser graphJSON;
private final JSONCache cache;
@Inject
public GraphsJSONHandler(
Identifiers identifiers,
GraphJSONParser graphJSON
GraphJSONParser graphJSON,
JSONCache cache
) {
this.identifiers = identifiers;
this.graphJSON = graphJSON;
this.cache = cache;
}
@Override
@ -57,51 +63,68 @@ public class GraphsJSONHandler implements PageHandler {
String type = target.getParameter("type")
.orElseThrow(() -> new BadRequestException("'type' parameter was not defined."));
DataID dataID = getDataID(type);
if (target.getParameter("server").isPresent()) {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return generateGraphDataJSONOfType(type, serverUUID);
return cache.getOrCache(dataID, serverUUID, () -> generateGraphDataJSONOfType(dataID, serverUUID));
}
// Assume network
return generateGraphDataJSONOfType(type);
return cache.getOrCache(dataID, () -> generateGraphDataJSONOfType(dataID));
}
private JSONResponse generateGraphDataJSONOfType(String type, UUID serverUUID) throws BadRequestException {
private DataID getDataID(String type) throws BadRequestException {
switch (type) {
case "performance":
return new JSONResponse(graphJSON.performanceGraphJSON(serverUUID));
case "playersOnline":
return new JSONResponse(graphJSON.playersOnlineGraph(serverUUID));
case "uniqueAndNew":
return new JSONResponse(graphJSON.uniqueAndNewGraphJSON(serverUUID));
case "serverCalendar":
return new JSONResponse(graphJSON.serverCalendarJSON(serverUUID));
case "worldPie":
return new JSONResponse(graphJSON.serverWorldPieJSONAsMap(serverUUID));
case "activity":
return new JSONResponse(graphJSON.activityGraphsJSONAsMap(serverUUID));
case "geolocation":
return new JSONResponse(graphJSON.geolocationGraphsJSONAsMap(serverUUID));
case "aggregatedPing":
return new JSONResponse(graphJSON.pingGraphsJSON(serverUUID));
case "punchCard":
return new JSONResponse(graphJSON.punchCardJSONAsMap(serverUUID));
default:
throw new BadRequestException("unknown 'type' parameter: " + type);
case "performance": return DataID.GRAPH_PERFORMANCE;
case "playersOnline": return DataID.GRAPH_ONLINE;
case "uniqueAndNew": return DataID.GRAPH_UNIQUE_NEW;
case "serverCalendar": return DataID.GRAPH_CALENDAR;
case "worldPie": return DataID.GRAPH_WORLD_PIE;
case "activity": return DataID.GRAPH_ACTIVITY;
case "geolocation": return DataID.GRAPH_WORLD_MAP;
case "aggregatedPing": return DataID.GRAPH_PING;
case "punchCard": return DataID.GRAPH_PUNCHCARD;
default: throw new BadRequestException("unknown 'type' parameter: " + type);
}
}
private JSONResponse generateGraphDataJSONOfType(String type) throws BadRequestException {
switch (type) {
case "activity":
private JSONResponse generateGraphDataJSONOfType(DataID id, UUID serverUUID) {
switch (id) {
case GRAPH_PERFORMANCE:
return new JSONResponse(graphJSON.performanceGraphJSON(serverUUID));
case GRAPH_ONLINE:
return new JSONResponse(graphJSON.playersOnlineGraph(serverUUID));
case GRAPH_UNIQUE_NEW:
return new JSONResponse(graphJSON.uniqueAndNewGraphJSON(serverUUID));
case GRAPH_CALENDAR:
return new JSONResponse(graphJSON.serverCalendarJSON(serverUUID));
case GRAPH_WORLD_PIE:
return new JSONResponse(graphJSON.serverWorldPieJSONAsMap(serverUUID));
case GRAPH_ACTIVITY:
return new JSONResponse(graphJSON.activityGraphsJSONAsMap(serverUUID));
case GRAPH_WORLD_MAP:
return new JSONResponse(graphJSON.geolocationGraphsJSONAsMap(serverUUID));
case GRAPH_PING:
return new JSONResponse(graphJSON.pingGraphsJSON(serverUUID));
case GRAPH_PUNCHCARD:
return new JSONResponse(graphJSON.punchCardJSONAsMap(serverUUID));
default:
return new JSONResponse(Collections.singletonMap("error", "Undefined ID: " + id.name()));
}
}
private JSONResponse generateGraphDataJSONOfType(DataID id) {
switch (id) {
case GRAPH_ACTIVITY:
return new JSONResponse(graphJSON.activityGraphsJSONAsMap());
case "uniqueAndNew":
case GRAPH_UNIQUE_NEW:
return new JSONResponse(graphJSON.uniqueAndNewGraphJSON());
case "serverPie":
case GRAPH_SERVER_PIE:
return new JSONResponse(graphJSON.serverPreferencePieJSONAsMap());
case "geolocation":
case GRAPH_WORLD_MAP:
return new JSONResponse(graphJSON.geolocationGraphsJSONAsMap());
default:
throw new BadRequestException("unknown 'type' parameter: " + type);
return new JSONResponse(Collections.singletonMap("error", "Undefined ID: " + id.name()));
}
}

View File

@ -23,6 +23,8 @@ import com.djrapitops.plan.delivery.rendering.json.network.NetworkSessionsOvervi
import com.djrapitops.plan.delivery.rendering.json.network.NetworkTabJSONParser;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.TreePageHandler;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import com.djrapitops.plan.exceptions.WebUserAuthException;
@ -38,25 +40,29 @@ import javax.inject.Singleton;
@Singleton
public class NetworkJSONHandler extends TreePageHandler {
private final JSONCache cache;
@Inject
public NetworkJSONHandler(
ResponseFactory responseFactory,
JSONFactory jsonFactory,
JSONCache cache,
NetworkOverviewJSONParser networkOverviewJSONParser,
NetworkPlayerBaseOverviewJSONParser playerBaseOverviewJSONParser,
NetworkSessionsOverviewJSONParser sessionsOverviewJSONParser
) {
super(responseFactory);
this.cache = cache;
registerPage("overview", networkOverviewJSONParser);
registerPage("playerbaseOverview", playerBaseOverviewJSONParser);
registerPage("sessionsOverview", sessionsOverviewJSONParser);
registerPage("servers", jsonFactory::serversAsJSONMaps);
registerPage("pingTable", jsonFactory::pingPerGeolocation);
registerPage("overview", DataID.SERVER_OVERVIEW, networkOverviewJSONParser);
registerPage("playerbaseOverview", DataID.PLAYERBASE_OVERVIEW, playerBaseOverviewJSONParser);
registerPage("sessionsOverview", DataID.SESSIONS_OVERVIEW, sessionsOverviewJSONParser);
registerPage("servers", DataID.SERVER_OVERVIEW, jsonFactory::serversAsJSONMaps);
registerPage("pingTable", DataID.PING_TABLE, jsonFactory::pingPerGeolocation);
}
private <T> void registerPage(String identifier, NetworkTabJSONParser<T> tabJSONParser) {
registerPage(identifier, new NetworkTabJSONHandler<>(tabJSONParser));
private <T> void registerPage(String identifier, DataID dataID, NetworkTabJSONParser<T> tabJSONParser) {
registerPage(identifier, new NetworkTabJSONHandler<>(dataID, cache, tabJSONParser));
}
@Override

View File

@ -20,11 +20,12 @@ import com.djrapitops.plan.delivery.rendering.json.network.NetworkTabJSONParser;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.exceptions.connection.WebException;
import java.util.function.Supplier;
@ -35,15 +36,19 @@ import java.util.function.Supplier;
*/
public class NetworkTabJSONHandler<T> implements PageHandler {
private final DataID dataID;
private final JSONCache cache;
private final Supplier<T> jsonParser;
public NetworkTabJSONHandler(NetworkTabJSONParser<T> jsonParser) {
public NetworkTabJSONHandler(DataID dataID, JSONCache cache, NetworkTabJSONParser<T> jsonParser) {
this.dataID = dataID;
this.cache = cache;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
return new JSONResponse(jsonParser.get());
public Response getResponse(Request request, RequestTarget target) {
return cache.getOrCache(dataID, () -> new JSONResponse(jsonParser.get()));
}
@Override

View File

@ -20,6 +20,8 @@ import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
@ -42,20 +44,25 @@ public class PlayerKillsJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final JSONFactory jsonFactory;
private final JSONCache cache;
@Inject
public PlayerKillsJSONHandler(
Identifiers identifiers,
JSONFactory jsonFactory
JSONFactory jsonFactory,
JSONCache cache
) {
this.identifiers = identifiers;
this.jsonFactory = jsonFactory;
this.cache = cache;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target);
return new JSONResponse(Collections.singletonMap("player_kills", jsonFactory.serverPlayerKillsAsJSONMap(serverUUID)));
return cache.getOrCache(DataID.KILLS, serverUUID, () ->
new JSONResponse(Collections.singletonMap("player_kills", jsonFactory.serverPlayerKillsAsJSONMap(serverUUID)))
);
}
@Override

View File

@ -21,6 +21,8 @@ import com.djrapitops.plan.delivery.rendering.json.PlayersTableJSONParser;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
@ -43,24 +45,27 @@ public class PlayersTableJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final JSONFactory jsonFactory;
private final JSONCache cache;
@Inject
public PlayersTableJSONHandler(
Identifiers identifiers,
JSONFactory jsonFactory
JSONFactory jsonFactory,
JSONCache cache
) {
this.identifiers = identifiers;
this.jsonFactory = jsonFactory;
this.cache = cache;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
if (target.getParameter("server").isPresent()) {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse(jsonFactory.serverPlayersTableJSON(serverUUID));
return cache.getOrCache(DataID.PLAYERS, serverUUID, () -> new JSONResponse(jsonFactory.serverPlayersTableJSON(serverUUID)));
}
// Assume network
return new JSONResponse(jsonFactory.networkPlayersTableJSON());
return cache.getOrCache(DataID.PLAYERS, () -> new JSONResponse(jsonFactory.networkPlayersTableJSON()));
}
@Override

View File

@ -19,6 +19,8 @@ package com.djrapitops.plan.delivery.webserver.pages.json;
import com.djrapitops.plan.delivery.rendering.json.*;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.TreePageHandler;
import com.djrapitops.plan.delivery.webserver.response.ResponseFactory;
import com.djrapitops.plan.exceptions.WebUserAuthException;
@ -35,11 +37,13 @@ import javax.inject.Singleton;
@Singleton
public class RootJSONHandler extends TreePageHandler {
private final JSONCache cache;
private Identifiers identifiers;
@Inject
public RootJSONHandler(
ResponseFactory responseFactory,
JSONCache cache,
Identifiers identifiers,
JSONFactory jsonFactory,
GraphsJSONHandler graphsJSONHandler,
@ -56,29 +60,28 @@ public class RootJSONHandler extends TreePageHandler {
NetworkJSONHandler networkJSONHandler
) {
super(responseFactory);
this.cache = cache;
this.identifiers = identifiers;
registerPage("players", playersTableJSONHandler);
registerPage("sessions", sessionsJSONHandler);
registerPage("kills", playerKillsJSONHandler);
registerPage("pingTable", jsonFactory::pingPerGeolocation);
registerPage("graph", graphsJSONHandler);
registerPage("players", playersTableJSONHandler, 1);
registerPage("sessions", sessionsJSONHandler, 0);
registerPage("kills", playerKillsJSONHandler, 0);
registerPage("pingTable", DataID.PING_TABLE, jsonFactory::pingPerGeolocation);
registerPage("graph", graphsJSONHandler, 0);
registerPage("serverOverview", serverOverviewJSONParser);
registerPage("onlineOverview", onlineActivityOverviewJSONParser);
registerPage("sessionsOverview", sessionsOverviewJSONParser);
registerPage("playerVersus", pvPPvEJSONParser);
registerPage("playerbaseOverview", playerBaseOverviewJSONParser);
registerPage("performanceOverview", performanceJSONParser);
registerPage("serverOverview", DataID.SERVER_OVERVIEW, serverOverviewJSONParser);
registerPage("onlineOverview", DataID.ONLINE_OVERVIEW, onlineActivityOverviewJSONParser);
registerPage("sessionsOverview", DataID.SESSIONS_OVERVIEW, sessionsOverviewJSONParser);
registerPage("playerVersus", DataID.PVP_PVE, pvPPvEJSONParser);
registerPage("playerbaseOverview", DataID.PLAYERBASE_OVERVIEW, playerBaseOverviewJSONParser);
registerPage("performanceOverview", DataID.PERFORMANCE_OVERVIEW, performanceJSONParser);
registerPage("player", playerJSONHandler);
registerPage("network", networkJSONHandler);
registerPage("player", playerJSONHandler, 2);
registerPage("network", networkJSONHandler, 0);
}
private <T> void registerPage(String identifier, ServerTabJSONParser<T> tabJSONParser) {
registerPage(identifier, new ServerTabJSONHandler<>(identifiers, tabJSONParser));
private <T> void registerPage(String identifier, DataID dataID, ServerTabJSONParser<T> tabJSONParser) {
registerPage(identifier, new ServerTabJSONHandler<>(dataID, cache, identifiers, tabJSONParser), 0);
}
@Override

View File

@ -20,6 +20,8 @@ import com.djrapitops.plan.delivery.rendering.json.ServerTabJSONParser;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
@ -37,10 +39,19 @@ import java.util.function.Function;
*/
public class ServerTabJSONHandler<T> implements PageHandler {
private final DataID dataID;
private final JSONCache cache;
private final Identifiers identifiers;
private final Function<UUID, T> jsonParser;
public ServerTabJSONHandler(Identifiers identifiers, ServerTabJSONParser<T> jsonParser) {
public ServerTabJSONHandler(
DataID dataID,
JSONCache cache,
Identifiers identifiers,
ServerTabJSONParser<T> jsonParser
) {
this.dataID = dataID;
this.cache = cache;
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@ -48,7 +59,7 @@ public class ServerTabJSONHandler<T> implements PageHandler {
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse(jsonParser.apply(serverUUID));
return cache.getOrCache(dataID, serverUUID, () -> new JSONResponse(jsonParser.apply(serverUUID)));
}
@Override

View File

@ -20,6 +20,8 @@ import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.webserver.Request;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
import com.djrapitops.plan.delivery.webserver.cache.DataID;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.delivery.webserver.pages.PageHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.data.JSONResponse;
@ -42,24 +44,31 @@ public class SessionsJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final JSONFactory jsonFactory;
private final JSONCache cache;
@Inject
public SessionsJSONHandler(
Identifiers identifiers,
JSONFactory jsonFactory
JSONFactory jsonFactory,
JSONCache cache
) {
this.identifiers = identifiers;
this.jsonFactory = jsonFactory;
this.cache = cache;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
if (target.getParameter("server").isPresent()) {
UUID serverUUID = identifiers.getServerUUID(target);
return new JSONResponse(Collections.singletonMap("sessions", jsonFactory.networkSessionsAsJSONMap(serverUUID)));
return cache.getOrCache(DataID.SESSIONS, serverUUID, () ->
new JSONResponse(Collections.singletonMap("sessions", jsonFactory.serverSessionsAsJSONMap(serverUUID)))
);
}
// Assume network
return new JSONResponse(Collections.singletonMap("sessions", jsonFactory.networkSessionsAsJSONMap()));
return cache.getOrCache(DataID.SESSIONS, () ->
new JSONResponse(Collections.singletonMap("sessions", jsonFactory.networkSessionsAsJSONMap()))
);
}
@Override