Skip to content

Commit 3036ab1

Browse files
cbismuths1monw
authored andcommitted
Don't omit default values when updating routing exclusions (#33638)
Exclusion setting `cluster.routing.allocation.exclude._host` default value is an empty string. When an exclusion setting is sent with a null value the o.e.c.s.Setting#innerGetRaw API return an empty string (probably to avoid a NullPointerException to be raised). The o.e.c.r.a.d.FilterAllocationDecider class is developed to omit updates of default values for exclusion setting. That's why a null exclusion setting value is translated to an empty string which is equals to the exclusion default value which is configured to be ignored. A simple fix would be to not omit default values for exclusion setting and keep the NullPointerException guard. This is the purpose of this commit. Closes #32721
1 parent aeb3cda commit 3036ab1

File tree

5 files changed

+52
-26
lines changed

5 files changed

+52
-26
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/FilterAllocationDecider.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ public FilterAllocationDecider(Settings settings, ClusterSettings clusterSetting
101101
setClusterRequireFilters(CLUSTER_ROUTING_REQUIRE_GROUP_SETTING.getAsMap(settings));
102102
setClusterExcludeFilters(CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING.getAsMap(settings));
103103
setClusterIncludeFilters(CLUSTER_ROUTING_INCLUDE_GROUP_SETTING.getAsMap(settings));
104-
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_REQUIRE_GROUP_SETTING, this::setClusterRequireFilters, (a,b)-> {}, true);
105-
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING, this::setClusterExcludeFilters, (a,b)-> {}, true);
106-
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_INCLUDE_GROUP_SETTING, this::setClusterIncludeFilters, (a,b)-> {}, true);
104+
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_REQUIRE_GROUP_SETTING, this::setClusterRequireFilters, (a, b) -> {});
105+
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_EXCLUDE_GROUP_SETTING, this::setClusterExcludeFilters, (a, b) -> {});
106+
clusterSettings.addAffixMapUpdateConsumer(CLUSTER_ROUTING_INCLUDE_GROUP_SETTING, this::setClusterIncludeFilters, (a, b) -> {});
107107
}
108108

109109
@Override

