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);
}
public static void findByIdOrInsert(String id, SingleResultCallback<IpIntel> callback) {
public static void findOrCreateById(String id, SingleResultCallback<IpIntel> callback) {
findById(id, (existingIpIntel, error) -> {
if (error != null) {
callback.onResult(null, error);

View File

@ -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<UUID> search, SingleResultCallback<Map<UUID, User>> callback) {
usersCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (users, error) -> {
public static void findOrCreateByIdGrouped(Map<UUID, String> search, SingleResultCallback<Map<UUID, User>> 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<UUID, User> 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<UUID, User> result = new ConcurrentHashMap<>();
for (User user : users) {
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);
}
});
});
}
@ -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);

View File

@ -17,7 +17,7 @@ public final class GETIpInteld implements Handler<RoutingContext> {
return;
}
IpIntel.findByIdOrInsert(userIp, (ipIntel, error) -> {
IpIntel.findOrCreateById(userIp, (ipIntel, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} 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<Punishment>>> 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<RoutingContext> {
userLookupCallback,
grantLookupCallback,
punishmentLookupCallback
).setHandler((result) -> {
if (result.failed()) {
callback.fail(result.cause());
).setHandler((batchLookupInfo) -> {
if (batchLookupInfo.failed()) {
callback.fail(batchLookupInfo.cause());
return;
}
Map<UUID, User> users = result.result().result(0);
Map<UUID, List<Grant>> grants = result.result().result(1);
Map<UUID, List<Punishment>> punishments = result.result().result(2);
Map<String, Object> response = new HashMap<>();
List<Future> loginInfoFutures = new LinkedList<>();
Map<UUID, User> users = batchLookupInfo.result().result(0);
Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(1);
Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(2);
Map<UUID, Future> loginInfoFutures = new HashMap<>();
users.forEach((uuid, user) -> {
Future<Map<String, Object>> loginInfoFuture = Future.future();
createLoginInfo(uuid, user, server, grants.get(uuid), punishments.get(uuid), Future.<Map<String, Object>>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<String, Object> 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<RoutingContext> {
return result;
}
private void createLoginInfo(UUID uuid, 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);
private void createLoginInfo(User user, Server server, List<Grant> grants, List<Punishment> punishments, Future<Map<String, Object>> 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<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());*/
// 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));
}
}