@Test public void updateDynamicShouldLogChanges() { String settingName = MyDynamicSettings.boolSetting.name(); String changedMessage = "Setting changed: '%s' changed from '%s' to '%s' via '%s'"; Config config = Config.builder().withConfigClasses( singletonList( new MyDynamicSettings() ) ).build(); Log log = mock( Log.class ); config.setLogger( log ); config.updateDynamicSetting( settingName, "false", ORIGIN ); config.updateDynamicSetting( settingName, "true", ORIGIN ); config.updateDynamicSetting( settingName, "", ORIGIN ); InOrder order = inOrder( log ); order.verify( log ).info( changedMessage, settingName, "default (true)", "false", "test" ); order.verify( log ).info( changedMessage, settingName, "false", "true", "test" ); order.verify( log ).info( changedMessage, settingName, "true", "default (true)", "test" ); verifyNoMoreInteractions( log ); }
config.updateDynamicSetting( settingName, "another", ORIGIN ); config.updateDynamicSetting( settingName, "secret2", ORIGIN ); config.updateDynamicSetting( settingName, "", ORIGIN );
@Test public void updateDynamicShouldInformRegisteredListeners() { Config config = Config.builder().withConfigClasses( singletonList( new MyDynamicSettings() ) ).build(); AtomicInteger counter = new AtomicInteger( 0 ); config.registerDynamicUpdateListener( MyDynamicSettings.boolSetting, ( previous, update ) -> { counter.getAndIncrement(); assertTrue( previous ); assertFalse( update ); } ); config.updateDynamicSetting( MyDynamicSettings.boolSetting.name(), "false", ORIGIN ); assertThat( counter.get(), is( 1 ) ); }
@Test public void updateDynamicShouldLogExceptionsFromUpdateListeners() { Config config = Config.builder().withConfigClasses( singletonList( new MyDynamicSettings() ) ).build(); IllegalStateException exception = new IllegalStateException( "Boo" ); config.registerDynamicUpdateListener( MyDynamicSettings.boolSetting, ( a, b ) -> { throw exception; } ); Log log = mock( Log.class ); config.setLogger( log ); String settingName = MyDynamicSettings.boolSetting.name(); config.updateDynamicSetting( settingName, "", ORIGIN ); verify( log ).error( "Failure when notifying listeners after dynamic setting change; " + "new setting might not have taken effect: Boo", exception ); }
@Test public void updateDynamicShouldThrowIfSettingIsNotDynamic() { Config config = Config.builder().withConfigClasses( singletonList( mySettingsWithDefaults ) ).build(); expect.expect( IllegalArgumentException.class ); config.updateDynamicSetting( MySettingsWithDefaults.hello.name(), "hello", ORIGIN ); }
@Test public void updateDynamicShouldNotAllowInvalidSettings() { Config config = Config.builder().withConfigClasses( singletonList( new MyDynamicSettings() ) ).build(); expect.expect( InvalidSettingException.class ); config.updateDynamicSetting( MyDynamicSettings.boolSetting.name(), "this is not a boolean", ORIGIN ); }
@Test public void pruningStrategyShouldBeDynamic() throws IOException { CheckPointer checkPointer = getInstanceFromDb( CheckPointer.class ); Config config = getInstanceFromDb( Config.class ); FileSystemAbstraction fs = getInstanceFromDb( FileSystemAbstraction.class ); LogFiles logFiles = LogFilesBuilder.builder( db.databaseLayout(), fs ) .withLogVersionRepository( new SimpleLogVersionRepository() ) .withLastCommittedTransactionIdSupplier( () -> 1 ) .withTransactionIdStore( new SimpleTransactionIdStore() ).build(); // Force transaction log rotation writeTransactionsAndRotateTwice(); // Checkpoint to make sure strategy is evaluated checkPointer.forceCheckPoint( triggerInfo ); // Make sure file is still there since we have disable pruning assertThat( countTransactionLogs( logFiles ), is( 3 ) ); // Change pruning to true config.updateDynamicSetting( keep_logical_logs.name(), "false", "test" ); // Checkpoint to make sure strategy is evaluated checkPointer.forceCheckPoint( triggerInfo ); // Make sure file is removed assertThat( countTransactionLogs( logFiles ), is( 2 ) ); }
@Description( "Updates a given setting value. Passing an empty value will result in removing the configured value " + "and falling back to the default value. Changes will not persist and will be lost if the server is restarted." ) @Procedure( name = "dbms.setConfigValue", mode = DBMS ) public void setConfigValue( @Name( "setting" ) String setting, @Name( "value" ) String value ) { securityContext.assertCredentialsNotExpired(); assertAdmin(); Config config = resolver.resolveDependency( Config.class ); config.updateDynamicSetting( setting, value, "dbms.setConfigValue" ); // throws if something goes wrong }