server/src/main/java/org/elasticsearch/common/settings/AbstractScopedSettings.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,13 @@ private void ensureSettingIsRegistered(Setting.AffixSetting<?> setting) {
301301
* consumer in order to be processed correctly. This consumer will get a namespace to value map instead of each individual namespace
302302
* and value as in {@link #addAffixUpdateConsumer(Setting.AffixSetting, BiConsumer, BiConsumer)}
303303
*/
304-
public synchronized <T> void addAffixMapUpdateConsumer(Setting.AffixSetting<T> setting, Consumer<Map<String, T>> consumer,
305-
BiConsumer<String, T> validator, boolean omitDefaults) {
304+
public synchronized <T> void addAffixMapUpdateConsumer(Setting.AffixSetting<T> setting, Consumer<Map<String, T>> consumer,
305+
BiConsumer<String, T> validator) {
306306
final Setting<?> registeredSetting = this.complexMatchers.get(setting.getKey());
307307
if (setting != registeredSetting) {
308308
throw new IllegalArgumentException("Setting is not registered for key [" + setting.getKey() + "]");
309309
}
310-
addSettingsUpdater(setting.newAffixMapUpdater(consumer, logger, validator, omitDefaults));
310+
addSettingsUpdater(setting.newAffixMapUpdater(consumer, logger, validator));
311311
}
312312

313313
synchronized void addSettingsUpdater(SettingUpdater<?> updater) {

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ public void apply(Map<AbstractScopedSettings.SettingUpdater<T>, T> value, Settin
700700
}
701701

702702
AbstractScopedSettings.SettingUpdater<Map<String, T>> newAffixMapUpdater(Consumer<Map<String, T>> consumer, Logger logger,
703-
BiConsumer<String, T> validator, boolean omitDefaults) {
703+
BiConsumer<String, T> validator) {
704704
return new AbstractScopedSettings.SettingUpdater<Map<String, T>>() {
705705

706706
@Override
@@ -721,9 +721,7 @@ public Map<String, T> getValue(Settings current, Settings previous) {
721721
// only the ones that have changed otherwise we might get too many updates
722722
// the hasChanged above checks only if there are any changes
723723
T value = updater.getValue(current, previous);
724-
if ((omitDefaults && value.equals(concreteSetting.getDefault(current))) == false) {
725-
result.put(namespace, value);
726-
}
724+
result.put(namespace, value);
727725
}
728726
});
729727
return result;

server/src/test/java/org/elasticsearch/common/settings/ScopedSettingsTests.java

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,8 @@ public void testAddConsumerAffixMap() {
371371
listResults.clear();
372372
listResults.putAll(map);
373373
};
374-
boolean omitDefaults = randomBoolean();
375-
service.addAffixMapUpdateConsumer(listSetting, listConsumer, (s, k) -> {}, omitDefaults);
376-
service.addAffixMapUpdateConsumer(intSetting, intConsumer, (s, k) -> {}, omitDefaults);
374+
service.addAffixMapUpdateConsumer(listSetting, listConsumer, (s, k) -> {});
375+
service.addAffixMapUpdateConsumer(intSetting, intConsumer, (s, k) -> {});
377376
assertEquals(0, listResults.size());
378377
assertEquals(0, intResults.size());
379378
service.applySettings(Settings.builder()
@@ -403,7 +402,6 @@ public void testAddConsumerAffixMap() {
403402
assertEquals(2, listResults.size());
404403
assertEquals(2, intResults.size());
405404

406-
407405
listResults.clear();
408406
intResults.clear();
409407

@@ -416,17 +414,9 @@ public void testAddConsumerAffixMap() {
416414
assertNull("test wasn't changed", intResults.get("test"));
417415
assertEquals(8, intResults.get("test_1").intValue());
418416
assertNull("test_list wasn't changed", listResults.get("test_list"));
419-
if (omitDefaults) {
420-
assertNull(listResults.get("test_list_1"));
421-
assertFalse(listResults.containsKey("test_list_1"));
422-
assertEquals(0, listResults.size());
423-
assertEquals(1, intResults.size());
424-
} else {
425-
assertEquals(Arrays.asList(1), listResults.get("test_list_1")); // reset to default
426-
assertEquals(1, listResults.size());
427-
assertEquals(1, intResults.size());
428-
}
429-
417+
assertEquals(Arrays.asList(1), listResults.get("test_list_1")); // reset to default
418+
assertEquals(1, listResults.size());
419+
assertEquals(1, intResults.size());
430420
}
431421

432422
public void testAffixMapConsumerNotCalledWithNull() {
@@ -442,7 +432,7 @@ public void testAffixMapConsumerNotCalledWithNull() {
442432
affixResults.clear();
443433
affixResults.putAll(map);
444434
};
445-
service.addAffixMapUpdateConsumer(prefixSetting, consumer, (s, k) -> {}, randomBoolean());
435+
service.addAffixMapUpdateConsumer(prefixSetting, consumer, (s, k) -> {});
446436
assertEquals(0, affixResults.size());
447437
service.applySettings(Settings.builder()
448438
.put("eggplant._name", 2)

server/src/test/java/org/elasticsearch/common/settings/SettingTests.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.elasticsearch.common.settings;
2020

2121
import org.elasticsearch.common.collect.Tuple;
22+
import org.elasticsearch.common.settings.AbstractScopedSettings.SettingUpdater;
2223
import org.elasticsearch.common.settings.Setting.Property;
2324
import org.elasticsearch.common.unit.ByteSizeUnit;
2425
import org.elasticsearch.common.unit.ByteSizeValue;
@@ -33,6 +34,8 @@
3334
import java.util.Map;
3435
import java.util.Set;
3536
import java.util.concurrent.atomic.AtomicReference;
37+
import java.util.function.BiConsumer;
38+
import java.util.function.Consumer;
3639
import java.util.function.Function;
3740
import java.util.stream.Collectors;
3841
import java.util.stream.Stream;
@@ -890,4 +893,39 @@ public void testExistsWithFallback() {
890893
}
891894
}
892895

896+
public void testAffixMapUpdateWithNullSettingValue() {
897+
// GIVEN an affix setting changed from "prefix._foo"="bar" to "prefix._foo"=null
898+
final Settings current = Settings.builder()
899+
.put("prefix._foo", (String) null)
900+
.build();
901+
902+
final Settings previous = Settings.builder()
903+
.put("prefix._foo", "bar")
904+
.build();
905+
906+
final Setting.AffixSetting<String> affixSetting =
907+
Setting.prefixKeySetting("prefix" + ".",
908+
(key) -> Setting.simpleString(key, (value, map) -> {}, Property.Dynamic, Property.NodeScope));
909+
910+
final Consumer<Map<String, String>> consumer = (map) -> {};
911+
final BiConsumer<String, String> validator = (s1, s2) -> {};
912+
913+
// WHEN creating an affix updater
914+
final SettingUpdater<Map<String, String>> updater = affixSetting.newAffixMapUpdater(consumer, logger, validator);
915+
916+
// THEN affix updater is always expected to have changed (even when defaults are omitted)
917+
assertTrue(updater.hasChanged(current, previous));
918+
919+
// THEN changes are expected when defaults aren't omitted
920+
final Map<String, String> updatedSettings = updater.getValue(current, previous);
921+
assertNotNull(updatedSettings);
922+
assertEquals(1, updatedSettings.size());
923+
924+
// THEN changes are reported when defaults aren't omitted
925+
final String key = updatedSettings.keySet().iterator().next();
926+
final String value = updatedSettings.get(key);
927+
assertEquals("_foo", key);
928+
assertEquals("", value);
929+
}
930+
893931
}

0 commit comments

Comments
 (0)