Improve initialization logic

feat/data-edit-commands
William 3 years ago
parent ff1c8cddb5
commit 723c79b3a9

@ -41,6 +41,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -75,147 +76,116 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync {
@Override @Override
public void onEnable() { public void onEnable() {
// Process initialization stages // Initialize HuskSync
CompletableFuture.supplyAsync(() -> { final AtomicBoolean initialized = new AtomicBoolean(true);
try {
// Set the logging adapter and resource reader // Set the logging adapter and resource reader
this.logger = new BukkitLogger(this.getLogger()); this.logger = new BukkitLogger(this.getLogger());
this.resourceReader = new BukkitResourceReader(this); this.resourceReader = new BukkitResourceReader(this);
// Load settings and locales // Load settings and locales
getLoggingAdapter().log(Level.INFO, "Loading plugin configuration settings & locales..."); getLoggingAdapter().log(Level.INFO, "Loading plugin configuration settings & locales...");
return reload().thenApply(loadedSettings -> { initialized.set(reload().join());
if (loadedSettings) { if (initialized.get()) {
logger.showDebugLogs(settings.getBooleanValue(Settings.ConfigOption.DEBUG_LOGGING)); logger.showDebugLogs(settings.getBooleanValue(Settings.ConfigOption.DEBUG_LOGGING));
getLoggingAdapter().log(Level.INFO, "Successfully loaded plugin configuration settings & locales"); getLoggingAdapter().log(Level.INFO, "Successfully loaded plugin configuration settings & locales");
} else { } else {
getLoggingAdapter().log(Level.SEVERE, "Failed to load plugin configuration settings and/or locales"); throw new HuskSyncInitializationException("Failed to load plugin configuration settings and/or locales");
} }
return loadedSettings;
}).join();
}).thenApply(succeeded -> {
// Prepare data adapter // Prepare data adapter
if (succeeded) { if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_COMPRESS_DATA)) {
if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_COMPRESS_DATA)) { dataAdapter = new CompressedDataAdapter();
dataAdapter = new CompressedDataAdapter(); } else {
} else { dataAdapter = new JsonDataAdapter();
dataAdapter = new JsonDataAdapter();
}
} }
return succeeded;
}).thenApply(succeeded -> {
// Prepare event cannon // Prepare event cannon
if (succeeded) { eventCannon = new BukkitEventCannon();
eventCannon = new BukkitEventCannon();
}
return succeeded;
}).thenApply(succeeded -> {
// Prepare data editor // Prepare data editor
if (succeeded) { dataEditor = new DataEditor(locales);
dataEditor = new DataEditor(locales);
}
return succeeded;
}).thenApply(succeeded -> {
// Prepare migrators // Prepare migrators
if (succeeded) { availableMigrators = new ArrayList<>();
availableMigrators = new ArrayList<>(); availableMigrators.add(new LegacyMigrator(this));
availableMigrators.add(new LegacyMigrator(this)); final Plugin mySqlPlayerDataBridge = Bukkit.getPluginManager().getPlugin("MySqlPlayerDataBridge");
final Plugin mySqlPlayerDataBridge = Bukkit.getPluginManager().getPlugin("MySqlPlayerDataBridge"); if (mySqlPlayerDataBridge != null) {
if (mySqlPlayerDataBridge != null) { availableMigrators.add(new MpdbMigrator(this, mySqlPlayerDataBridge));
availableMigrators.add(new MpdbMigrator(this, mySqlPlayerDataBridge));
}
} }
return succeeded;
}).thenApply(succeeded -> { // Prepare database connection
// Establish connection to the database this.database = new MySqlDatabase(settings, resourceReader, logger, dataAdapter, eventCannon);
if (succeeded) { getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the database...");
this.database = new MySqlDatabase(settings, resourceReader, logger, dataAdapter, eventCannon); initialized.set(this.database.initialize());
getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the database..."); if (initialized.get()) {
final CompletableFuture<Boolean> databaseConnectFuture = new CompletableFuture<>(); getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the database");
Bukkit.getScheduler().runTask(this, () -> { } else {
final boolean initialized = this.database.initialize(); throw new HuskSyncInitializationException("Failed to establish a connection to the database. " +
if (!initialized) { "Please check the supplied database credentials in the config file");
getLoggingAdapter().log(Level.SEVERE, "Failed to establish a connection to the database. " + "Please check the supplied database credentials in the config file");
databaseConnectFuture.completeAsync(() -> false);
return;
}
getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the database");
databaseConnectFuture.completeAsync(() -> true);
});
return databaseConnectFuture.join();
} }
return false;
}).thenApply(succeeded -> { // Prepare redis connection
// Establish connection to the Redis server this.redisManager = new RedisManager(this);
if (succeeded) { getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the Redis server...");
this.redisManager = new RedisManager(this); initialized.set(this.redisManager.initialize().join());
getLoggingAdapter().log(Level.INFO, "Attempting to establish connection to the Redis server..."); if (initialized.get()) {
return this.redisManager.initialize().thenApply(initialized -> { getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the Redis server");
if (!initialized) { } else {
getLoggingAdapter().log(Level.SEVERE, "Failed to establish a connection to the Redis server. " + "Please check the supplied Redis credentials in the config file"); throw new HuskSyncInitializationException("Failed to establish a connection to the Redis server. " +
return false; "Please check the supplied Redis credentials in the config file");
}
getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the Redis server");
return true;
}).join();
} }
return false;
}).thenApply(succeeded -> {
// Register events // Register events
if (succeeded) { getLoggingAdapter().log(Level.INFO, "Registering events...");
getLoggingAdapter().log(Level.INFO, "Registering events..."); this.eventListener = new BukkitEventListener(this);
this.eventListener = new BukkitEventListener(this); getLoggingAdapter().log(Level.INFO, "Successfully registered events listener");
getLoggingAdapter().log(Level.INFO, "Successfully registered events listener");
}
return succeeded;
}).thenApply(succeeded -> {
// Register permissions // Register permissions
if (succeeded) { getLoggingAdapter().log(Level.INFO, "Registering permissions & commands...");
getLoggingAdapter().log(Level.INFO, "Registering permissions & commands..."); Arrays.stream(Permission.values()).forEach(permission -> getServer().getPluginManager()
Arrays.stream(Permission.values()).forEach(permission -> getServer().getPluginManager().addPermission(new org.bukkit.permissions.Permission(permission.node, switch (permission.defaultAccess) { .addPermission(new org.bukkit.permissions.Permission(permission.node, switch (permission.defaultAccess) {
case EVERYONE -> PermissionDefault.TRUE; case EVERYONE -> PermissionDefault.TRUE;
case NOBODY -> PermissionDefault.FALSE; case NOBODY -> PermissionDefault.FALSE;
case OPERATORS -> PermissionDefault.OP; case OPERATORS -> PermissionDefault.OP;
}))); })));
// Register commands // Register commands
for (final BukkitCommandType bukkitCommandType : BukkitCommandType.values()) { for (final BukkitCommandType bukkitCommandType : BukkitCommandType.values()) {
final PluginCommand pluginCommand = getCommand(bukkitCommandType.commandBase.command); final PluginCommand pluginCommand = getCommand(bukkitCommandType.commandBase.command);
if (pluginCommand != null) { if (pluginCommand != null) {
new BukkitCommand(bukkitCommandType.commandBase, this).register(pluginCommand); new BukkitCommand(bukkitCommandType.commandBase, this).register(pluginCommand);
}
} }
getLoggingAdapter().log(Level.INFO, "Successfully registered permissions & commands");
} }
return succeeded; getLoggingAdapter().log(Level.INFO, "Successfully registered permissions & commands");
}).thenApply(succeeded -> {
if (succeeded && Bukkit.getPluginManager().getPlugin("Plan") != null) { // Hook into plan
if (Bukkit.getPluginManager().getPlugin("Plan") != null) {
getLoggingAdapter().log(Level.INFO, "Enabling Plan integration..."); getLoggingAdapter().log(Level.INFO, "Enabling Plan integration...");
new PlanHook(database, logger).hookIntoPlan(); new PlanHook(database, logger).hookIntoPlan();
getLoggingAdapter().log(Level.INFO, "Plan integration enabled!"); getLoggingAdapter().log(Level.INFO, "Plan integration enabled!");
} }
return succeeded;
}).thenApply(succeeded -> {
// Check for updates // Check for updates
if (succeeded && settings.getBooleanValue(Settings.ConfigOption.CHECK_FOR_UPDATES)) { if (settings.getBooleanValue(Settings.ConfigOption.CHECK_FOR_UPDATES)) {
getLoggingAdapter().log(Level.INFO, "Checking for updates..."); getLoggingAdapter().log(Level.INFO, "Checking for updates...");
new UpdateChecker(getPluginVersion(), getLoggingAdapter()).logToConsole(); CompletableFuture.runAsync(() -> new UpdateChecker(getPluginVersion(), getLoggingAdapter()).logToConsole());
} }
return succeeded; } catch (HuskSyncInitializationException exception) {
}).thenAccept(succeeded -> { getLoggingAdapter().log(Level.SEVERE, exception.getMessage());
// Handle failed initialization initialized.set(false);
if (!succeeded) { } catch (Exception exception) {
getLoggingAdapter().log(Level.SEVERE, "An unhandled exception occurred initializing HuskSync!", exception);
initialized.set(false);
} finally {
// Validate initialization
if (initialized.get()) {
getLoggingAdapter().log(Level.INFO, "Successfully enabled HuskSync v" + getPluginVersion());
} else {
getLoggingAdapter().log(Level.SEVERE, "Failed to initialize HuskSync. The plugin will now be disabled"); getLoggingAdapter().log(Level.SEVERE, "Failed to initialize HuskSync. The plugin will now be disabled");
getServer().getPluginManager().disablePlugin(this); getServer().getPluginManager().disablePlugin(this);
} else {
getLoggingAdapter().log(Level.INFO, "Successfully enabled HuskSync v" + getPluginVersion());
} }
}).exceptionally(exception -> { }
getLoggingAdapter().log(Level.SEVERE, "An exception occurred initializing HuskSync. (" + exception.getMessage() + ") The plugin will now be disabled.");
exception.printStackTrace();
getServer().getPluginManager().disablePlugin(this);
return null;
});
} }
@Override @Override

@ -0,0 +1,12 @@
package net.william278.husksync;
import org.jetbrains.annotations.NotNull;
/**
* Indicates an exception occurred while initialising the HuskSync plugin
*/
public class HuskSyncInitializationException extends RuntimeException {
public HuskSyncInitializationException(@NotNull String message) {
super(message);
}
}

@ -114,7 +114,7 @@ public class MySqlDatabase extends Database {
getLogger().log(Level.SEVERE, "Failed to perform database setup: " + e.getMessage()); getLogger().log(Level.SEVERE, "Failed to perform database setup: " + e.getMessage());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); getLogger().log(Level.SEVERE, "An unhandled exception occurred during database setup!", e);
} }
return false; return false;
} }

Loading…
Cancel
Save