From 3707d2f03c6a159e8d396941fffcf973357b9e69 Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 22 Oct 2023 20:17:37 +0100 Subject: [PATCH] Add healthcheck functionality to API --- .../java/net/luckperms/api/LuckPerms.java | 12 +++ .../net/luckperms/api/platform/Health.java | 51 ++++++++++++ .../common/api/LuckPermsApiProvider.java | 6 ++ .../common/commands/misc/InfoCommand.java | 6 +- .../luckperms/common/locale/Message.java | 35 ++++++++- .../plugin/AbstractLuckPermsPlugin.java | 39 ++++++++++ .../common/plugin/LuckPermsPlugin.java | 8 ++ .../common/plugin/util/HealthCheckResult.java | 64 +++++++-------- .../luckperms/common/storage/Storage.java | 3 +- .../common/storage/StorageMetadata.java | 77 +++++++++++++++++++ .../implementation/StorageImplementation.java | 7 +- .../file/AbstractConfigurateStorage.java | 6 ++ .../implementation/mongodb/MongoStorage.java | 33 +++----- .../implementation/split/SplitStorage.java | 20 ++--- .../implementation/sql/SqlStorage.java | 18 +---- .../sql/connection/ConnectionFactory.java | 8 +- .../file/FlatfileConnectionFactory.java | 31 ++------ .../hikari/HikariConnectionFactory.java | 26 +++---- .../main/resources/luckperms_en.properties | 3 - .../common/storage/SqlStorageTest.java | 5 ++ .../standalone/app/LuckPermsApplication.java | 14 +--- .../app/utils/HeartbeatHttpServer.java | 13 ++-- .../standalone/LPStandalonePlugin.java | 12 --- .../standalone/StandaloneHealthReporter.java | 69 ----------------- .../luckperms/standalone/IntegrationTest.java | 6 +- .../standalone/MessagingIntegrationTest.java | 10 +-- .../standalone/StorageIntegrationTest.java | 6 +- 27 files changed, 321 insertions(+), 267 deletions(-) create mode 100644 api/src/main/java/net/luckperms/api/platform/Health.java rename standalone/app/src/main/java/me/lucko/luckperms/standalone/app/integration/HealthReporter.java => common/src/main/java/me/lucko/luckperms/common/plugin/util/HealthCheckResult.java (54%) create mode 100644 common/src/main/java/me/lucko/luckperms/common/storage/StorageMetadata.java delete mode 100644 standalone/src/main/java/me/lucko/luckperms/standalone/StandaloneHealthReporter.java diff --git a/api/src/main/java/net/luckperms/api/LuckPerms.java b/api/src/main/java/net/luckperms/api/LuckPerms.java index 584cdf29a..8e99fe610 100644 --- a/api/src/main/java/net/luckperms/api/LuckPerms.java +++ b/api/src/main/java/net/luckperms/api/LuckPerms.java @@ -40,6 +40,7 @@ import net.luckperms.api.model.user.User; import net.luckperms.api.model.user.UserManager; import net.luckperms.api.node.NodeBuilderRegistry; import net.luckperms.api.node.matcher.NodeMatcherFactory; +import net.luckperms.api.platform.Health; import net.luckperms.api.platform.Platform; import net.luckperms.api.platform.PlayerAdapter; import net.luckperms.api.platform.PluginMetadata; @@ -219,6 +220,17 @@ public interface LuckPerms { */ @NonNull CompletableFuture runUpdateTask(); + /** + * Executes a health check. + * + *

This task checks if the LuckPerms implementation is running and + * whether it has a connection to the database (if applicable).

+ * + * @return the health status + * @since 5.5 + */ + @NonNull Health runHealthCheck(); + /** * Registers a {@link MessengerProvider} for use by the platform. * diff --git a/api/src/main/java/net/luckperms/api/platform/Health.java b/api/src/main/java/net/luckperms/api/platform/Health.java new file mode 100644 index 000000000..7e7704f23 --- /dev/null +++ b/api/src/main/java/net/luckperms/api/platform/Health.java @@ -0,0 +1,51 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.luckperms.api.platform; + +import java.util.Map; + +/** + * Represents the "health" status (healthcheck) of a LuckPerms implementation. + * + * @since 5.5 + */ +public interface Health { + + /** + * Gets if LuckPerms is healthy. + * + * @return if LuckPerms is healthy + */ + boolean isHealthy(); + + /** + * Gets extra metadata/details about the healthcheck result. + * + * @return details about the healthcheck status + */ + Map getDetails(); + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java b/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java index 2356ca562..7da93b90e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java @@ -55,6 +55,7 @@ import net.luckperms.api.model.group.GroupManager; import net.luckperms.api.model.user.UserManager; import net.luckperms.api.node.NodeBuilderRegistry; import net.luckperms.api.node.matcher.NodeMatcherFactory; +import net.luckperms.api.platform.Health; import net.luckperms.api.platform.Platform; import net.luckperms.api.platform.PlayerAdapter; import net.luckperms.api.platform.PluginMetadata; @@ -172,6 +173,11 @@ public class LuckPermsApiProvider implements LuckPerms { return this.plugin.getSyncTaskBuffer().request(); } + @Override + public @NonNull Health runHealthCheck() { + return this.plugin.runHealthCheck(); + } + @Override public @NonNull AbstractEventBus getEventBus() { return this.plugin.getEventDispatcher().getEventBus(); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/InfoCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/InfoCommand.java index 78845ca3c..1f4b81fa9 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/InfoCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/InfoCommand.java @@ -33,9 +33,6 @@ import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.util.Predicates; -import net.kyori.adventure.text.Component; - -import java.util.Map; public class InfoCommand extends SingleCommand { public InfoCommand() { @@ -44,8 +41,7 @@ public class InfoCommand extends SingleCommand { @Override public void execute(LuckPermsPlugin plugin, Sender sender, ArgumentList args, String label) { - Map storageMeta = plugin.getStorage().getMeta(); - Message.INFO.send(sender, plugin, storageMeta); + Message.INFO.send(sender, plugin, plugin.getStorage().getMeta()); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java index 710d86bf7..ee530dd56 100644 --- a/common/src/main/java/me/lucko/luckperms/common/locale/Message.java +++ b/common/src/main/java/me/lucko/luckperms/common/locale/Message.java @@ -36,6 +36,7 @@ import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; import me.lucko.luckperms.common.sender.Sender; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.util.DurationFormatter; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; @@ -55,6 +56,7 @@ import net.luckperms.api.node.types.InheritanceNode; import net.luckperms.api.node.types.MetaNode; import net.luckperms.api.util.Tristate; +import java.text.DecimalFormat; import java.time.Duration; import java.time.Instant; import java.time.ZoneId; @@ -1535,7 +1537,7 @@ public interface Message { ) ); - Args2> INFO = (plugin, storageMeta) -> joinNewline( + Args2 INFO = (plugin, storageMeta) -> joinNewline( // "&2Running &bLuckPerms v{}&2 by &bLuck&2." // "&f- &3Platform: &f{}" // "&f- &3Server Brand: &f{}" @@ -1598,14 +1600,39 @@ public interface Message { .append(text(plugin.getStorage().getName(), WHITE)) ); - for (Map.Entry metaEntry : storageMeta.entrySet()) { + if (storageMeta.connected() != null) { builder.append(newline()); builder.append(prefixed(text() .color(DARK_AQUA) .append(text(" ")) - .append(metaEntry.getKey()) + .append(translatable("luckperms.command.info.storage.meta.connected-key")) .append(text(": ")) - .append(metaEntry.getValue()) + .append(formatBoolean(storageMeta.connected())) + )); + } + + if (storageMeta.ping() != null) { + builder.append(newline()); + builder.append(prefixed(text() + .color(DARK_AQUA) + .append(text(" ")) + .append(translatable("luckperms.command.info.storage.meta.ping-key")) + .append(text(": ")) + .append(text(storageMeta.ping() + "ms", GREEN)) + )); + } + + if (storageMeta.sizeBytes() != null) { + DecimalFormat format = new DecimalFormat("#.##"); + String size = format.format(storageMeta.sizeBytes() / 1048576D) + "MB"; + + builder.append(newline()); + builder.append(prefixed(text() + .color(DARK_AQUA) + .append(text(" ")) + .append(translatable("luckperms.command.info.storage.meta.file-size-key")) + .append(text(": ")) + .append(text(size, GREEN)) )); } })), diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java index fc662324e..f337a1dff 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java @@ -52,8 +52,10 @@ import me.lucko.luckperms.common.locale.TranslationRepository; import me.lucko.luckperms.common.messaging.InternalMessagingService; import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.plugin.logging.PluginLogger; +import me.lucko.luckperms.common.plugin.util.HealthCheckResult; import me.lucko.luckperms.common.storage.Storage; import me.lucko.luckperms.common.storage.StorageFactory; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.file.watcher.FileWatcher; import me.lucko.luckperms.common.storage.misc.DataConstraints; import me.lucko.luckperms.common.tasks.CacheHousekeepingTask; @@ -64,6 +66,7 @@ import me.lucko.luckperms.common.verbose.VerboseHandler; import me.lucko.luckperms.common.webeditor.socket.WebEditorSocket; import me.lucko.luckperms.common.webeditor.store.WebEditorStore; import net.luckperms.api.LuckPerms; +import net.luckperms.api.platform.Health; import okhttp3.OkHttpClient; import java.io.IOException; @@ -74,8 +77,11 @@ import java.time.Duration; import java.time.Instant; import java.time.LocalDate; import java.time.Month; +import java.util.Collections; import java.util.EnumSet; +import java.util.LinkedHashMap; import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -107,6 +113,8 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { private EventDispatcher eventDispatcher; private SimpleExtensionManager extensionManager; + private boolean running = false; + /** * Performs the initial actions to load the plugin */ @@ -248,6 +256,9 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { // perform any platform-specific final setup tasks performFinalSetup(); + // mark as running + this.running = true; + Duration timeTaken = Duration.between(getBootstrap().getStartupTime(), Instant.now()); getLogger().info("Successfully enabled. (took " + timeTaken.toMillis() + "ms)"); } @@ -272,6 +283,9 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { // unload extensions this.extensionManager.close(); + // mark as not running + this.running = false; + // remove any hooks into the platform removePlatformHooks(); @@ -383,6 +397,31 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { } } + @Override + public Health runHealthCheck() { + if (!this.running) { + return HealthCheckResult.unhealthy(Collections.emptyMap()); + } + + StorageMetadata meta = this.storage.getMeta(); + if (meta.connected() != null && !meta.connected()) { + return HealthCheckResult.unhealthy(Collections.singletonMap("reason", "storage disconnected")); + } + + Map map = new LinkedHashMap<>(); + if (meta.connected() != null) { + map.put("storageConnected", meta.connected().toString()); + } + if (meta.ping() != null) { + map.put("storagePing", meta.ping().toString()); + } + if (meta.sizeBytes() != null) { + map.put("storageSizeBytes", meta.sizeBytes().toString()); + } + + return HealthCheckResult.healthy(map); + } + @Override public Optional lookupUniqueId(String username) { // get a result from the DB cache diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java index 23d0f4e90..3bb51a8ca 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java @@ -57,6 +57,7 @@ import me.lucko.luckperms.common.tasks.SyncTask; import me.lucko.luckperms.common.treeview.PermissionRegistry; import me.lucko.luckperms.common.verbose.VerboseHandler; import me.lucko.luckperms.common.webeditor.store.WebEditorStore; +import net.luckperms.api.platform.Health; import net.luckperms.api.query.QueryOptions; import java.util.Collections; @@ -263,6 +264,13 @@ public interface LuckPermsPlugin { */ WebEditorStore getWebEditorStore(); + /** + * Runs a health check for the plugin. + * + * @return the result of the healthcheck + */ + Health runHealthCheck(); + /** * Gets a calculated context instance for the user using the rules of the platform. * diff --git a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/integration/HealthReporter.java b/common/src/main/java/me/lucko/luckperms/common/plugin/util/HealthCheckResult.java similarity index 54% rename from standalone/app/src/main/java/me/lucko/luckperms/standalone/app/integration/HealthReporter.java rename to common/src/main/java/me/lucko/luckperms/common/plugin/util/HealthCheckResult.java index b6ddeb7dd..5ea17a416 100644 --- a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/integration/HealthReporter.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/util/HealthCheckResult.java @@ -23,55 +23,45 @@ * SOFTWARE. */ -package me.lucko.luckperms.standalone.app.integration; +package me.lucko.luckperms.common.plugin.util; import com.google.gson.Gson; +import net.luckperms.api.platform.Health; import java.util.Map; -/** - * An interface able to provide information about the application/plugin health. - */ -public interface HealthReporter { +public class HealthCheckResult implements Health { + private static final Gson GSON = new Gson(); - /** - * Polls the current health status. - * - * @return the health status - */ - Health poll(); + public static HealthCheckResult healthy(Map details) { + return new HealthCheckResult(true, details); + } - final class Health { - private static final Gson GSON = new Gson(); + public static HealthCheckResult unhealthy(Map details) { + return new HealthCheckResult(false, details); + } - private final boolean up; - private final Map details; + private final boolean healthy; + private final Map details; - Health(boolean up, Map details) { - this.up = up; - this.details = details; - } + HealthCheckResult(boolean healthy, Map details) { + this.healthy = healthy; + this.details = details; + } - public boolean isUp() { - return this.up; - } + @Override + public boolean isHealthy() { + return this.healthy; + } - public Map details() { - return this.details; - } + @Override + public Map getDetails() { + return this.details; + } - @Override - public String toString() { - return GSON.toJson(this); - } - - public static Health up(Map details) { - return new Health(true, details); - } - - public static Health down(Map details) { - return new Health(false, details); - } + @Override + public String toString() { + return GSON.toJson(this); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/Storage.java b/common/src/main/java/me/lucko/luckperms/common/storage/Storage.java index 685af72ac..064c86000 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/Storage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/Storage.java @@ -37,7 +37,6 @@ import me.lucko.luckperms.common.storage.implementation.StorageImplementation; import me.lucko.luckperms.common.storage.implementation.split.SplitStorage; import me.lucko.luckperms.common.storage.misc.NodeEntry; import me.lucko.luckperms.common.util.Throwing; -import net.kyori.adventure.text.Component; import net.luckperms.api.actionlog.Action; import net.luckperms.api.event.cause.CreationCause; import net.luckperms.api.event.cause.DeletionCause; @@ -126,7 +125,7 @@ public class Storage { } } - public Map getMeta() { + public StorageMetadata getMeta() { return this.implementation.getMeta(); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/StorageMetadata.java b/common/src/main/java/me/lucko/luckperms/common/storage/StorageMetadata.java new file mode 100644 index 000000000..2d1bdbd0f --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/storage/StorageMetadata.java @@ -0,0 +1,77 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.storage; + +public class StorageMetadata { + + // remote + private Boolean connected; + private Integer ping; + + // local + private Long sizeBytes; + + public Boolean connected() { + return this.connected; + } + + public Integer ping() { + return this.ping; + } + + public Long sizeBytes() { + return this.sizeBytes; + } + + public StorageMetadata connected(boolean connected) { + this.connected = connected; + return this; + } + + public StorageMetadata ping(int ping) { + this.ping = ping; + return this; + } + + public StorageMetadata sizeBytes(long sizeBytes) { + this.sizeBytes = sizeBytes; + return this; + } + + public StorageMetadata combine(StorageMetadata other) { + if (this.connected == null || (other.connected != null && !other.connected)) { + this.connected = other.connected; + } + if (this.ping == null || (other.ping != null && other.ping > this.ping)) { + this.ping = other.ping; + } + if (this.sizeBytes == null || (other.sizeBytes != null && other.sizeBytes > this.sizeBytes)) { + this.sizeBytes = other.sizeBytes; + } + return this; + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/StorageImplementation.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/StorageImplementation.java index 2c65a605d..1b53936aa 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/StorageImplementation.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/StorageImplementation.java @@ -32,14 +32,13 @@ import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.misc.NodeEntry; -import net.kyori.adventure.text.Component; import net.luckperms.api.actionlog.Action; import net.luckperms.api.model.PlayerSaveResult; import net.luckperms.api.node.Node; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -55,9 +54,7 @@ public interface StorageImplementation { void shutdown(); - default Map getMeta() { - return Collections.emptyMap(); - } + StorageMetadata getMeta(); void logAction(Action entry) throws Exception; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java index 9bf3ddf8e..15bf0f2e1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/file/AbstractConfigurateStorage.java @@ -41,6 +41,7 @@ import me.lucko.luckperms.common.node.types.Meta; import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.node.types.Suffix; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.StorageImplementation; import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader; import me.lucko.luckperms.common.storage.implementation.file.loader.JsonLoader; @@ -116,6 +117,11 @@ public abstract class AbstractConfigurateStorage implements StorageImplementatio return this.implementationName; } + @Override + public StorageMetadata getMeta() { + return new StorageMetadata(); + } + /** * Reads a configuration node from the given location * diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java index 3055f8b84..e09fc65c1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/mongodb/MongoStorage.java @@ -40,7 +40,6 @@ import me.lucko.luckperms.common.actionlog.Log; import me.lucko.luckperms.common.actionlog.LoggedAction; import me.lucko.luckperms.common.bulkupdate.BulkUpdate; import me.lucko.luckperms.common.context.MutableContextSetImpl; -import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.HolderType; import me.lucko.luckperms.common.model.Track; @@ -49,13 +48,12 @@ import me.lucko.luckperms.common.model.manager.group.GroupManager; import me.lucko.luckperms.common.node.factory.NodeBuilders; import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.StorageImplementation; import me.lucko.luckperms.common.storage.misc.NodeEntry; import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl; import me.lucko.luckperms.common.storage.misc.StorageCredentials; import me.lucko.luckperms.common.util.Iterators; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import net.luckperms.api.actionlog.Action; import net.luckperms.api.context.Context; import net.luckperms.api.context.ContextSet; @@ -72,7 +70,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -147,37 +144,25 @@ public class MongoStorage implements StorageImplementation { } @Override - public Map getMeta() { - Map meta = new LinkedHashMap<>(); - boolean success = true; + public StorageMetadata getMeta() { + StorageMetadata metadata = new StorageMetadata(); + boolean success = true; long start = System.currentTimeMillis(); + try { this.database.runCommand(new Document("ping", 1)); } catch (Exception e) { success = false; } - long duration = System.currentTimeMillis() - start; if (success) { - meta.put( - Component.translatable("luckperms.command.info.storage.meta.ping-key"), - Component.text(duration + "ms", NamedTextColor.GREEN) - ); - } - meta.put( - Component.translatable("luckperms.command.info.storage.meta.connected-key"), - Message.formatBoolean(success) - ); - - if (!this.prefix.isEmpty()) { - meta.put( - Component.translatable("luckperms.command.info.storage.meta.collection-prefix-key"), - Component.text(this.prefix, NamedTextColor.WHITE) - ); + int duration = (int) (System.currentTimeMillis() - start); + metadata.ping(duration); } - return meta; + metadata.connected(success); + return metadata; } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/split/SplitStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/split/SplitStorage.java index baa52a6c1..970e97068 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/split/SplitStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/split/SplitStorage.java @@ -28,28 +28,24 @@ package me.lucko.luckperms.common.storage.implementation.split; import com.google.common.collect.ImmutableMap; import me.lucko.luckperms.common.actionlog.Log; import me.lucko.luckperms.common.bulkupdate.BulkUpdate; -import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.StorageType; import me.lucko.luckperms.common.storage.implementation.StorageImplementation; import me.lucko.luckperms.common.storage.misc.NodeEntry; -import net.kyori.adventure.text.Component; import net.luckperms.api.actionlog.Action; import net.luckperms.api.model.PlayerSaveResult; import net.luckperms.api.node.Node; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; public class SplitStorage implements StorageImplementation { private final LuckPermsPlugin plugin; @@ -108,18 +104,12 @@ public class SplitStorage implements StorageImplementation { } @Override - public Map getMeta() { - Map meta = new LinkedHashMap<>(); - meta.put( - Component.translatable("luckperms.command.info.storage.meta.split-types-key"), - Message.formatStringList(this.types.entrySet().stream() - .map(e -> e.getKey().toString().toLowerCase(Locale.ROOT) + "->" + e.getValue().getName().toLowerCase(Locale.ROOT)) - .collect(Collectors.toList())) - ); + public StorageMetadata getMeta() { + StorageMetadata metadata = new StorageMetadata(); for (StorageImplementation backing : this.implementations.values()) { - meta.putAll(backing.getMeta()); + metadata.combine(backing.getMeta()); } - return meta; + return metadata; } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java index ee68fb342..58e8a606e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/SqlStorage.java @@ -33,7 +33,6 @@ import me.lucko.luckperms.common.actionlog.LoggedAction; import me.lucko.luckperms.common.bulkupdate.BulkUpdate; import me.lucko.luckperms.common.bulkupdate.BulkUpdateStatistics; import me.lucko.luckperms.common.bulkupdate.PreparedStatementBuilder; -import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Track; @@ -42,6 +41,7 @@ import me.lucko.luckperms.common.model.manager.group.GroupManager; import me.lucko.luckperms.common.node.factory.NodeBuilders; import me.lucko.luckperms.common.node.matcher.ConstraintNodeMatcher; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.StorageImplementation; import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory; import me.lucko.luckperms.common.storage.misc.NodeEntry; @@ -49,8 +49,6 @@ import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl; import me.lucko.luckperms.common.util.Difference; import me.lucko.luckperms.common.util.Uuids; import me.lucko.luckperms.common.util.gson.GsonProvider; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import net.luckperms.api.actionlog.Action; import net.luckperms.api.context.DefaultContextKeys; import net.luckperms.api.context.MutableContextSet; @@ -229,18 +227,8 @@ public class SqlStorage implements StorageImplementation { } @Override - public Map getMeta() { - Map meta = this.connectionFactory.getMeta(); - - String tablePrefix = this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX); - if (!tablePrefix.equals("luckperms_")) { - meta.put( - Component.translatable("luckperms.command.info.storage.meta.table-prefix-key"), - Component.text(tablePrefix, NamedTextColor.WHITE) - ); - } - - return meta; + public StorageMetadata getMeta() { + return this.connectionFactory.getMeta(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/ConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/ConnectionFactory.java index 002a9aa08..494313bb4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/ConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/ConnectionFactory.java @@ -26,12 +26,10 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import net.kyori.adventure.text.Component; +import me.lucko.luckperms.common.storage.StorageMetadata; import java.sql.Connection; import java.sql.SQLException; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.function.Function; public interface ConnectionFactory { @@ -42,9 +40,7 @@ public interface ConnectionFactory { void shutdown() throws Exception; - default Map getMeta() { - return new LinkedHashMap<>(); - } + StorageMetadata getMeta(); Function getStatementProcessor(); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/file/FlatfileConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/file/FlatfileConnectionFactory.java index 0886d1f2a..abe027947 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/file/FlatfileConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/file/FlatfileConnectionFactory.java @@ -25,25 +25,19 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.file; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.sql.Connection; import java.sql.SQLException; -import java.text.DecimalFormat; -import java.util.LinkedHashMap; -import java.util.Map; /** * Abstract {@link ConnectionFactory} using a file based database driver. */ abstract class FlatfileConnectionFactory implements ConnectionFactory { - /** Format used for formatting database file size. */ - protected static final DecimalFormat FILE_SIZE_FORMAT = new DecimalFormat("#.##"); /** The current open connection, if any */ private NonClosableConnection connection; @@ -101,28 +95,19 @@ abstract class FlatfileConnectionFactory implements ConnectionFactory { } @Override - public Map getMeta() { - String fileSize; + public StorageMetadata getMeta() { + StorageMetadata metadata = new StorageMetadata(); + Path databaseFile = getWriteFile(); if (Files.exists(databaseFile)) { - long length; try { - length = Files.size(databaseFile); + long length = Files.size(databaseFile); + metadata.sizeBytes(length); } catch (IOException e) { - length = 0; + // ignore } - - double size = length / 1048576D; - fileSize = FILE_SIZE_FORMAT.format(size) + "MB"; - } else { - fileSize = "0MB"; } - Map meta = new LinkedHashMap<>(); - meta.put( - Component.translatable("luckperms.command.info.storage.meta.file-size-key"), - Component.text(fileSize, NamedTextColor.GREEN) - ); - return meta; + return metadata; } } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java index f147efac8..8c9bbd8f6 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/implementation/sql/connection/hikari/HikariConnectionFactory.java @@ -28,19 +28,16 @@ package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari; import com.google.common.collect.ImmutableList; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; -import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.logging.PluginLogger; +import me.lucko.luckperms.common.storage.StorageMetadata; import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory; import me.lucko.luckperms.common.storage.misc.StorageCredentials; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -178,11 +175,12 @@ public abstract class HikariConnectionFactory implements ConnectionFactory { } @Override - public Map getMeta() { - Map meta = new LinkedHashMap<>(); - boolean success = true; + public StorageMetadata getMeta() { + StorageMetadata metadata = new StorageMetadata(); + boolean success = true; long start = System.currentTimeMillis(); + try (Connection c = getConnection()) { try (Statement s = c.createStatement()) { s.execute("/* ping */ SELECT 1"); @@ -192,18 +190,12 @@ public abstract class HikariConnectionFactory implements ConnectionFactory { } if (success) { - long duration = System.currentTimeMillis() - start; - meta.put( - Component.translatable("luckperms.command.info.storage.meta.ping-key"), - Component.text(duration + "ms", NamedTextColor.GREEN) - ); + int duration = (int) (System.currentTimeMillis() - start); + metadata.ping(duration); } - meta.put( - Component.translatable("luckperms.command.info.storage.meta.connected-key"), - Message.formatBoolean(success) - ); - return meta; + metadata.connected(success); + return metadata; } // dumb plugins seem to keep doing stupid stuff with shading of SLF4J and Log4J. diff --git a/common/src/main/resources/luckperms_en.properties b/common/src/main/resources/luckperms_en.properties index 8939215fe..9239b6045 100644 --- a/common/src/main/resources/luckperms_en.properties +++ b/common/src/main/resources/luckperms_en.properties @@ -150,12 +150,9 @@ luckperms.command.info.server-brand-key=Server Brand luckperms.command.info.server-version-key=Server Version luckperms.command.info.storage-key=Storage luckperms.command.info.storage-type-key=Type -luckperms.command.info.storage.meta.split-types-key=Types luckperms.command.info.storage.meta.ping-key=Ping luckperms.command.info.storage.meta.connected-key=Connected luckperms.command.info.storage.meta.file-size-key=File Size -luckperms.command.info.storage.meta.table-prefix-key=Table Prefix -luckperms.command.info.storage.meta.collection-prefix-key=Collection Prefix luckperms.command.info.extensions-key=Extensions luckperms.command.info.messaging-key=Messaging luckperms.command.info.instance-key=Instance diff --git a/common/src/test/java/me/lucko/luckperms/common/storage/SqlStorageTest.java b/common/src/test/java/me/lucko/luckperms/common/storage/SqlStorageTest.java index bcd45e79e..e6fb76a0a 100644 --- a/common/src/test/java/me/lucko/luckperms/common/storage/SqlStorageTest.java +++ b/common/src/test/java/me/lucko/luckperms/common/storage/SqlStorageTest.java @@ -277,6 +277,11 @@ public class SqlStorageTest { return "H2"; } + @Override + public StorageMetadata getMeta() { + return new StorageMetadata(); + } + @Override public void init(LuckPermsPlugin plugin) { diff --git a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/LuckPermsApplication.java b/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/LuckPermsApplication.java index 11043b7a0..e1ea21850 100644 --- a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/LuckPermsApplication.java +++ b/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/LuckPermsApplication.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.standalone.app; import me.lucko.luckperms.standalone.app.integration.CommandExecutor; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; import me.lucko.luckperms.standalone.app.integration.ShutdownCallback; import me.lucko.luckperms.standalone.app.utils.DockerCommandSocket; import me.lucko.luckperms.standalone.app.utils.HeartbeatHttpServer; @@ -54,8 +53,6 @@ public class LuckPermsApplication implements AutoCloseable { private LuckPerms luckPermsApi; /** A command executor interface to run LuckPerms commands */ private CommandExecutor commandExecutor; - /** An interface that can poll the health of the application */ - private HealthReporter healthReporter; /** If the application is running */ private final AtomicBoolean running = new AtomicBoolean(true); @@ -78,7 +75,7 @@ public class LuckPermsApplication implements AutoCloseable { List arguments = Arrays.asList(args); if (arguments.contains("--docker")) { this.dockerCommandSocket = DockerCommandSocket.createAndStart("/opt/luckperms/luckperms.sock", terminal); - this.heartbeatHttpServer = HeartbeatHttpServer.createAndStart(3001, this.healthReporter); + this.heartbeatHttpServer = HeartbeatHttpServer.createAndStart(3001, () -> this.luckPermsApi.runHealthCheck()); } terminal.start(); // blocking @@ -123,11 +120,6 @@ public class LuckPermsApplication implements AutoCloseable { this.commandExecutor = commandExecutor; } - // called before start() - public void setHealthReporter(HealthReporter healthReporter) { - this.healthReporter = healthReporter; - } - public LuckPerms getApi() { return this.luckPermsApi; } @@ -136,10 +128,6 @@ public class LuckPermsApplication implements AutoCloseable { return this.commandExecutor; } - public HealthReporter getHealthReporter() { - return this.healthReporter; - } - public String getVersion() { return "@version@"; } diff --git a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/utils/HeartbeatHttpServer.java b/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/utils/HeartbeatHttpServer.java index 912b4be4d..262e7d78d 100644 --- a/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/utils/HeartbeatHttpServer.java +++ b/standalone/app/src/main/java/me/lucko/luckperms/standalone/app/utils/HeartbeatHttpServer.java @@ -29,7 +29,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; +import net.luckperms.api.platform.Health; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -39,6 +39,7 @@ import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.function.Supplier; /** * Provides a tiny http server indicating the current status of the app @@ -52,7 +53,7 @@ public class HeartbeatHttpServer implements HttpHandler, AutoCloseable { .build() ); - public static HeartbeatHttpServer createAndStart(int port, HealthReporter healthReporter) { + public static HeartbeatHttpServer createAndStart(int port, Supplier healthReporter) { HeartbeatHttpServer socket = null; try { @@ -65,10 +66,10 @@ public class HeartbeatHttpServer implements HttpHandler, AutoCloseable { return socket; } - private final HealthReporter healthReporter; + private final Supplier healthReporter; private final HttpServer server; - public HeartbeatHttpServer(HealthReporter healthReporter, int port) throws IOException { + public HeartbeatHttpServer(Supplier healthReporter, int port) throws IOException { this.healthReporter = healthReporter; this.server = HttpServer.create(new InetSocketAddress(port), 50); this.server.createContext("/health", this); @@ -78,10 +79,10 @@ public class HeartbeatHttpServer implements HttpHandler, AutoCloseable { @Override public void handle(HttpExchange exchange) throws IOException { - HealthReporter.Health health = this.healthReporter.poll(); + Health health = this.healthReporter.get(); byte[] response = health.toString().getBytes(StandardCharsets.UTF_8); - exchange.sendResponseHeaders(health.isUp() ? 200 : 503, response.length); + exchange.sendResponseHeaders(health.isHealthy() ? 200 : 503, response.length); try (OutputStream responseBody = exchange.getResponseBody()) { responseBody.write(response); } diff --git a/standalone/src/main/java/me/lucko/luckperms/standalone/LPStandalonePlugin.java b/standalone/src/main/java/me/lucko/luckperms/standalone/LPStandalonePlugin.java index f084b168b..609b785e3 100644 --- a/standalone/src/main/java/me/lucko/luckperms/standalone/LPStandalonePlugin.java +++ b/standalone/src/main/java/me/lucko/luckperms/standalone/LPStandalonePlugin.java @@ -56,8 +56,6 @@ import java.util.stream.Stream; public class LPStandalonePlugin extends AbstractLuckPermsPlugin { private final LPStandaloneBootstrap bootstrap; - private boolean running = false; - private StandaloneSenderFactory senderFactory; private StandaloneDummyConnectionListener connectionListener; private StandaloneCommandManager commandManager; @@ -79,10 +77,6 @@ public class LPStandalonePlugin extends AbstractLuckPermsPlugin { return this.bootstrap.getLoader(); } - public boolean isRunning() { - return this.running; - } - @Override protected void setupSenderFactory() { this.senderFactory = new StandaloneSenderFactory(this); @@ -149,17 +143,11 @@ public class LPStandalonePlugin extends AbstractLuckPermsPlugin { @Override protected void registerApiOnPlatform(LuckPerms api) { this.bootstrap.getLoader().setApi(api); - this.bootstrap.getLoader().setHealthReporter(new StandaloneHealthReporter(this)); } @Override protected void performFinalSetup() { - this.running = true; - } - @Override - protected void removePlatformHooks() { - this.running = false; } @Override diff --git a/standalone/src/main/java/me/lucko/luckperms/standalone/StandaloneHealthReporter.java b/standalone/src/main/java/me/lucko/luckperms/standalone/StandaloneHealthReporter.java deleted file mode 100644 index 6bf89818b..000000000 --- a/standalone/src/main/java/me/lucko/luckperms/standalone/StandaloneHealthReporter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.standalone; - -import me.lucko.luckperms.common.locale.TranslationManager; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; - -import java.util.Collections; -import java.util.Locale; -import java.util.Map; -import java.util.stream.Collectors; - -public class StandaloneHealthReporter implements HealthReporter { - private final LPStandalonePlugin plugin; - - public StandaloneHealthReporter(LPStandalonePlugin plugin) { - this.plugin = plugin; - } - - @Override - public Health poll() { - if (!this.plugin.isRunning()) { - return Health.down(Collections.emptyMap()); - } - - Map meta = this.plugin.getStorage().getMeta().entrySet().stream() - .collect(Collectors.toMap( - e -> render(e.getKey()).toLowerCase(Locale.ROOT), - e -> render(e.getValue()) - )); - - if ("false".equals(meta.get("connected"))) { - return Health.down(Collections.singletonMap("reason", "storage disconnected")); - } - - return Health.up(meta); - } - - private static String render(Component component) { - return PlainTextComponentSerializer.plainText().serialize( - TranslationManager.render(component) - ); - } -} diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java index 278dacb58..4184c447d 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/IntegrationTest.java @@ -29,10 +29,10 @@ import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.node.types.Permission; import me.lucko.luckperms.standalone.app.integration.CommandExecutor; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; import me.lucko.luckperms.standalone.utils.TestPluginProvider; import net.luckperms.api.model.data.DataType; import net.luckperms.api.node.NodeEqualityPredicate; +import net.luckperms.api.platform.Health; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -52,9 +52,9 @@ public class IntegrationTest { @Test public void testLoadEnableDisable(@TempDir Path tempDir) { TestPluginProvider.use(tempDir, (app, bootstrap, plugin) -> { - HealthReporter.Health health = app.getHealthReporter().poll(); + Health health = plugin.runHealthCheck(); assertNotNull(health); - assertTrue(health.isUp()); + assertTrue(health.isHealthy()); }); } diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java index cb3cb12fa..2deffa4a6 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/MessagingIntegrationTest.java @@ -28,12 +28,12 @@ package me.lucko.luckperms.standalone; import com.google.common.collect.ImmutableMap; import me.lucko.luckperms.common.actionlog.LoggedAction; import me.lucko.luckperms.common.messaging.InternalMessagingService; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; import me.lucko.luckperms.standalone.utils.TestPluginProvider; import net.luckperms.api.actionlog.Action; import net.luckperms.api.event.EventBus; import net.luckperms.api.event.log.LogReceiveEvent; import net.luckperms.api.event.sync.PreNetworkSyncEvent; +import net.luckperms.api.platform.Health; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -61,13 +61,13 @@ public class MessagingIntegrationTest { TestPluginProvider.Plugin pluginB = TestPluginProvider.create(tempDirB, config)) { // check the plugins are healthy - HealthReporter.Health healthA = pluginA.app().getHealthReporter().poll(); + Health healthA = pluginA.plugin().runHealthCheck(); assertNotNull(healthA); - assertTrue(healthA.isUp()); + assertTrue(healthA.isHealthy()); - HealthReporter.Health healthB = pluginB.app().getHealthReporter().poll(); + Health healthB = pluginB.plugin().runHealthCheck(); assertNotNull(healthB); - assertTrue(healthB.isUp()); + assertTrue(healthB.isHealthy()); InternalMessagingService messagingServiceA = pluginA.plugin().getMessagingService().orElse(null); InternalMessagingService messagingServiceB = pluginB.plugin().getMessagingService().orElse(null); diff --git a/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java b/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java index d7f1af829..e1527ab60 100644 --- a/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java +++ b/standalone/src/test/java/me/lucko/luckperms/standalone/StorageIntegrationTest.java @@ -40,7 +40,6 @@ import me.lucko.luckperms.common.node.types.Permission; import me.lucko.luckperms.common.node.types.Prefix; import me.lucko.luckperms.common.storage.misc.NodeEntry; import me.lucko.luckperms.standalone.app.LuckPermsApplication; -import me.lucko.luckperms.standalone.app.integration.HealthReporter; import me.lucko.luckperms.standalone.utils.TestPluginBootstrap; import me.lucko.luckperms.standalone.utils.TestPluginBootstrap.TestPlugin; import me.lucko.luckperms.standalone.utils.TestPluginProvider; @@ -50,6 +49,7 @@ import net.luckperms.api.model.data.DataType; import net.luckperms.api.node.Node; import net.luckperms.api.node.NodeType; import net.luckperms.api.node.types.PrefixNode; +import net.luckperms.api.platform.Health; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -118,9 +118,9 @@ public class StorageIntegrationTest { private static void testStorage(LuckPermsApplication app, TestPluginBootstrap bootstrap, TestPlugin plugin) { // check the plugin is healthy - HealthReporter.Health health = app.getHealthReporter().poll(); + Health health = plugin.runHealthCheck(); assertNotNull(health); - assertTrue(health.isUp()); + assertTrue(health.isHealthy()); // try to create / save a group Group group = plugin.getStorage().createAndLoadGroup("test", CreationCause.INTERNAL).join();