#704 Implement reloading via injector

- Create interfaces Reloadable and SettingsDependent to recognize reloadable classes
- Iterate through instances in injector to reload
This commit is contained in:
ljacqu
2016-05-12 19:51:10 +02:00
parent 4bad04b160
commit e04f7dc711
19 changed files with 240 additions and 50 deletions
@@ -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.<String>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.<String>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.<String>emptyList(), service);
// then
verify(settings).reload();
verify(initializer).performReloadOnServices();
verify(sender).sendMessage(argThat(containsString("cannot change database type")));
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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"));