diff --git a/pom.xml b/pom.xml index 14ddddb..3696dfe 100644 --- a/pom.xml +++ b/pom.xml @@ -57,21 +57,16 @@ vertx-web 3.2.0 - - io.vertx - vertx-mongo-client - 3.2.0 - - - io.vertx - vertx-redis-client - 3.2.0 - com.google.guava guava 19.0 + + org.mongodb + mongodb-driver-async + 3.0.4 + org.projectlombok lombok diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 327e4c6..0e19f09 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -1,27 +1,64 @@ package net.frozenorb.apiv3; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mongodb.MongoCredential; +import com.mongodb.ServerAddress; +import com.mongodb.async.client.MongoClient; +import com.mongodb.async.client.MongoClientSettings; +import com.mongodb.async.client.MongoClients; +import com.mongodb.async.client.MongoDatabase; +import com.mongodb.connection.ClusterConnectionMode; +import com.mongodb.connection.ClusterSettings; import io.vertx.core.AbstractVerticle; import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.mongo.MongoClient; import io.vertx.ext.web.Router; import lombok.Getter; +import net.frozenorb.apiv3.collections.AuditLog; +import net.frozenorb.apiv3.collections.Grant; import net.frozenorb.apiv3.collections.Server; +import net.frozenorb.apiv3.mongoCodec.InstantCodec; import net.frozenorb.apiv3.utils.ErrorUtils; +import org.bson.BsonType; +import org.bson.Document; +import org.bson.codecs.BsonTypeClassMap; +import org.bson.codecs.BsonValueCodecProvider; +import org.bson.codecs.DocumentCodecProvider; +import org.bson.codecs.ValueCodecProvider; +import org.bson.codecs.configuration.CodecRegistries; +import org.bson.codecs.configuration.CodecRegistry; + +import java.time.Instant; +import java.util.UUID; +import java.util.stream.Collectors; public final class APIv3 extends AbstractVerticle { - @Getter private static MongoClient mongoClient; + @Getter private static MongoDatabase mongo; public void start() { Router coreHttpRouter = Router.router(vertx); - mongoClient = MongoClient.createShared(vertx, new JsonObject() - .put("host", "ds055505.mongolab.com") - .put("port", 55505) - .put("username", "test") - .put("password", "test") - .put("db_name", "minehqapi") + BsonTypeClassMap codecMap = new BsonTypeClassMap(ImmutableMap.of( + BsonType.DATE_TIME, Instant.class + )); + CodecRegistry codecRegistry = CodecRegistries.fromRegistries( + CodecRegistries.fromCodecs(new InstantCodec()), + CodecRegistries.fromProviders(new DocumentCodecProvider(codecMap)), + CodecRegistries.fromProviders(new ValueCodecProvider(), new DocumentCodecProvider(), new BsonValueCodecProvider()) ); + MongoClientSettings settings = + MongoClientSettings.builder() + .clusterSettings( + ClusterSettings.builder() + .mode(ClusterConnectionMode.SINGLE) + .hosts(ImmutableList.of(new ServerAddress("ds055505.mongolab.com", 55505))) + .build() + ) + .credentialList(ImmutableList.of(MongoCredential.createCredential("test", "minehqapi", "test".toCharArray()))) + .codecRegistry(codecRegistry) + .build(); + MongoClient mongoClient = MongoClients.create(settings); + mongo = mongoClient.getDatabase("minehqapi"); // We always reply in JSON. coreHttpRouter.route("/*").handler(ctx -> { @@ -33,15 +70,11 @@ public final class APIv3 extends AbstractVerticle { Server.findAll(res -> { if (res.succeeded()) { JsonArray response = new JsonArray(); - - res.result().forEach(server -> { - response.add(server.toLiteJson()); - }); + res.result().forEach(server -> response.add(server.toLiteJson())); ctx.response().end(response.encode()); } else { - JsonObject error = ErrorUtils.toJson(res.cause()); - ctx.response().end(error.encode()); + ctx.response().end(ErrorUtils.createResponse(res.cause()).toJson()); } }); }); @@ -49,15 +82,52 @@ public final class APIv3 extends AbstractVerticle { coreHttpRouter.get("/server/:server").handler(ctx -> { Server.findById(ctx.request().getParam("server"), res -> { if (res.succeeded()) { - JsonObject json = res.result().toFullJson(); - ctx.response().end(json.encode()); + res.result().update(); + ctx.response().end(res.result().toFullJson().toJson()); } else { - JsonObject error = ErrorUtils.toJson(res.cause()); - ctx.response().end(error.encode()); + ctx.response().end(ErrorUtils.createResponse(res.cause()).toJson()); } }); }); + coreHttpRouter.get("/user/:user/grants").handler(ctx -> { + UUID target = UUID.fromString(ctx.request().getParam("user")); + + Grant.findByTarget(target, res -> { + if (res.succeeded()) { + JsonArray response = new JsonArray(); + res.result().forEach(grant -> response.add(grant.toLiteJson())); + + ctx.response().end(response.encode()); + } else { + ctx.response().end(ErrorUtils.createResponse(res.cause()).toJson()); + } + }); + }); + + coreHttpRouter.get("/auditLog").handler(ctx -> { + AuditLog.findAll((auditLog, error) -> { + if (error != null) { + auditLog.stream().map(AuditLog::toLiteJson).collect(Collectors.toList()); + JsonArray response = new JsonArray(); + + auditLog.result().forEach(server -> { + response.add(server.toLiteJson()); + }); + + ctx.response().end(response.encode()); + } else { + ctx.response().end(ErrorUtils.createResponse(error).toJson()); + } + }); + }); + + coreHttpRouter.get("/doAction/:actionType").handler(ctx -> { + String actionType = ctx.request().getParam("actionType"); + AuditLog.log(UUID.randomUUID(), "192.168.1.1", actionType, new Document()); + ctx.response().end("its done"); + }); + vertx.createHttpServer().requestHandler(coreHttpRouter::accept).listen(8080); } diff --git a/src/main/java/net/frozenorb/apiv3/LiteFullJson.java b/src/main/java/net/frozenorb/apiv3/LiteFullJson.java index 9e5e923..5c5422d 100644 --- a/src/main/java/net/frozenorb/apiv3/LiteFullJson.java +++ b/src/main/java/net/frozenorb/apiv3/LiteFullJson.java @@ -1,12 +1,26 @@ package net.frozenorb.apiv3; -import io.vertx.core.json.JsonObject; +import org.bson.Document; + +import java.util.Collection; public interface LiteFullJson { - JsonObject toLiteJson(); - default JsonObject toFullJson() { + Document toLiteJson(); + default Document toFullJson() { return toLiteJson(); } + static String toLiteJson(Object value) { + if (value instanceof Collection) { + + } else { + + } + } + + static String toFullJson(Object value) { + + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/collections/AuditLog.java b/src/main/java/net/frozenorb/apiv3/collections/AuditLog.java index 9a358c6..d64fa4d 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/AuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/collections/AuditLog.java @@ -1,46 +1,89 @@ package net.frozenorb.apiv3.collections; +import com.mongodb.async.SingleResultCallback; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.LiteFullJson; +import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; +import org.bson.types.ObjectId; -import java.util.List; +import java.time.Instant; +import java.util.Collection; +import java.util.Date; +import java.util.UUID; @ToString public final class AuditLog implements LiteFullJson { - public static final String COLLECTION_NAME = "auditLog"; + private static final String COLLECTION_NAME = "auditLog"; + private static final Document TIME_BASED_SORT = new Document("performedAt", -1); @Getter private String id; + @Getter private UUID performedBy; + @Getter private Instant performedAt; + @Getter private long performedFrom; + @Getter private String actionType; + @Getter private Document actionData; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), AuditLog::new, callback); + public static void findAll(SingleResultCallback> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), TIME_BASED_SORT, AuditLog::new, callback); } - public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), AuditLog::new, callback); + public static void findByPerformer(UUID performer, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("performedBy", performer.toString()), AuditLog::new, callback); } - private AuditLog(JsonObject json) { + public static void findByPerformerIp(long machineIp, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("performedFrom", machineIp), AuditLog::new, callback); + } + + public static void findByActionType(String actionType, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("actionType", actionType), AuditLog::new, callback); + } + + public static void log(UUID user, String userIp, String actionType, Document data) { + Document insert = new Document(); + + insert.put("_id", new ObjectId().toString()); + insert.put("performedBy", user.toString()); + insert.put("performedAt", new Date()); + insert.put("performedFrom", IPUtils.humanToMachine(userIp)); + insert.put("actionType", actionType); + insert.put("actionData", data); + + APIv3.getMongo().getCollection(COLLECTION_NAME).insertOne(insert, (result, error) -> {}); + } + + private AuditLog(Document json) { this.id = json.getString("_id"); + this.performedBy = UUID.fromString(json.getString("performedBy")); + this.performedAt = json.get("performedAt", Instant.class); + this.performedFrom = json.getLong("performedFrom"); + this.actionType = json.getString("actionType"); + this.actionData = json.get("actionData", Document.class); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); - json.put("_id", id); + json.put("id", id); + json.put("performedBy", performedBy.toString()); + json.put("performedAt", performedAt.toString()); + json.put("performedFrom", IPUtils.machineToHuman(performedFrom)); + json.put("actionType", actionType); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); - + public Document toFullJson() { + Document json = toLiteJson(); + json.put("actionData", actionData); return json; } diff --git a/src/main/java/net/frozenorb/apiv3/collections/EmailTemplate.java b/src/main/java/net/frozenorb/apiv3/collections/EmailTemplate.java index d6c2223..3171606 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/EmailTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/collections/EmailTemplate.java @@ -2,47 +2,65 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; +import java.util.Map; @ToString public final class EmailTemplate implements LiteFullJson { - public static final String COLLECTION_NAME = "emailTemplate"; + private static final String COLLECTION_NAME = "emailTemplate"; @Getter private String id; + @Getter private String title; + @Getter private String body; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), EmailTemplate::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), EmailTemplate::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), EmailTemplate::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), EmailTemplate::new, callback); } - private EmailTemplate(JsonObject json) { + private EmailTemplate(Document json) { this.id = json.getString("_id"); + this.title = json.getString("title"); + this.body = json.getString("body"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); - json.put("_id", id); + json.put("id", id); + json.put("title", title); + json.put("body", body); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public String fillTitle(Map replacements) { + return fill(title, replacements); + } + public String fillBody(Map replacements) { + return fill(body, replacements); + } + private String fill(String working, Map replacements) { + for (Map.Entry replacement : replacements.entrySet()) { + String key = replacement.getKey(); + String value = String.valueOf(replacement.getValue()); - return json; + working = working.replace(key, value); + } + + return working; } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/collections/Grant.java b/src/main/java/net/frozenorb/apiv3/collections/Grant.java index eae67dd..a33e404 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/collections/Grant.java @@ -1,46 +1,84 @@ package net.frozenorb.apiv3.collections; +import com.google.common.collect.ImmutableSet; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.time.Instant; +import java.util.Collection; +import java.util.Set; +import java.util.UUID; @ToString public final class Grant implements LiteFullJson { - public static final String COLLECTION_NAME = "grant"; + private static final String COLLECTION_NAME = "grant"; @Getter private String id; + @Getter private UUID target; + @Getter private String reason; + @Getter private Set scopes; + @Getter private String rank; + @Getter private UUID addedBy; + @Getter private Instant addedAt; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), Grant::new, callback); + @Getter private UUID removedBy; + @Getter private Instant removedAt; + @Getter private String removalReason; + + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), Grant::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), Grant::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), Grant::new, callback); } - private Grant(JsonObject json) { + public static void findByTarget(UUID target, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("target", target.toString()), Grant::new, callback); + } + + public static void findByAddedBy(UUID addedBy, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("addedBy", addedBy.toString()), Grant::new, callback); + } + + private Grant(Document json) { this.id = json.getString("_id"); + this.target = UUID.fromString(json.getString("target")); + this.reason = json.getString("reason"); + this.scopes = ImmutableSet.copyOf((Collection) json.get("scopes")); // This is a safe cast, the collection's type is always String + this.rank = json.getString("rank"); + this.addedBy = UUID.fromString(json.getString("addedBy")); + this.addedAt = (Instant) json.get("addedAt"); + + if (json.containsKey("removedBy")) { + this.removedBy = UUID.fromString(json.getString("removedBy")); + this.removedAt = (Instant) json.get("removedAt"); + this.removalReason = json.getString("removalReason"); + } } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); - - json.put("_id", id); - - return json; - } - - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toLiteJson() { + Document json = new Document(); + json.put("id", id); + json.put("target", target.toString()); + json.put("reason", reason); + json.put("scopes", scopes); + json.put("rank", rank); + json.put("addedBy", addedBy.toString()); + json.put("addedAt", addedAt.toString()); + if (removedBy != null) { + json.put("removedBy", removedBy.toString()); + json.put("removedAt", removedAt.toString()); + json.put("removalReason", removalReason); + } return json; } diff --git a/src/main/java/net/frozenorb/apiv3/collections/IPBan.java b/src/main/java/net/frozenorb/apiv3/collections/IPBan.java index cc67e82..8584c49 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/IPBan.java +++ b/src/main/java/net/frozenorb/apiv3/collections/IPBan.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class IPBan implements LiteFullJson { - public static final String COLLECTION_NAME = "ipBan"; + private static final String COLLECTION_NAME = "ipBan"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), IPBan::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), IPBan::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), IPBan::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), IPBan::new, callback); } - private IPBan(JsonObject json) { + private IPBan(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/IPLog.java b/src/main/java/net/frozenorb/apiv3/collections/IPLog.java index 4bcbd0e..d84c397 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/IPLog.java +++ b/src/main/java/net/frozenorb/apiv3/collections/IPLog.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class IPLog implements LiteFullJson { - public static final String COLLECTION_NAME = "ipLog"; + private static final String COLLECTION_NAME = "ipLog"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), IPLog::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), IPLog::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), IPLog::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), IPLog::new, callback); } - private IPLog(JsonObject json) { + private IPLog(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/MaxMindCache.java b/src/main/java/net/frozenorb/apiv3/collections/MaxMindCache.java index 3ce2cd1..1443088 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/MaxMindCache.java +++ b/src/main/java/net/frozenorb/apiv3/collections/MaxMindCache.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class MaxMindCache implements LiteFullJson { - public static final String COLLECTION_NAME = "maxMindCache"; + private static final String COLLECTION_NAME = "maxMindCache"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), MaxMindCache::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), MaxMindCache::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), MaxMindCache::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), MaxMindCache::new, callback); } - private MaxMindCache(JsonObject json) { + private MaxMindCache(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/NotificationLog.java b/src/main/java/net/frozenorb/apiv3/collections/NotificationLog.java index 186c6ab..d10ce3b 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/NotificationLog.java +++ b/src/main/java/net/frozenorb/apiv3/collections/NotificationLog.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class NotificationLog implements LiteFullJson { - public static final String COLLECTION_NAME = "notificationLog"; + private static final String COLLECTION_NAME = "notificationLog"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), NotificationLog::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), NotificationLog::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), NotificationLog::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), NotificationLog::new, callback); } - private NotificationLog(JsonObject json) { + private NotificationLog(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/Punishment.java b/src/main/java/net/frozenorb/apiv3/collections/Punishment.java index 5b46c8c..e397f0d 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/collections/Punishment.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class Punishment implements LiteFullJson { - public static final String COLLECTION_NAME = "punishment"; + private static final String COLLECTION_NAME = "punishment"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), Punishment::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), Punishment::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), Punishment::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), Punishment::new, callback); } - private Punishment(JsonObject json) { + private Punishment(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/Server.java b/src/main/java/net/frozenorb/apiv3/collections/Server.java index f3fefca..3d2e1d3 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/Server.java +++ b/src/main/java/net/frozenorb/apiv3/collections/Server.java @@ -2,22 +2,21 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; @ToString(exclude={ "secret" }) public final class Server implements LiteFullJson { - public static final String COLLECTION_NAME = "server"; + private static final String COLLECTION_NAME = "server"; @Getter private String id; @Getter private String bungeeId; @@ -29,36 +28,40 @@ public final class Server implements LiteFullJson { @Getter private double lastTps; @Getter private List players; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), Server::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), Server::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), Server::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), Server::new, callback); } - public static void findByGroup(String groupId, Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject().put("group", groupId), Server::new, callback); + public static void findByGroup(String groupId, Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document("group", groupId), Server::new, callback); } - private Server(JsonObject json) { + private Server(Document json) { this.id = json.getString("_id"); this.bungeeId = json.getString("bungeeId"); this.displayName = json.getString("displayName"); this.secret = json.getString("secret"); this.group = json.getString("group"); this.internalIp = json.getString("internalIp"); - this.lastUpdate = json.getInstant("lastUpdate"); - this.lastTps = json.getDouble("lastTps"); + this.lastUpdate = json.get("lastUpdate", Instant.class); + this.lastTps = json.get("lastTps", Number.class).doubleValue(); this.players = new ArrayList<>(); - for (Object uuidString : json.getJsonArray("players")) { + for (Object uuidString : json.get("players", Collection.class)) { players.add(UUID.fromString((String) uuidString)); } } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public void update() { + APIv3.getMongo().getCollection(COLLECTION_NAME).updateOne(new Document("_id", id), new Document("$set", new Document("lastUpdate", new Date())), (result, error) -> {}); + } + + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); json.put("bungeeId", bungeeId); @@ -69,12 +72,12 @@ public final class Server implements LiteFullJson { return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); - json.put("lastUpdate", lastUpdate); + json.put("lastUpdate", lastUpdate.toString()); json.put("lastTps", lastTps); - json.put("players", new JsonArray(players)); + json.put("players", players.stream().map(UUID::toString).collect(Collectors.toList())); return json; } diff --git a/src/main/java/net/frozenorb/apiv3/collections/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/collections/ServerGroup.java index 6e605b4..f7ff4d5 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/ServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/collections/ServerGroup.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class ServerGroup implements LiteFullJson { - public static final String COLLECTION_NAME = "serverGroup"; + private static final String COLLECTION_NAME = "serverGroup"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), ServerGroup::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), ServerGroup::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), ServerGroup::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), ServerGroup::new, callback); } - private ServerGroup(JsonObject json) { + private ServerGroup(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/collections/User.java b/src/main/java/net/frozenorb/apiv3/collections/User.java index 491b829..765fde4 100644 --- a/src/main/java/net/frozenorb/apiv3/collections/User.java +++ b/src/main/java/net/frozenorb/apiv3/collections/User.java @@ -2,43 +2,43 @@ package net.frozenorb.apiv3.collections; import io.vertx.core.AsyncResult; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.LiteFullJson; import net.frozenorb.apiv3.utils.MongoUtils; +import org.bson.Document; -import java.util.List; +import java.util.Collection; @ToString public final class User implements LiteFullJson { - public static final String COLLECTION_NAME = "user"; + private static final String COLLECTION_NAME = "user"; @Getter private String id; - public static void findAll(Handler>> callback) { - MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject(), User::new, callback); + public static void findAll(Handler>> callback) { + MongoUtils.findAndTransform(COLLECTION_NAME, new Document(), User::new, callback); } public static void findById(String id, Handler> callback) { - MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), User::new, callback); + MongoUtils.findOneAndTransform(COLLECTION_NAME, new Document("_id", id), User::new, callback); } - private User(JsonObject json) { + private User(Document json) { this.id = json.getString("_id"); } - public JsonObject toLiteJson() { - JsonObject json = new JsonObject(); + public Document toLiteJson() { + Document json = new Document(); json.put("_id", id); return json; } - public JsonObject toFullJson() { - JsonObject json = toLiteJson(); + public Document toFullJson() { + Document json = toLiteJson(); diff --git a/src/main/java/net/frozenorb/apiv3/mongoCodec/InstantCodec.java b/src/main/java/net/frozenorb/apiv3/mongoCodec/InstantCodec.java new file mode 100644 index 0000000..df1cbff --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/mongoCodec/InstantCodec.java @@ -0,0 +1,26 @@ +package net.frozenorb.apiv3.mongoCodec; + +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; + +import java.time.Instant; + +public final class InstantCodec implements Codec { + + public void encode(BsonWriter writer, Instant value, EncoderContext context) { + writer.writeDateTime(value.toEpochMilli()); + } + + public Instant decode(BsonReader reader, DecoderContext context) { + long epochMillis = reader.readDateTime(); + return Instant.ofEpochMilli(epochMillis); + } + + public Class getEncoderClass() { + return Instant.class; + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java index bdd3c96..0b08d8d 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java @@ -1,21 +1,33 @@ package net.frozenorb.apiv3.utils; -import io.vertx.core.json.JsonObject; import lombok.experimental.UtilityClass; +import org.bson.Document; + +import java.util.UUID; @UtilityClass public class ErrorUtils { - public static JsonObject toJson(Throwable throwable) { - return toJson(throwable.getClass().getSimpleName()); + public static Document createResponse(Throwable throwable) { + // We do this identifier thing so we can easily search logs for the exception. + // We can't send the stack trace to the user, so this is a good alternative. + String identifier = UUID.randomUUID().toString(); + System.out.println("[Caught exception] Identifier=" + identifier); + throwable.printStackTrace(); + + return createResponse(throwable.getClass().getSimpleName(), identifier); } - public static JsonObject toJson(String reason) { - JsonObject json = new JsonObject(); + public static Document createResponse(String reason, String identifier) { + Document json = new Document(); json.put("failed", true); json.put("reason", reason); + if (identifier != null) { + json.put("identifier", identifier); + } + return json; } diff --git a/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java index 130ed28..1c970b7 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java @@ -2,58 +2,52 @@ package net.frozenorb.apiv3.utils; import com.google.common.base.Function; import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; +import com.mongodb.async.client.FindIterable; import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.mongo.FindOptions; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; +import org.bson.Document; +import java.util.ArrayList; import java.util.Collection; -import java.util.List; @UtilityClass public class MongoUtils { - private static final FindOptions limitOneOptions = new FindOptions().setLimit(1); - private static final FindOptions defaultOptions = new FindOptions(); + private static FindIterable createFindIterable(String collection, Document query, Document sort) { + return APIv3.getMongo().getCollection(collection).find(query).sort(sort); + } - public static void findOneAndTransform(String collection, JsonObject query, Function transformation, Handler> callback) { - APIv3.getMongoClient().findWithOptions(collection, query, limitOneOptions, res -> { - if (res.succeeded()) { - if (!res.result().isEmpty()) { - JsonObject json = res.result().get(0); - T transformed = transformation.apply(json); + public static void findOneAndTransform(String collection, Document query, Function transformation, Handler> callback) { + findOneAndTransform(collection, query, new Document(), transformation, callback); + } - callback.handle(Future.succeededFuture(transformed)); - } else { - callback.handle(Future.succeededFuture(null)); - } + public static void findOneAndTransform(String collection, Document query, Document sort, Function transformation, Handler> callback) { + createFindIterable(collection, query, sort).first((result, error) -> { + if (error != null) { + callback.handle(Future.failedFuture(error)); } else { - callback.handle(Future.failedFuture(res.cause())); + T transformed = transformation.apply(result); + callback.handle(Future.succeededFuture(transformed)); } }); } - public static void findManyAndTransform(String collection, JsonObject query, Function transformation, Handler>> callback) { - findManyAndTransform(collection, query, defaultOptions, transformation, callback); + public static void findAndTransform(String collection, Document query, Function transformation, Handler>> callback) { + findAndTransform(collection, query, new Document(), transformation, callback); } - public static void findManyAndTransform(String collection, JsonObject query, FindOptions options, Function transformation, Handler>> callback) { - APIv3.getMongoClient().findWithOptions(collection, query, options, res -> { - if (res.succeeded()) { - Collection servers = Collections2.transform(res.result(), transformation); - callback.handle(Future.succeededFuture(ImmutableList.copyOf(servers))); + public static void findAndTransform(String collection, Document query, Document sort, Function transformation, Handler>> callback) { + createFindIterable(collection, query, sort).into(new ArrayList<>(), (result, error) -> { + if (error != null) { + callback.handle(Future.failedFuture(error)); } else { - callback.handle(Future.failedFuture(res.cause())); + Collection transformed = Collections2.transform(result, transformation); + callback.handle(Future.succeededFuture(transformed)); } }); } - public static JsonObject set(JsonObject json) { - return new JsonObject().put("$set", json); - } - } \ No newline at end of file