Finish the server heartbeat

This commit is contained in:
Colin McDonald 2016-06-25 16:23:44 -04:00
parent a255d45603
commit 605b70bf01
4 changed files with 81 additions and 85 deletions

View File

@ -33,7 +33,7 @@ public final class IpIntel {
ipIntelCollection.find(new Document("_id", id)).first(callback); ipIntelCollection.find(new Document("_id", id)).first(callback);
} }
public static void findByIdOrInsert(String id, SingleResultCallback<IpIntel> callback) { public static void findOrCreateById(String id, SingleResultCallback<IpIntel> callback) {
findById(id, (existingIpIntel, error) -> { findById(id, (existingIpIntel, error) -> {
if (error != null) { if (error != null) {
callback.onResult(null, error); callback.onResult(null, error);

View File

@ -32,6 +32,7 @@ import org.bson.Document;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Entity @Entity
@ -87,24 +88,56 @@ public final class User {
usersCollection.find(new Document("lastUsername", lastUsername)).first(callback); usersCollection.find(new Document("lastUsername", lastUsername)).first(callback);
} }
public static void findByIdGrouped(Iterable<UUID> search, SingleResultCallback<Map<UUID, User>> callback) { public static void findOrCreateByIdGrouped(Map<UUID, String> search, SingleResultCallback<Map<UUID, User>> callback) {
usersCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (users, error) -> { usersCollection.find(new Document("_id", new Document("$in", search.keySet()))).into(new LinkedList<>(), (users, error) -> {
if (error != null) { if (error != null) {
callback.onResult(null, error); callback.onResult(null, error);
} else { return;
Map<UUID, User> result = new HashMap<>();
for (UUID user : search) {
result.put(user, null);
} }
Map<UUID, User> result = new ConcurrentHashMap<>();
for (User user : users) { for (User user : users) {
result.put(user.getId(), user); result.put(user.getId(), user);
} }
List<Future> 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); callback.onResult(result, null);
} }
}); });
});
} }
private User() {} // For Jackson private User() {} // For Jackson
@ -174,7 +207,7 @@ public final class User {
), new FutureCompatibilityCallback<>(punishmentsFuture)); ), new FutureCompatibilityCallback<>(punishmentsFuture));
if (userIp != null) { if (userIp != null) {
IpIntel.findByIdOrInsert(userIp, new FutureCompatibilityCallback<>(ipIntelFuture)); IpIntel.findOrCreateById(userIp, new FutureCompatibilityCallback<>(ipIntelFuture));
IpBan.findByIp(userIp, new FutureCompatibilityCallback<>(ipBansFuture)); IpBan.findByIp(userIp, new FutureCompatibilityCallback<>(ipBansFuture));
} else { } else {
ipIntelFuture.complete(null); ipIntelFuture.complete(null);

View File

@ -17,7 +17,7 @@ public final class GETIpInteld implements Handler<RoutingContext> {
return; return;
} }
IpIntel.findByIdOrInsert(userIp, (ipIntel, error) -> { IpIntel.findOrCreateById(userIp, (ipIntel, error) -> {
if (error != null) { if (error != null) {
ErrorUtils.respondInternalError(ctx, error); ErrorUtils.respondInternalError(ctx, error);
} else { } else {

View File

@ -79,7 +79,7 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
Future<Map<UUID, List<Grant>>> grantLookupCallback = Future.future(); Future<Map<UUID, List<Grant>>> grantLookupCallback = Future.future();
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future(); Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
User.findByIdGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(userLookupCallback)); User.findOrCreateByIdGrouped(playerNames, new FutureCompatibilityCallback<>(userLookupCallback));
Grant.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(grantLookupCallback)); Grant.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(grantLookupCallback));
Punishment.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(punishmentLookupCallback)); Punishment.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(punishmentLookupCallback));
@ -87,37 +87,35 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
userLookupCallback, userLookupCallback,
grantLookupCallback, grantLookupCallback,
punishmentLookupCallback punishmentLookupCallback
).setHandler((result) -> { ).setHandler((batchLookupInfo) -> {
if (result.failed()) { if (batchLookupInfo.failed()) {
callback.fail(result.cause()); callback.fail(batchLookupInfo.cause());
return; return;
} }
Map<UUID, User> users = result.result().result(0); Map<UUID, User> users = batchLookupInfo.result().result(0);
Map<UUID, List<Grant>> grants = result.result().result(1); Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(1);
Map<UUID, List<Punishment>> punishments = result.result().result(2); Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(2);
Map<String, Object> response = new HashMap<>(); Map<UUID, Future> loginInfoFutures = new HashMap<>();
List<Future> loginInfoFutures = new LinkedList<>();
users.forEach((uuid, user) -> { users.forEach((uuid, user) -> {
Future<Map<String, Object>> loginInfoFuture = Future.future(); Future<Map<String, Object>> loginInfoFuture = Future.future();
createLoginInfo(user, server, grants.get(uuid), punishments.get(uuid), loginInfoFuture);
createLoginInfo(uuid, user, server, grants.get(uuid), punishments.get(uuid), Future.<Map<String, Object>>future().setHandler((loginInfoResult) -> { loginInfoFutures.put(uuid, loginInfoFuture);
if (loginInfoResult.failed()) {
loginInfoFuture.fail(loginInfoFuture.cause());
} else {
loginInfoFuture.complete(ImmutableMap.of(uuid.toString(), loginInfoResult.result()));
}
}));
loginInfoFutures.add(loginInfoFuture);
}); });
CompositeFuture.all(loginInfoFutures).setHandler((allLoginInfo) -> { CompositeFuture.all(ImmutableList.copyOf(loginInfoFutures.values())).setHandler((allLoginInfo) -> {
for (int i = 0; i < allLoginInfo.result().size(); i++) { if (allLoginInfo.failed()) {
response.putAll(allLoginInfo.result().result(i)); callback.fail(allLoginInfo.cause());
return;
} }
Map<String, Object> response = new HashMap<>();
loginInfoFutures.forEach((uuid, loginInfo) -> {
response.put(uuid.toString(), loginInfo.result());
});
callback.complete(response); callback.complete(response);
}); });
}); });
@ -181,30 +179,7 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
return result; return result;
} }
private void createLoginInfo(UUID uuid, User user, Server server, List<Grant> grants, List<Punishment> punishments, Future<Map<String, Object>> callback) { private void createLoginInfo(User user, Server server, List<Grant> grants, List<Punishment> punishments, Future<Map<String, Object>> callback) {
if (user == null) {
/*String username = playerNames.get(uuid);
user = new User(uuid, username);
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
user.checkNameCollisions(nameCollisionCallback);
nameCollisionCallback.get();
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
user.insert(insertCallback);
insertCallback.get();
users.put(uuid, user);
// Only save if needed
if (user.seenOnServer(server)) {
BlockingCallback<UpdateResult> saveCallback = new BlockingCallback<>();
user.save(saveCallback);
saveCallback.get();
}
// TODO: Provide IPs for ip ban lookup (and ip intel)
BlockingCallback<Map<String, Object>> loginInfo = new BlockingCallback<>();
user.getLoginInfo(server, null, punishments.get(uuid), ImmutableList.of(), grants.get(uuid), loginInfo);
res2.put(uuid.toString(), loginInfo.get());*/
} else {
if (user.seenOnServer(server)) { if (user.seenOnServer(server)) {
user.save((ignored, error) -> { user.save((ignored, error) -> {
if (error != null) { if (error != null) {
@ -212,23 +187,11 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
return; return;
} }
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, (loginInfo, error2) -> { // TODO: IP BAN INFO (AND FOR LINE BELOW)
if (error2 != null) { user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new FutureCompatibilityCallback<>(callback));
callback.fail(error2);
} else {
callback.complete(loginInfo);
}
});
}); });
} else { } else {
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, (loginInfo, error2) -> { user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new FutureCompatibilityCallback<>(callback));
if (error2 != null) {
callback.fail(error2);
} else {
callback.complete(loginInfo);
}
});
}
} }
} }