From e04f7dc7111633dc22867816c69e1afc51cda3a6 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 12 May 2016 19:51:10 +0200 Subject: [PATCH] #704 Implement reloading via injector - Create interfaces Reloadable and SettingsDependent to recognize reloadable classes - Iterate through instances in injector to reload --- src/main/java/fr/xephi/authme/AuthMe.java | 17 ------- .../executable/authme/ReloadCommand.java | 21 +++++++- .../authme/command/help/HelpProvider.java | 12 +++-- .../xephi/authme/datasource/DataSource.java | 4 +- .../AuthMeServiceInitializer.java | 21 ++++++++ .../authme/initialization/Reloadable.java | 13 +++++ .../initialization/SettingsDependent.java | 16 ++++++ .../java/fr/xephi/authme/output/Messages.java | 14 +++-- .../authme/security/PasswordSecurity.java | 4 +- .../xephi/authme/security/crypts/BCRYPT.java | 12 +++-- .../authme/security/crypts/SALTED2MD5.java | 12 +++-- .../fr/xephi/authme/security/crypts/SMF.java | 1 + .../fr/xephi/authme/settings/SpawnLoader.java | 8 +-- .../executable/authme/ReloadCommandTest.java | 51 ++++++++++++++++--- .../AuthMeServiceInitializerTest.java | 33 ++++++++++++ .../initialization/samples/GammaService.java | 14 ++++- .../samples/PostConstructTestClass.java | 17 ++++++- .../initialization/samples/ProvidedClass.java | 14 ++++- .../output/MessagesIntegrationTest.java | 6 ++- 19 files changed, 240 insertions(+), 50 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/initialization/Reloadable.java create mode 100644 src/main/java/fr/xephi/authme/initialization/SettingsDependent.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index cc0fcaa5..1ae1a6e0 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -321,23 +321,6 @@ public class AuthMe extends JavaPlugin { runAutoPurge(); } - /** - * Reload certain components. - * - * @throws Exception if an error occurs - */ - public void reload() throws Exception { - newSettings.reload(); - // We do not change database type for consistency issues, but we'll output a note in the logs - if (!newSettings.getProperty(DatabaseSettings.BACKEND).equals(database.getType())) { - ConsoleLogger.info("Note: cannot change database type during /authme reload"); - } - database.reload(); - messages.reload(newSettings.getMessagesFile()); - passwordSecurity.reload(); - spawnLoader.initialize(newSettings); - } - /** * Set up the mail API, if enabled. */ diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java index 3c3bc921..ec709796 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java @@ -4,7 +4,11 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.initialization.AuthMeServiceInitializer; import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.settings.NewSetting; +import fr.xephi.authme.settings.properties.DatabaseSettings; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -18,10 +22,25 @@ public class ReloadCommand implements ExecutableCommand { @Inject private AuthMe plugin; + @Inject + private AuthMeServiceInitializer initializer; + + @Inject + private NewSetting settings; + + @Inject + private DataSource dataSource; + @Override public void executeCommand(CommandSender sender, List arguments, CommandService commandService) { try { - plugin.reload(); + settings.reload(); + // We do not change database type for consistency issues, but we'll output a note in the logs + if (!settings.getProperty(DatabaseSettings.BACKEND).equals(dataSource.getType())) { + ConsoleLogger.info("Note: cannot change database type during /authme reload"); + sender.sendMessage("Note: cannot change database type during /authme reload"); + } + initializer.performReloadOnServices(); commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS); } catch (Exception e) { sender.sendMessage("Error occurred during reload of AuthMe: aborting"); diff --git a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java index c5a3ec5f..8a2774a5 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java @@ -7,6 +7,7 @@ import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandPermissions; import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.FoundCommandResult; +import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionsManager; @@ -26,7 +27,7 @@ import static java.util.Collections.singletonList; /** * Help syntax generator for AuthMe commands. */ -public class HelpProvider { +public class HelpProvider implements SettingsDependent { // --- Bit flags --- /** Set to not show the command. */ @@ -46,12 +47,12 @@ public class HelpProvider { public static final int ALL_OPTIONS = ~HIDE_COMMAND; private final PermissionsManager permissionsManager; - private final String helpHeader; + private String helpHeader; @Inject public HelpProvider(PermissionsManager permissionsManager, NewSetting settings) { this.permissionsManager = permissionsManager; - this.helpHeader = settings.getProperty(PluginSettings.HELP_HEADER); + loadSettings(settings); } public List printHelp(CommandSender sender, FoundCommandResult result, int options) { @@ -88,6 +89,11 @@ public class HelpProvider { return lines; } + @Override + public void loadSettings(NewSetting settings) { + helpHeader = settings.getProperty(PluginSettings.HELP_HEADER); + } + private static void printDetailedDescription(CommandDescription command, List lines) { lines.add(ChatColor.GOLD + "Short description: " + ChatColor.WHITE + command.getDescription()); lines.add(ChatColor.GOLD + "Detailed description:"); diff --git a/src/main/java/fr/xephi/authme/datasource/DataSource.java b/src/main/java/fr/xephi/authme/datasource/DataSource.java index 4c844a83..d80affc4 100644 --- a/src/main/java/fr/xephi/authme/datasource/DataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/DataSource.java @@ -1,6 +1,7 @@ package fr.xephi.authme.datasource; import fr.xephi.authme.cache.auth.PlayerAuth; +import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.security.crypts.HashedPassword; import java.util.List; @@ -8,7 +9,7 @@ import java.util.List; /** * Interface for manipulating {@link PlayerAuth} objects from a data source. */ -public interface DataSource { +public interface DataSource extends Reloadable { /** * Return whether there is a record for the given username. @@ -204,6 +205,7 @@ public interface DataSource { /** * Reload the data source. */ + @Override void reload(); } diff --git a/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java b/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java index 72c2169c..c6d7fd85 100644 --- a/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java +++ b/src/main/java/fr/xephi/authme/initialization/AuthMeServiceInitializer.java @@ -2,6 +2,7 @@ package fr.xephi.authme.initialization; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; +import fr.xephi.authme.settings.NewSetting; import javax.annotation.PostConstruct; import javax.inject.Provider; @@ -122,6 +123,26 @@ public class AuthMeServiceInitializer { return object; } + /** + * Performs a reload on all applicable instances which are registered. + * Requires that the {@link NewSetting settings} instance be registered. + *

