diff --git a/README.md b/README.md index 188971b..01d6d11 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +TODO +- timeout/error handling with reactive + environment ----------- diff --git a/core-bukkit-api/build.gradle.kts b/core-bukkit-api/build.gradle.kts index c0b067e..f76f62c 100644 --- a/core-bukkit-api/build.gradle.kts +++ b/core-bukkit-api/build.gradle.kts @@ -36,8 +36,9 @@ dependencies { api("io.nats:jnats:2.25.2") api("de.kentoj.scrow:kencommandapi-core:0.4") - implementation("de.kentoj.scrow:kencommandapi-bukkit:0.4") api("de.kentoj.scrow:kencommandapi-bukkit:0.4") + + api(project(":core-lib")) } publishing { diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java index ea1d494..fa9a113 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java @@ -4,6 +4,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase; import de.kentoj.kencommandapi.BukkitKenCommandApi; import de.kentoj.scrow.bukkit.friends.FriendRequestService; import de.kentoj.scrow.bukkit.friends.FriendshipService; +import de.kentoj.scrowlib.servermanager.ServerManager; import io.nats.client.Connection; import lombok.AccessLevel; import lombok.Getter; diff --git a/core-bukkit-impl/build.gradle.kts b/core-bukkit-impl/build.gradle.kts index 9673d07..6b57f8d 100644 --- a/core-bukkit-impl/build.gradle.kts +++ b/core-bukkit-impl/build.gradle.kts @@ -22,6 +22,8 @@ dependencies { implementation(project(":core-bukkit-api")) implementation("org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT") + implementation("de.kentoj.scrow:kencommandapi-bukkit:0.4") + implementation(project(":core-lib")) } tasks { diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java index 09b28e5..62ed252 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java @@ -1,13 +1,10 @@ package de.kentoj.scrow.bukkit; -import de.kentoj.scrow.bukkit.crown.command.CrownCommand; +import de.kentoj.scrow.bukkit.crown.CrownCommand; import de.kentoj.scrow.bukkit.economy.CoinsCommand; import de.kentoj.scrow.bukkit.friends.command.FriendCommand; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; -import reactor.core.publisher.Mono; - -import java.util.UUID; public class CoreImplPlugin extends JavaPlugin { @@ -27,7 +24,7 @@ public class CoreImplPlugin extends JavaPlugin { } private void registerServer() { - ScrowAPI.getServerManager().updateState(System.getenv("SERVER_HANDLE"), "UP") + ScrowAPI.getServerManager().setState(System.getenv("SERVER_HANDLE"), "UP") .subscribe(__ -> Bukkit.getLogger().info("registered self")); } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java index e8bcd1b..fa3ce75 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java @@ -5,13 +5,13 @@ import com.mongodb.MongoClientSettings; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; import de.kentoj.kencommandapi.BukkitKenCommandApi; -import de.kentoj.scrow.bukkit.crown.CrownServerManager; import de.kentoj.scrow.bukkit.economy.InMemoryEconomyService; import de.kentoj.scrow.bukkit.economy.MongoEconomyService; import de.kentoj.scrow.bukkit.friends.friendship.InMemoryFriendshipService; import de.kentoj.scrow.bukkit.friends.friendship.MongoFriendshipService; import de.kentoj.scrow.bukkit.friends.request.InMemoryFriendRequestService; import de.kentoj.scrow.bukkit.friends.request.MongoFriendRequestService; +import de.kentoj.scrowlib.servermanager.CrownServerManager; import io.nats.client.Nats; import io.nats.client.Options; import lombok.AccessLevel; diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java similarity index 93% rename from core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownCommand.java rename to core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java index 82e8db6..d42ec71 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownCommand.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java @@ -1,4 +1,4 @@ -package de.kentoj.scrow.bukkit.crown.command; +package de.kentoj.scrow.bukkit.crown; import de.kentoj.kencommandapi.BukkitCommandContext; import de.kentoj.kencommandapi.api.structure.node.CommandNode; diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDeployServerLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java similarity index 90% rename from core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDeployServerLiteral.java rename to core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java index e47054a..571318b 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDeployServerLiteral.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java @@ -1,4 +1,4 @@ -package de.kentoj.scrow.bukkit.crown.command; +package de.kentoj.scrow.bukkit.crown; import de.kentoj.kencommandapi.BukkitCommandContext; import de.kentoj.kencommandapi.api.processing.CommandExecutor; @@ -28,8 +28,8 @@ public class CrownDeployServerLiteral implements CommandExecutor { - ctx.getSender().sendMessage("Deployed instance of " + template + " with handle " + handle); + .subscribe(server -> { + ctx.getSender().sendMessage("Deployed instance of " + template + " with handle " + server.getHandle()); }); } } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDestroyServerLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java similarity index 81% rename from core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDestroyServerLiteral.java rename to core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java index 053e5b5..0e96e75 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownDestroyServerLiteral.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java @@ -1,4 +1,4 @@ -package de.kentoj.scrow.bukkit.crown.command; +package de.kentoj.scrow.bukkit.crown; import de.kentoj.kencommandapi.BukkitCommandContext; import de.kentoj.kencommandapi.api.processing.CommandExecutor; @@ -6,6 +6,7 @@ import de.kentoj.kencommandapi.api.structure.argument.CommandArgument; import de.kentoj.kencommandapi.api.structure.argument.types.StringArgumentType; import de.kentoj.kencommandapi.api.structure.node.CommandNode; import de.kentoj.scrow.bukkit.ScrowAPI; +import de.kentoj.scrowlib.servermanager.ServerInstance; import lombok.Getter; import org.bukkit.command.CommandSender; @@ -24,7 +25,10 @@ public class CrownDestroyServerLiteral implements CommandExecutor()); this.handleArg.setSuggestionProvider(ctx -> { //noinspection CodeBlock2Expr - return ScrowAPI.getServerManager().getRunningServers().collect(Collectors.toSet()).toFuture(); + return ScrowAPI.getServerManager().getRunningServers() + .map(ServerInstance::getHandle) + .collect(Collectors.toSet()) + .toFuture(); }); this.node.addArgument(handleArg); } @@ -35,7 +39,7 @@ public class CrownDestroyServerLiteral implements CommandExecutor { - ctx.getSender().sendMessage("Destroyed server with handle " + handle); + ctx.getSender().sendMessage("Destroyed server with handle " + handle); }); } } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownListServersLiteral.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java similarity index 66% rename from core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownListServersLiteral.java rename to core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java index cb12096..487a47a 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/command/CrownListServersLiteral.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java @@ -1,4 +1,4 @@ -package de.kentoj.scrow.bukkit.crown.command; +package de.kentoj.scrow.bukkit.crown; import de.kentoj.kencommandapi.BukkitCommandContext; import de.kentoj.kencommandapi.api.processing.CommandExecutor; @@ -20,11 +20,15 @@ public class CrownListServersLiteral implements CommandExecutor { - var msg = new StringBuilder().append('\n'); - uids.forEach(uid -> msg.append(" > ").append(uid)); - msg.append('\n'); + .reduce(new StringBuilder("\n"), (acc, cur) -> acc.append("> ") + .append(cur.getHandle()) + .append(" on port ") + .append(cur.getPort()) + .append(": ") + .append(cur.getState()) + .append('\n') + ) + .subscribe(msg -> { ctx.getPlayerSender().sendMessage(msg.toString()); }); } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownServerManager.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownServerManager.java deleted file mode 100644 index 320db4e..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownServerManager.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.kentoj.scrow.bukkit.crown; - -import com.google.common.base.Preconditions; -import de.kentoj.scrow.bukkit.ScrowAPI; -import de.kentoj.scrow.bukkit.ServerManager; -import io.nats.client.Connection; -import lombok.RequiredArgsConstructor; -import org.bson.Document; -import org.jetbrains.annotations.NotNull; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.Arrays; - -public class CrownServerManager implements ServerManager { - - private final - - @Override - public Mono<@NotNull String> deployServer(String template) { - return Mono.fromFuture(nats.request("crown.deploy-server", new Document() - .append("template", template)) - .map(msg -> new String(msg.getData())); - } - - @Override - public Flux<@NotNull String> getRunningServers() { - return Mono.fromFuture(nats.request("crown.deploy-server", new byte[0])) - .flatMapMany(msg -> { - var ids = new String(msg.getData()).split("\u001F"); - return Flux.fromStream(Arrays.stream(ids)); - }); - } - - @Override - public Mono<@NotNull Void> destroyServer(String handle) { - return Mono.fromFuture(nats.request("crown.destroy-server",handle.getBytes())) - .then(); - } - - @Override - public Mono<@NotNull Void> updateState(String handle, String state) { - Preconditions.checkArgument(!state.contains(" "), "state may not contain spaces"); - var payload = (handle + " " + state).getBytes(); - return Mono.fromFuture(nats.request("crown.update-state", payload)) - .then(); - } -} diff --git a/core-lib/src/main/java/de/kentoj/scrowlib/DocumentRepository.java b/core-lib/src/main/java/de/kentoj/scrowlib/messaging/DocumentRepository.java similarity index 92% rename from core-lib/src/main/java/de/kentoj/scrowlib/DocumentRepository.java rename to core-lib/src/main/java/de/kentoj/scrowlib/messaging/DocumentRepository.java index 70c86f3..ff5cdfa 100644 --- a/core-lib/src/main/java/de/kentoj/scrowlib/DocumentRepository.java +++ b/core-lib/src/main/java/de/kentoj/scrowlib/messaging/DocumentRepository.java @@ -1,4 +1,4 @@ -package de.kentoj.scrowlib; +package de.kentoj.scrowlib.messaging; import io.nats.client.Message; import lombok.AccessLevel; diff --git a/core-lib/src/main/java/de/kentoj/scrowlib/NatsRepository.java b/core-lib/src/main/java/de/kentoj/scrowlib/messaging/NatsRepository.java similarity index 97% rename from core-lib/src/main/java/de/kentoj/scrowlib/NatsRepository.java rename to core-lib/src/main/java/de/kentoj/scrowlib/messaging/NatsRepository.java index 36974e8..7b33187 100644 --- a/core-lib/src/main/java/de/kentoj/scrowlib/NatsRepository.java +++ b/core-lib/src/main/java/de/kentoj/scrowlib/messaging/NatsRepository.java @@ -1,4 +1,4 @@ -package de.kentoj.scrowlib; +package de.kentoj.scrowlib.messaging; import io.nats.client.Connection; import io.nats.client.Dispatcher; diff --git a/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/CrownServerManager.java b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/CrownServerManager.java new file mode 100644 index 0000000..310808a --- /dev/null +++ b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/CrownServerManager.java @@ -0,0 +1,72 @@ +package de.kentoj.scrowlib.servermanager; + +import com.google.common.base.Preconditions; +import com.google.common.io.Files; +import de.kentoj.scrowlib.messaging.DocumentRepository; +import de.kentoj.scrowlib.messaging.NatsRepository; +import io.nats.client.Connection; +import org.bson.Document; +import org.jetbrains.annotations.NotNull; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public class CrownServerManager implements ServerManager { + + private final NatsRepository natsRepo; + + public CrownServerManager(Connection nats) { + this.natsRepo = new NatsRepository(nats); + } + + @Override + public Mono<@NotNull ServerInstance> deployServer(String template) { + var payload = DocumentRepository.toBytes(new Document("template", template)); + return natsRepo.request("crown.deploy-server", payload) + .map(DocumentRepository::fromMessage) + .map(doc -> new ServerInstance( + doc.getString("handle"), + doc.getInteger("port") + )); + } + + @Override + public Flux<@NotNull ServerInstance> getRunningServers() { + var payload = DocumentRepository.toBytes(new Document()); + return natsRepo.request("crown.list-servers", payload) + .map(DocumentRepository::fromMessage) + .map(doc -> + doc.getList("instances", Document.class) + ) + .flatMapIterable(l -> l) + .map(doc -> new ServerInstance( + doc.getString("handle"), + doc.getInteger("port"), + doc.getString("state") + )); + } + + @Override + public Mono<@NotNull Void> destroyServer(String handle) { + var payload = DocumentRepository.toBytes(new Document("handle", handle)); + return natsRepo.request("crown.destroy-server", payload) + .then(); + } + + @Override + public Mono<@NotNull String> getState(String handle) { + var payload = DocumentRepository.toBytes(new Document("handle", handle)); + return natsRepo.request("crown.get-state", payload) + .map(DocumentRepository::fromMessage) + .map(doc -> doc.getString("state")); + } + + @Override + public Mono<@NotNull Void> setState(String handle, String state) { + Preconditions.checkArgument(!state.contains(" "), "state may not contain spaces"); + var payload = DocumentRepository.toBytes(new Document() + .append("handle", handle) + .append("state", state)); + return natsRepo.request("crown.set-state", payload) + .then(); + } +} diff --git a/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerInstance.java b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerInstance.java new file mode 100644 index 0000000..2ee727f --- /dev/null +++ b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerInstance.java @@ -0,0 +1,16 @@ +package de.kentoj.scrowlib.servermanager; + +import lombok.AllArgsConstructor; +import lombok.Value; + +@Value +@AllArgsConstructor +public class ServerInstance { + String handle; + int port; + String state; + + public ServerInstance(String handle, int port) { + this(handle, port, "STARTING"); + } +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ServerManager.java b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerManager.java similarity index 61% rename from core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ServerManager.java rename to core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerManager.java index 08eedb1..cccba3a 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ServerManager.java +++ b/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerManager.java @@ -1,4 +1,4 @@ -package de.kentoj.scrow.bukkit; +package de.kentoj.scrowlib.servermanager; import org.jetbrains.annotations.NotNull; import reactor.core.publisher.Flux; @@ -9,17 +9,19 @@ public interface ServerManager { /** * @return Mono with handle of deployed server */ - Mono<@NotNull String> deployServer(String template); + Mono<@NotNull ServerInstance> deployServer(String template); /** * @return Flux with handles of running servers */ - Flux<@NotNull String> getRunningServers(); + Flux<@NotNull ServerInstance> getRunningServers(); /** * Attempts a clean shutdown, if that doesn't succeed, kills the server. */ Mono<@NotNull Void> destroyServer(String handle); - Mono<@NotNull Void> updateState(String handle, String state); + Mono<@NotNull String> getState(String handle); + + Mono<@NotNull Void> setState(String handle, String state); }