From 605b70bf0130ffbbc64f92c14c4dc01329cbf78f Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Sat, 25 Jun 2016 16:23:44 -0400 Subject: [PATCH] Finish the server heartbeat --- .../net/frozenorb/apiv3/model/IpIntel.java | 2 +- .../java/net/frozenorb/apiv3/model/User.java | 63 +++++++++--- .../apiv3/route/ipIntel/GETIpInteld.java | 2 +- .../route/servers/POSTServersHeartbeat.java | 99 ++++++------------- 4 files changed, 81 insertions(+), 85 deletions(-) diff --git a/src/main/java/net/frozenorb/apiv3/model/IpIntel.java b/src/main/java/net/frozenorb/apiv3/model/IpIntel.java index 4e83b16..4e8c943 100644 --- a/src/main/java/net/frozenorb/apiv3/model/IpIntel.java +++ b/src/main/java/net/frozenorb/apiv3/model/IpIntel.java @@ -33,7 +33,7 @@ public final class IpIntel { ipIntelCollection.find(new Document("_id", id)).first(callback); } - public static void findByIdOrInsert(String id, SingleResultCallback callback) { + public static void findOrCreateById(String id, SingleResultCallback callback) { findById(id, (existingIpIntel, error) -> { if (error != null) { callback.onResult(null, error); diff --git a/src/main/java/net/frozenorb/apiv3/model/User.java b/src/main/java/net/frozenorb/apiv3/model/User.java index e33f07c..8db0360 100644 --- a/src/main/java/net/frozenorb/apiv3/model/User.java +++ b/src/main/java/net/frozenorb/apiv3/model/User.java @@ -32,6 +32,7 @@ import org.bson.Document; import java.time.Instant; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @Entity @@ -87,23 +88,55 @@ public final class User { usersCollection.find(new Document("lastUsername", lastUsername)).first(callback); } - public static void findByIdGrouped(Iterable search, SingleResultCallback> callback) { - usersCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (users, error) -> { + public static void findOrCreateByIdGrouped(Map search, SingleResultCallback> callback) { + usersCollection.find(new Document("_id", new Document("$in", search.keySet()))).into(new LinkedList<>(), (users, error) -> { if (error != null) { callback.onResult(null, error); - } else { - Map result = new HashMap<>(); - - for (UUID user : search) { - result.put(user, null); - } - - for (User user : users) { - result.put(user.getId(), user); - } - - callback.onResult(result, null); + return; } + + Map result = new ConcurrentHashMap<>(); + + for (User user : users) { + result.put(user.getId(), user); + } + + List createNewUserFutures = new ArrayList<>(); + + search.forEach((uuid, username) -> { + if (result.containsKey(uuid) || !UuidUtils.isAcceptableUuid(uuid)) { + return; + } + + Future createNewUserFuture = Future.future(); + createNewUserFutures.add(createNewUserFuture); + + User created = new User(uuid, username); + created.checkNameCollisions((ignored, error2) -> { + if (error2 != null) { + createNewUserFuture.fail(error2); + return; + } + + created.insert((ignored2, error3) -> { + if (error3 != null) { + createNewUserFuture.fail(error3); + return; + } + + result.put(uuid, created); + createNewUserFuture.complete(); + }); + }); + }); + + CompositeFuture.all(createNewUserFutures).setHandler((creationStatus) -> { + if (creationStatus.failed()) { + callback.onResult(null, creationStatus.cause()); + } else { + callback.onResult(result, null); + } + }); }); } @@ -174,7 +207,7 @@ public final class User { ), new FutureCompatibilityCallback<>(punishmentsFuture)); if (userIp != null) { - IpIntel.findByIdOrInsert(userIp, new FutureCompatibilityCallback<>(ipIntelFuture)); + IpIntel.findOrCreateById(userIp, new FutureCompatibilityCallback<>(ipIntelFuture)); IpBan.findByIp(userIp, new FutureCompatibilityCallback<>(ipBansFuture)); } else { ipIntelFuture.complete(null); diff --git a/src/main/java/net/frozenorb/apiv3/route/ipIntel/GETIpInteld.java b/src/main/java/net/frozenorb/apiv3/route/ipIntel/GETIpInteld.java index 570465a..11bbb1e 100644 --- a/src/main/java/net/frozenorb/apiv3/route/ipIntel/GETIpInteld.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipIntel/GETIpInteld.java @@ -17,7 +17,7 @@ public final class GETIpInteld implements Handler { return; } - IpIntel.findByIdOrInsert(userIp, (ipIntel, error) -> { + IpIntel.findOrCreateById(userIp, (ipIntel, error) -> { if (error != null) { ErrorUtils.respondInternalError(ctx, error); } else { diff --git a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServersHeartbeat.java b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServersHeartbeat.java index 197e399..af7792c 100644 --- a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServersHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServersHeartbeat.java @@ -79,7 +79,7 @@ public final class POSTServersHeartbeat implements Handler { Future>> grantLookupCallback = Future.future(); Future>> punishmentLookupCallback = Future.future(); - User.findByIdGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(userLookupCallback)); + User.findOrCreateByIdGrouped(playerNames, new FutureCompatibilityCallback<>(userLookupCallback)); Grant.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(grantLookupCallback)); Punishment.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(punishmentLookupCallback)); @@ -87,37 +87,35 @@ public final class POSTServersHeartbeat implements Handler { userLookupCallback, grantLookupCallback, punishmentLookupCallback - ).setHandler((result) -> { - if (result.failed()) { - callback.fail(result.cause()); + ).setHandler((batchLookupInfo) -> { + if (batchLookupInfo.failed()) { + callback.fail(batchLookupInfo.cause()); return; } - Map users = result.result().result(0); - Map> grants = result.result().result(1); - Map> punishments = result.result().result(2); - Map response = new HashMap<>(); - List loginInfoFutures = new LinkedList<>(); + Map users = batchLookupInfo.result().result(0); + Map> grants = batchLookupInfo.result().result(1); + Map> punishments = batchLookupInfo.result().result(2); + Map loginInfoFutures = new HashMap<>(); users.forEach((uuid, user) -> { Future> loginInfoFuture = Future.future(); - - createLoginInfo(uuid, user, server, grants.get(uuid), punishments.get(uuid), Future.>future().setHandler((loginInfoResult) -> { - if (loginInfoResult.failed()) { - loginInfoFuture.fail(loginInfoFuture.cause()); - } else { - loginInfoFuture.complete(ImmutableMap.of(uuid.toString(), loginInfoResult.result())); - } - })); - - loginInfoFutures.add(loginInfoFuture); + createLoginInfo(user, server, grants.get(uuid), punishments.get(uuid), loginInfoFuture); + loginInfoFutures.put(uuid, loginInfoFuture); }); - CompositeFuture.all(loginInfoFutures).setHandler((allLoginInfo) -> { - for (int i = 0; i < allLoginInfo.result().size(); i++) { - response.putAll(allLoginInfo.result().result(i)); + CompositeFuture.all(ImmutableList.copyOf(loginInfoFutures.values())).setHandler((allLoginInfo) -> { + if (allLoginInfo.failed()) { + callback.fail(allLoginInfo.cause()); + return; } + Map response = new HashMap<>(); + + loginInfoFutures.forEach((uuid, loginInfo) -> { + response.put(uuid.toString(), loginInfo.result()); + }); + callback.complete(response); }); }); @@ -181,54 +179,19 @@ public final class POSTServersHeartbeat implements Handler { return result; } - private void createLoginInfo(UUID uuid, User user, Server server, List grants, List punishments, Future> callback) { - if (user == null) { - /*String username = playerNames.get(uuid); - user = new User(uuid, username); - BlockingCallback nameCollisionCallback = new BlockingCallback<>(); - user.checkNameCollisions(nameCollisionCallback); - nameCollisionCallback.get(); - BlockingCallback insertCallback = new BlockingCallback<>(); - user.insert(insertCallback); - insertCallback.get(); - users.put(uuid, user); + private void createLoginInfo(User user, Server server, List grants, List punishments, Future> callback) { + if (user.seenOnServer(server)) { + user.save((ignored, error) -> { + if (error != null) { + callback.fail(error); + return; + } - // Only save if needed - if (user.seenOnServer(server)) { - BlockingCallback saveCallback = new BlockingCallback<>(); - user.save(saveCallback); - saveCallback.get(); - } - - // TODO: Provide IPs for ip ban lookup (and ip intel) - BlockingCallback> loginInfo = new BlockingCallback<>(); - user.getLoginInfo(server, null, punishments.get(uuid), ImmutableList.of(), grants.get(uuid), loginInfo); - res2.put(uuid.toString(), loginInfo.get());*/ + // TODO: IP BAN INFO (AND FOR LINE BELOW) + user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new FutureCompatibilityCallback<>(callback)); + }); } else { - if (user.seenOnServer(server)) { - user.save((ignored, error) -> { - if (error != null) { - callback.fail(error); - return; - } - - user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, (loginInfo, error2) -> { - if (error2 != null) { - callback.fail(error2); - } else { - callback.complete(loginInfo); - } - }); - }); - } else { - user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, (loginInfo, error2) -> { - if (error2 != null) { - callback.fail(error2); - } else { - callback.complete(loginInfo); - } - }); - } + user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new FutureCompatibilityCallback<>(callback)); } }