+ * Note that the order in which these classes are reloaded is not guaranteed. + */ + public void performReloadOnServices() { + NewSetting settings = (NewSetting) objects.get(NewSetting.class); + if (settings == null) { + throw new IllegalStateException("Settings instance is null"); + } + for (Object object : objects.values()) { + if (object instanceof Reloadable) { + ((Reloadable) object).reload(); + } else if (object instanceof SettingsDependent) { + ((SettingsDependent) object).loadSettings(settings); + } + } + } + /** * Instantiates the given class by locating an @Inject constructor and retrieving * or instantiating its parameters. diff --git a/src/main/java/fr/xephi/authme/initialization/Reloadable.java b/src/main/java/fr/xephi/authme/initialization/Reloadable.java new file mode 100644 index 00000000..6b28fc7d --- /dev/null +++ b/src/main/java/fr/xephi/authme/initialization/Reloadable.java @@ -0,0 +1,13 @@ +package fr.xephi.authme.initialization; + +/** + * Interface for reloadable entities. + */ +public interface Reloadable { + + /** + * Performs the reload action. + */ + void reload(); + +} diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java b/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java new file mode 100644 index 00000000..f891b170 --- /dev/null +++ b/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java @@ -0,0 +1,16 @@ +package fr.xephi.authme.initialization; + +import fr.xephi.authme.settings.NewSetting; + +/** + * Interface for classes that keep a local copy of certain settings. + */ +public interface SettingsDependent { + + /** + * Loads the needed settings. + * + * @param settings the settings instance + */ + void loadSettings(NewSetting settings); +} diff --git a/src/main/java/fr/xephi/authme/output/Messages.java b/src/main/java/fr/xephi/authme/output/Messages.java index 8ac42a7b..61bf3d7d 100644 --- a/src/main/java/fr/xephi/authme/output/Messages.java +++ b/src/main/java/fr/xephi/authme/output/Messages.java @@ -1,6 +1,8 @@ package fr.xephi.authme.output; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -14,7 +16,7 @@ import java.io.InputStreamReader; /** * Class for retrieving and sending translatable messages to players. */ -public class Messages { +public class Messages implements SettingsDependent { private FileConfiguration configuration; private String fileName; @@ -114,13 +116,9 @@ public class Messages { return message; } - /** - * Reset the messages manager to retrieve messages from the given file instead of the current one. - * - * @param messagesFile The new file to load messages from - */ - public void reload(File messagesFile) { - initializeFile(messagesFile); + @Override + public void loadSettings(NewSetting settings) { + initializeFile(settings.getMessagesFile()); } private void initializeFile(File messageFile) { diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java index 4a525531..18620426 100644 --- a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java +++ b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java @@ -3,6 +3,7 @@ package fr.xephi.authme.security; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.events.PasswordEncryptionEvent; import fr.xephi.authme.initialization.AuthMeServiceInitializer; +import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.security.crypts.EncryptionMethod; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.settings.NewSetting; @@ -15,7 +16,7 @@ import javax.inject.Inject; /** * Manager class for password-related operations. */ -public class PasswordSecurity { +public class PasswordSecurity implements Reloadable { @Inject private NewSetting settings; @@ -36,6 +37,7 @@ public class PasswordSecurity { * Load or reload the configuration. */ @PostConstruct + @Override public void reload() { this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH); diff --git a/src/main/java/fr/xephi/authme/security/crypts/BCRYPT.java b/src/main/java/fr/xephi/authme/security/crypts/BCRYPT.java index 67d8c794..dc1b3676 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/BCRYPT.java +++ b/src/main/java/fr/xephi/authme/security/crypts/BCRYPT.java @@ -1,6 +1,7 @@ package fr.xephi.authme.security.crypts; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.security.crypts.description.HasSalt; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.SaltType; @@ -13,13 +14,13 @@ import javax.inject.Inject; @Recommendation(Usage.RECOMMENDED) // provided the salt length is >= 8 @HasSalt(value = SaltType.TEXT) // length depends on the bcryptLog2Rounds setting -public class BCRYPT implements EncryptionMethod { +public class BCRYPT implements EncryptionMethod, SettingsDependent { - private final int bCryptLog2Rounds; + private int bCryptLog2Rounds; @Inject public BCRYPT(NewSetting settings) { - this.bCryptLog2Rounds = settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND); + loadSettings(settings); } @Override @@ -52,4 +53,9 @@ public class BCRYPT implements EncryptionMethod { public boolean hasSeparateSalt() { return false; } + + @Override + public void loadSettings(NewSetting settings) { + bCryptLog2Rounds = settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND); + } } diff --git a/src/main/java/fr/xephi/authme/security/crypts/SALTED2MD5.java b/src/main/java/fr/xephi/authme/security/crypts/SALTED2MD5.java index bf67432b..a0e92284 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/SALTED2MD5.java +++ b/src/main/java/fr/xephi/authme/security/crypts/SALTED2MD5.java @@ -1,5 +1,6 @@ package fr.xephi.authme.security.crypts; +import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.crypts.description.HasSalt; import fr.xephi.authme.security.crypts.description.Recommendation; @@ -14,13 +15,13 @@ import static fr.xephi.authme.security.HashUtils.md5; @Recommendation(Usage.ACCEPTABLE) // presuming that length is something sensible (>= 8) @HasSalt(value = SaltType.TEXT) // length defined by the doubleMd5SaltLength setting -public class SALTED2MD5 extends SeparateSaltMethod { +public class SALTED2MD5 extends SeparateSaltMethod implements SettingsDependent { - private final int saltLength; + private int saltLength; @Inject public SALTED2MD5(NewSetting settings) { - saltLength = settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH); + loadSettings(settings); } @Override @@ -33,4 +34,9 @@ public class SALTED2MD5 extends SeparateSaltMethod { return RandomString.generateHex(saltLength); } + @Override + public void loadSettings(NewSetting settings) { + saltLength = settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH); + } + } diff --git a/src/main/java/fr/xephi/authme/security/crypts/SMF.java b/src/main/java/fr/xephi/authme/security/crypts/SMF.java index 832afa2a..175efc3f 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/SMF.java +++ b/src/main/java/fr/xephi/authme/security/crypts/SMF.java @@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils; public class SMF extends UsernameSaltMethod { + @Override public HashedPassword computeHash(String password, String name) { return new HashedPassword(HashUtils.sha1(name.toLowerCase() + password)); } diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java index a046d813..b2d366ae 100644 --- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java +++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java @@ -5,6 +5,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.hooks.PluginHooks; import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.StringUtils; @@ -27,7 +28,7 @@ import java.io.IOException; * should be taken from. In AuthMe, we can distinguish between the regular spawn and a "first spawn", * to which players will be teleported who have joined for the first time. */ -public class SpawnLoader { +public class SpawnLoader implements SettingsDependent { private final File authMeConfigurationFile; private final PluginHooks pluginHooks; @@ -49,7 +50,7 @@ public class SpawnLoader { FileUtils.copyFileFromResource(spawnFile, "spawn.yml"); this.authMeConfigurationFile = new File(pluginFolder, "spawn.yml"); this.pluginHooks = pluginHooks; - initialize(settings); + loadSettings(settings); } /** @@ -57,7 +58,8 @@ public class SpawnLoader { * * @param settings The settings instance */ - public void initialize(NewSetting settings) { + @Override + public void loadSettings(NewSetting settings) { spawnPriority = settings.getProperty(RestrictionSettings.SPAWN_PRIORITY).split(","); authMeConfiguration = YamlConfiguration.loadConfiguration(authMeConfigurationFile); loadEssentialsSpawn(); diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java index 42623496..5d52bbd8 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java @@ -3,7 +3,12 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.AuthMe; import fr.xephi.authme.TestHelper; import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.datasource.DataSourceType; +import fr.xephi.authme.initialization.AuthMeServiceInitializer; import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.settings.NewSetting; +import fr.xephi.authme.settings.properties.DatabaseSettings; import org.bukkit.command.CommandSender; import org.junit.BeforeClass; import org.junit.Test; @@ -14,6 +19,9 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Collections; +import static org.hamcrest.Matchers.containsString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.matches; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -32,7 +40,13 @@ public class ReloadCommandTest { private AuthMe authMe; @Mock - private CommandService service; + private AuthMeServiceInitializer initializer; + + @Mock + private NewSetting settings; + + @Mock + private DataSource dataSource; @BeforeClass public static void setUpLogger() { @@ -40,30 +54,55 @@ public class ReloadCommandTest { } @Test - public void shouldReload() throws Exception { + public void shouldReload() { // given CommandSender sender = mock(CommandSender.class); + CommandService service = mock(CommandService.class); + given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL); + given(dataSource.getType()).willReturn(DataSourceType.MYSQL); // when command.executeCommand(sender, Collections.emptyList(), service); // then - verify(authMe).reload(); + verify(settings).reload(); + verify(initializer).performReloadOnServices(); verify(service).send(sender, MessageKey.CONFIG_RELOAD_SUCCESS); } @Test - public void shouldHandleReloadError() throws Exception { + public void shouldHandleReloadError() { // given - doThrow(IllegalStateException.class).when(authMe).reload(); CommandSender sender = mock(CommandSender.class); + CommandService service = mock(CommandService.class); + doThrow(IllegalStateException.class).when(initializer).performReloadOnServices(); + given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL); + given(dataSource.getType()).willReturn(DataSourceType.MYSQL); // when command.executeCommand(sender, Collections.emptyList(), service); // then - verify(authMe).reload(); + verify(settings).reload(); + verify(initializer).performReloadOnServices(); verify(sender).sendMessage(matches("Error occurred.*")); verify(authMe).stopOrUnload(); } + + @Test + public void shouldIssueWarningForChangedDatasourceSetting() { + // given + CommandSender sender = mock(CommandSender.class); + CommandService service = mock(CommandService.class); + given(settings.getProperty(DatabaseSettings.BACKEND)).willReturn(DataSourceType.MYSQL); + given(dataSource.getType()).willReturn(DataSourceType.SQLITE); + + // when + command.executeCommand(sender, Collections.emptyList(), service); + + // then + verify(settings).reload(); + verify(initializer).performReloadOnServices(); + verify(sender).sendMessage(argThat(containsString("cannot change database type"))); + } } diff --git a/src/test/java/fr/xephi/authme/initialization/AuthMeServiceInitializerTest.java b/src/test/java/fr/xephi/authme/initialization/AuthMeServiceInitializerTest.java index 63e4d01c..a81571d1 100644 --- a/src/test/java/fr/xephi/authme/initialization/AuthMeServiceInitializerTest.java +++ b/src/test/java/fr/xephi/authme/initialization/AuthMeServiceInitializerTest.java @@ -8,6 +8,7 @@ import fr.xephi.authme.initialization.samples.ClassWithAbstractDependency; import fr.xephi.authme.initialization.samples.ClassWithAnnotations; import fr.xephi.authme.initialization.samples.Duration; import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations; +import fr.xephi.authme.initialization.samples.GammaService; import fr.xephi.authme.initialization.samples.InstantiationFallbackClasses; import fr.xephi.authme.initialization.samples.InvalidClass; import fr.xephi.authme.initialization.samples.InvalidPostConstruct; @@ -15,6 +16,7 @@ import fr.xephi.authme.initialization.samples.InvalidStaticFieldInjection; import fr.xephi.authme.initialization.samples.PostConstructTestClass; import fr.xephi.authme.initialization.samples.ProvidedClass; import fr.xephi.authme.initialization.samples.Size; +import fr.xephi.authme.settings.NewSetting; import org.junit.Before; import org.junit.Test; @@ -23,6 +25,7 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; /** * Test for {@link AuthMeServiceInitializer}. @@ -244,4 +247,34 @@ public class AuthMeServiceInitializerTest { assertThat(result.getFallbackDependency(), not(nullValue())); } + @Test + public void shouldPerformReloadOnApplicableInstances() { + // given + initializer.provide(Size.class, 12); + initializer.provide(Duration.class, -113L); + initializer.register(NewSetting.class, mock(NewSetting.class)); + + GammaService gammaService = initializer.get(GammaService.class); + PostConstructTestClass postConstructTestClass = initializer.get(PostConstructTestClass.class); + ProvidedClass providedClass = initializer.get(ProvidedClass.class); + initializer.get(ClassWithAnnotations.class); + // Assert that no class was somehow reloaded at initialization + assertThat(gammaService.getWasReloaded() || postConstructTestClass.getWasReloaded() + || providedClass.getWasReloaded(), equalTo(false)); + + // when + initializer.performReloadOnServices(); + + // then + assertThat(gammaService.getWasReloaded(), equalTo(true)); + assertThat(postConstructTestClass.getWasReloaded(), equalTo(true)); + assertThat(providedClass.getWasReloaded(), equalTo(true)); + } + + @Test(expected = RuntimeException.class) + public void shouldThrowForNullSetting() { + // given / when / then + initializer.performReloadOnServices(); + } + } diff --git a/src/test/java/fr/xephi/authme/initialization/samples/GammaService.java b/src/test/java/fr/xephi/authme/initialization/samples/GammaService.java index 9d6f9bfa..158187ea 100644 --- a/src/test/java/fr/xephi/authme/initialization/samples/GammaService.java +++ b/src/test/java/fr/xephi/authme/initialization/samples/GammaService.java @@ -1,13 +1,16 @@ package fr.xephi.authme.initialization.samples; +import fr.xephi.authme.initialization.Reloadable; + import javax.inject.Inject; /** * Sample - class dependent on alpha service. */ -public class GammaService { +public class GammaService implements Reloadable { private AlphaService alphaService; + private boolean wasReloaded; @Inject public GammaService(AlphaService alphaService) { @@ -17,4 +20,13 @@ public class GammaService { public AlphaService getAlphaService() { return alphaService; } + + @Override + public void reload() { + wasReloaded = true; + } + + public boolean getWasReloaded() { + return wasReloaded; + } } diff --git a/src/test/java/fr/xephi/authme/initialization/samples/PostConstructTestClass.java b/src/test/java/fr/xephi/authme/initialization/samples/PostConstructTestClass.java index 0bec84ee..375e58fa 100644 --- a/src/test/java/fr/xephi/authme/initialization/samples/PostConstructTestClass.java +++ b/src/test/java/fr/xephi/authme/initialization/samples/PostConstructTestClass.java @@ -1,12 +1,15 @@ package fr.xephi.authme.initialization.samples; +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.settings.NewSetting; + import javax.annotation.PostConstruct; import javax.inject.Inject; /** * Sample class for testing the execution of @PostConstruct methods. */ -public class PostConstructTestClass { +public class PostConstructTestClass implements SettingsDependent { @Inject @Size @@ -15,6 +18,7 @@ public class PostConstructTestClass { private BetaManager betaManager; private boolean wasPostConstructCalled = false; private boolean wasSecondPostConstructCalled = false; + private boolean wasReloaded = false; @PostConstruct protected void setFieldToTrue() { @@ -34,4 +38,15 @@ public class PostConstructTestClass { public BetaManager getBetaManager() { return betaManager; } + + @Override + public void loadSettings(NewSetting settings) { + if (settings != null) { + wasReloaded = true; + } + } + + public boolean getWasReloaded() { + return wasReloaded; + } } diff --git a/src/test/java/fr/xephi/authme/initialization/samples/ProvidedClass.java b/src/test/java/fr/xephi/authme/initialization/samples/ProvidedClass.java index 7ce81bd3..d3405abe 100644 --- a/src/test/java/fr/xephi/authme/initialization/samples/ProvidedClass.java +++ b/src/test/java/fr/xephi/authme/initialization/samples/ProvidedClass.java @@ -1,11 +1,15 @@ package fr.xephi.authme.initialization.samples; +import fr.xephi.authme.initialization.Reloadable; + import javax.inject.Inject; /** * Sample - class that is always provided to the initializer beforehand. */ -public class ProvidedClass { +public class ProvidedClass implements Reloadable { + + private boolean wasReloaded = false; @Inject public ProvidedClass() { @@ -15,4 +19,12 @@ public class ProvidedClass { public ProvidedClass(String manualConstructor) { } + @Override + public void reload() { + wasReloaded = true; + } + + public boolean getWasReloaded() { + return wasReloaded; + } } diff --git a/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java index cd858ad8..5777d1d4 100644 --- a/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java @@ -2,6 +2,7 @@ package fr.xephi.authme.output; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.settings.NewSetting; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.junit.Before; @@ -19,6 +20,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.junit.Assume.assumeThat; +import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; @@ -247,9 +249,11 @@ public class MessagesIntegrationTest { MessageKey key = MessageKey.WRONG_PASSWORD; // assumption: message comes back as defined in messages_test.yml assumeThat(messages.retrieveSingle(key), equalTo("§cWrong password!")); + NewSetting settings = mock(NewSetting.class); + given(settings.getMessagesFile()).willReturn(TestHelper.getJarFile("/messages_test2.yml")); // when - messages.reload(TestHelper.getJarFile("/messages_test2.yml")); + messages.loadSettings(settings); // then assertThat(messages.retrieveSingle(key), equalTo("test2 - wrong password"));