diff --git a/community/kernel/src/main/java/org/neo4j/kernel/configuration/Config.java b/community/kernel/src/main/java/org/neo4j/kernel/configuration/Config.java index 4d7caeb40eefc..822ae83351da8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/configuration/Config.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/configuration/Config.java @@ -571,11 +571,11 @@ public Optional getValue( @Nonnull String key ) * @implNote No migration or config validation is done. If you need this you have to refactor this method. * * @param setting The setting to set to the specified value. - * @param value The new value to set, passing {@code null} or empty should reset the value back to default value. + * @param newValue The new value to set, passing {@code null} or empty should reset the value back to default value. * @throws IllegalArgumentException if the provided setting is unknown or not dynamic. * @throws InvalidSettingException if the value is not formatted correctly. */ - public void updateDynamicSetting( String setting, String value ) throws IllegalArgumentException, InvalidSettingException + public void updateDynamicSetting( String setting, String newValue ) throws IllegalArgumentException, InvalidSettingException { // Make sure the setting is valid and is marked as dynamic Optional option = findConfigValue( setting ); @@ -591,19 +591,22 @@ public void updateDynamicSetting( String setting, String value ) throws IllegalA throw new IllegalArgumentException( "Setting is not dynamic and can not be changed at runtime" ); } - if ( value == null || value.isEmpty() ) + String oldValue; + + if ( newValue == null || newValue.isEmpty() ) { // Empty means we want to delete the configured value and fallback to the default value - params.remove( setting ); + oldValue = params.remove( setting ); if ( overriddenDefaults.containsKey( setting ) ) { params.put( setting, overriddenDefaults.get( setting ) ); } + newValue = ""; } else { // Change setting, make sure it's valid - Map newEntry = stringMap( setting, value ); + Map newEntry = stringMap( setting, newValue ); List settingValidators = configOptions.stream() .map( ConfigOptions::settingGroup ) .collect( Collectors.toList() ); @@ -612,8 +615,13 @@ public void updateDynamicSetting( String setting, String value ) throws IllegalA validator.validate( newEntry, ignore -> {} ); // Throws if invalid } - params.put( setting, value ); + oldValue = params.put( setting, newValue ); + if ( oldValue == null ) + { + oldValue = ""; + } } + log.info( "Setting changed: '%s' changed from '%s' to '%s'", setting, oldValue, newValue ); } private Optional findConfigValue( String setting ) diff --git a/community/kernel/src/test/java/org/neo4j/kernel/configuration/ConfigTest.java b/community/kernel/src/test/java/org/neo4j/kernel/configuration/ConfigTest.java index 1b718bb0e1d6f..bb6a1c3de9c49 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/configuration/ConfigTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/configuration/ConfigTest.java @@ -33,6 +33,7 @@ import javax.annotation.Nonnull; import org.neo4j.configuration.DocumentedDefaultValue; +import org.neo4j.configuration.Dynamic; import org.neo4j.configuration.Internal; import org.neo4j.configuration.LoadableConfig; import org.neo4j.configuration.ReplacedBy; @@ -353,4 +354,28 @@ public void augmentDefaults() throws Exception config.augmentDefaults( MySettingsWithDefaults.hello, "new default" ); assertEquals( "new default", config.get( MySettingsWithDefaults.hello ) ); } + + public static class MyDynamicSettings implements LoadableConfig + { + @Dynamic + public static final Setting boolSetting = setting( "bool_setting", BOOLEAN, Settings.TRUE ); + } + + @Test + public void updateDynamicShouldLogChanges() throws Exception + { + Config config = Config.builder().withConfigClasses( Collections.singletonList( new MyDynamicSettings() ) ).build(); + + Log log = mock( Log.class ); + config.setLogger( log ); + + config.updateDynamicSetting( MyDynamicSettings.boolSetting.name(), "false" ); + config.updateDynamicSetting( MyDynamicSettings.boolSetting.name(), "true" ); + config.updateDynamicSetting( MyDynamicSettings.boolSetting.name(), "" ); + + verify( log ).info("Setting changed: '%s' changed from '%s' to '%s'", MyDynamicSettings.boolSetting.name(), "", "false" ); + verify( log ).info("Setting changed: '%s' changed from '%s' to '%s'", MyDynamicSettings.boolSetting.name(), "false", "true" ); + verify( log ).info("Setting changed: '%s' changed from '%s' to '%s'", MyDynamicSettings.boolSetting.name(), "true", "" ); + verifyNoMoreInteractions( log ); + } }