Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting validation against arbitrary types #47264

Merged
merged 12 commits into from
Oct 2, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -153,16 +154,20 @@ static Setting<Integer> buildNumberOfShardsSetting() {
public static final Setting<Integer> INDEX_ROUTING_PARTITION_SIZE_SETTING =
Setting.intSetting(SETTING_ROUTING_PARTITION_SIZE, 1, 1, Property.IndexScope);

public static final Setting<Integer> INDEX_NUMBER_OF_ROUTING_SHARDS_SETTING =
Setting.intSetting("index.number_of_routing_shards", INDEX_NUMBER_OF_SHARDS_SETTING,
1, new Setting.Validator<Integer>() {
public static final Setting<Integer> INDEX_NUMBER_OF_ROUTING_SHARDS_SETTING = Setting.intSetting(
"index.number_of_routing_shards",
INDEX_NUMBER_OF_SHARDS_SETTING,
1,
new Setting.Validator<>() {

@Override
public void validate(Integer value) {
public void validate(final Integer value) {

}

@Override
public void validate(Integer numRoutingShards, Map<Setting<Integer>, Integer> settings) {
Integer numShards = settings.get(INDEX_NUMBER_OF_SHARDS_SETTING);
public void validate(final Integer numRoutingShards, final Map<Setting<?>, Object> settings) {
int numShards = (int) settings.get(INDEX_NUMBER_OF_SHARDS_SETTING);
if (numRoutingShards < numShards) {
throw new IllegalArgumentException("index.number_of_routing_shards [" + numRoutingShards
+ "] must be >= index.number_of_shards [" + numShards + "]");
Expand All @@ -171,10 +176,13 @@ public void validate(Integer numRoutingShards, Map<Setting<Integer>, Integer> se
}

@Override
public Iterator<Setting<Integer>> settings() {
return Collections.singleton(INDEX_NUMBER_OF_SHARDS_SETTING).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(INDEX_NUMBER_OF_SHARDS_SETTING);
return settings.iterator();
}
}, Property.IndexScope);

},
Property.IndexScope);

public static final String SETTING_AUTO_EXPAND_REPLICAS = "index.auto_expand_replicas";
public static final Setting<AutoExpandReplicas> INDEX_AUTO_EXPAND_REPLICAS_SETTING = AutoExpandReplicas.SETTING;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import org.elasticsearch.common.unit.RatioValue;
import org.elasticsearch.common.unit.TimeValue;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

Expand Down Expand Up @@ -105,68 +105,72 @@ static final class LowDiskWatermarkValidator implements Setting.Validator<String

@Override
public void validate(String value) {

}

@Override
public void validate(String value, Map<Setting<String>, String> settings) {
final String highWatermarkRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING);
final String floodStageRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
public void validate(final String value, final Map<Setting<?>, Object> settings) {
final String highWatermarkRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING);
final String floodStageRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
doValidate(value, highWatermarkRaw, floodStageRaw);
}

@Override
public Iterator<Setting<String>> settings() {
return Arrays.asList(
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(
CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING,
CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING)
.iterator();
CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
return settings.iterator();
}

}

static final class HighDiskWatermarkValidator implements Setting.Validator<String> {

@Override
public void validate(String value) {
public void validate(final String value) {

}

@Override
public void validate(String value, Map<Setting<String>, String> settings) {
final String lowWatermarkRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING);
final String floodStageRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
public void validate(final String value, final Map<Setting<?>, Object> settings) {
final String lowWatermarkRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING);
final String floodStageRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
doValidate(lowWatermarkRaw, value, floodStageRaw);
}

@Override
public Iterator<Setting<String>> settings() {
return Arrays.asList(
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(
CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING,
CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING)
.iterator();
CLUSTER_ROUTING_ALLOCATION_DISK_FLOOD_STAGE_WATERMARK_SETTING);
return settings.iterator();
}

}

static final class FloodStageValidator implements Setting.Validator<String> {

@Override
public void validate(String value) {
public void validate(final String value) {

}

@Override
public void validate(String value, Map<Setting<String>, String> settings) {
final String lowWatermarkRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING);
final String highWatermarkRaw = settings.get(CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING);
public void validate(final String value, final Map<Setting<?>, Object> settings) {
final String lowWatermarkRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING);
final String highWatermarkRaw = (String) settings.get(CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING);
doValidate(lowWatermarkRaw, highWatermarkRaw, value);
}

@Override
public Iterator<Setting<String>> settings() {
return Arrays.asList(
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(
CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING,
CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING)
.iterator();
CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING);
return settings.iterator();
}

}

private static void doValidate(String low, String high, String flood) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,12 +432,12 @@ private T get(Settings settings, boolean validate) {
try {
T parsed = parser.apply(value);
if (validate) {
final Iterator<Setting<T>> it = validator.settings();
final Map<Setting<T>, T> map;
final Iterator<Setting<?>> it = validator.settings();
final Map<Setting<?>, Object> map;
if (it.hasNext()) {
map = new HashMap<>();
while (it.hasNext()) {
final Setting<T> setting = it.next();
final Setting<?> setting = it.next();
map.put(setting, setting.get(settings, false)); // we have to disable validation or we will stack overflow
}
} else {
Expand Down Expand Up @@ -864,7 +864,7 @@ public interface Validator<T> {
* @param value the value of this setting
* @param settings a map from the settings specified by {@link #settings()}} to their values
*/
default void validate(T value, Map<Setting<T>, T> settings) {
default void validate(T value, Map<Setting<?>, Object> settings) {
}

/**
Expand All @@ -874,7 +874,7 @@ default void validate(T value, Map<Setting<T>, T> settings) {
*
* @return the settings on which the validity of this setting depends.
*/
default Iterator<Setting<T>> settings() {
default Iterator<Setting<?>> settings() {
return Collections.emptyIterator();
}

Expand Down
18 changes: 10 additions & 8 deletions server/src/main/java/org/elasticsearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ public void validate(final String value) {
}

@Override
public void validate(final String value, final Map<Setting<String>, String> settings) {
final String requiredPipeline = settings.get(IndexSettings.REQUIRED_PIPELINE);
public void validate(final String value, final Map<Setting<?>, Object> settings) {
final String requiredPipeline = (String) settings.get(IndexSettings.REQUIRED_PIPELINE);
if (value.equals(IngestService.NOOP_PIPELINE_NAME) == false
&& requiredPipeline.equals(IngestService.NOOP_PIPELINE_NAME) == false) {
throw new IllegalArgumentException(
Expand All @@ -327,8 +327,9 @@ public void validate(final String value, final Map<Setting<String>, String> sett
}

@Override
public Iterator<Setting<String>> settings() {
return List.of(REQUIRED_PIPELINE).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(REQUIRED_PIPELINE);
return settings.iterator();
}

}
Expand All @@ -341,17 +342,18 @@ public void validate(final String value) {
}

@Override
public void validate(final String value, final Map<Setting<String>, String> settings) {
final String defaultPipeline = settings.get(IndexSettings.DEFAULT_PIPELINE);
public void validate(final String value, final Map<Setting<?>, Object> settings) {
final String defaultPipeline = (String) settings.get(IndexSettings.DEFAULT_PIPELINE);
if (value.equals(IngestService.NOOP_PIPELINE_NAME) && defaultPipeline.equals(IngestService.NOOP_PIPELINE_NAME) == false) {
throw new IllegalArgumentException(
"index has a required pipeline [" + value + "] and a default pipeline [" + defaultPipeline + "]");
}
}

@Override
public Iterator<Setting<String>> settings() {
return List.of(DEFAULT_PIPELINE).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(DEFAULT_PIPELINE);
return settings.iterator();
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,46 +76,54 @@ public final class AutoQueueAdjustingExecutorBuilder extends ExecutorBuilder<Aut
minSizeKey,
Integer.toString(minQueueSize),
s -> Setting.parseInt(s, 0, minSizeKey),
new Setting.Validator<Integer>() {
new Setting.Validator<>() {

@Override
public void validate(Integer value) {
public void validate(final Integer value) {

}

@Override
public void validate(Integer value, Map<Setting<Integer>, Integer> settings) {
if (value > settings.get(tempMaxQueueSizeSetting)) {
public void validate(final Integer value, final Map<Setting<?>, Object> settings) {
if (value > (int) settings.get(tempMaxQueueSizeSetting)) {
throw new IllegalArgumentException("Failed to parse value [" + value + "] for setting [" + minSizeKey
+ "] must be <= " + settings.get(tempMaxQueueSizeSetting));
}
}

@Override
public Iterator<Setting<Integer>> settings() {
return Arrays.asList(tempMaxQueueSizeSetting).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(tempMaxQueueSizeSetting);
return settings.iterator();
}

},
Setting.Property.NodeScope);
this.maxQueueSizeSetting = new Setting<>(
maxSizeKey,
Integer.toString(maxQueueSize),
s -> Setting.parseInt(s, 0, maxSizeKey),
new Setting.Validator<Integer>() {

@Override
public void validate(Integer value) {

}

@Override
public void validate(Integer value, Map<Setting<Integer>, Integer> settings) {
if (value < settings.get(tempMinQueueSizeSetting)) {
public void validate(final Integer value, final Map<Setting<?>, Object> settings) {
if (value < (int) settings.get(tempMinQueueSizeSetting)) {
throw new IllegalArgumentException("Failed to parse value [" + value + "] for setting [" + minSizeKey
+ "] must be >= " + settings.get(tempMinQueueSizeSetting));
}
}

@Override
public Iterator<Setting<Integer>> settings() {
return Arrays.asList(tempMinQueueSizeSetting).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(tempMinQueueSizeSetting);
return settings.iterator();
}

},
Setting.Property.NodeScope);
this.frameSizeSetting = Setting.intSetting(frameSizeKey, frameSize, 100, Setting.Property.NodeScope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,68 +507,80 @@ private static List<Setting<String>> invalidSettings(int numberOfInvalidSettings

private static Setting<String> invalidInIsolationSetting(int index) {
return Setting.simpleString("invalid.setting" + index,
new Setting.Validator<String>() {
new Setting.Validator<>() {

@Override
public void validate(String value) {
public void validate(final String value) {
throw new IllegalArgumentException("Invalid in isolation setting");
}

@Override
public void validate(String value, Map<Setting<String>, String> settings) {
public void validate(final String value, final Map<Setting<?>, Object> settings) {

}

},
Property.NodeScope);
}

private static Setting<String> invalidWithDependenciesSetting(int index) {
return Setting.simpleString("invalid.setting" + index,
new Setting.Validator<String>() {
new Setting.Validator<>() {

@Override
public void validate(String value) {
public void validate(final String value) {
}

@Override
public void validate(String value, Map<Setting<String>, String> settings) {
public void validate(final String value, final Map<Setting<?>, Object> settings) {
throw new IllegalArgumentException("Invalid with dependencies setting");
}

},
Property.NodeScope);
}

private static class FooLowSettingValidator implements Setting.Validator<Integer> {

@Override
public void validate(Integer value) {
public void validate(final Integer value) {
}

@Override
public void validate(Integer low, Map<Setting<Integer>, Integer> settings) {
if (settings.containsKey(SETTING_FOO_HIGH) && low > settings.get(SETTING_FOO_HIGH)) {
public void validate(final Integer low, final Map<Setting<?>, Object> settings) {
if (settings.containsKey(SETTING_FOO_HIGH) && low > (int) settings.get(SETTING_FOO_HIGH)) {
throw new IllegalArgumentException("[low]=" + low + " is higher than [high]=" + settings.get(SETTING_FOO_HIGH));
}
}

@Override
public Iterator<Setting<Integer>> settings() {
return asList(SETTING_FOO_LOW, SETTING_FOO_HIGH).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(SETTING_FOO_HIGH);
return settings.iterator();
}

}

private static class FooHighSettingValidator implements Setting.Validator<Integer> {

@Override
public void validate(Integer value) {
public void validate(final Integer value) {

}

@Override
public void validate(Integer high, Map<Setting<Integer>, Integer> settings) {
if (settings.containsKey(SETTING_FOO_LOW) && high < settings.get(SETTING_FOO_LOW)) {
public void validate(final Integer high, final Map<Setting<?>, Object> settings) {
if (settings.containsKey(SETTING_FOO_LOW) && high < (int) settings.get(SETTING_FOO_LOW)) {
throw new IllegalArgumentException("[high]=" + high + " is lower than [low]=" + settings.get(SETTING_FOO_LOW));
}
}

@Override
public Iterator<Setting<Integer>> settings() {
return asList(SETTING_FOO_LOW, SETTING_FOO_HIGH).iterator();
public Iterator<Setting<?>> settings() {
final List<Setting<?>> settings = List.of(SETTING_FOO_LOW);
return settings.iterator();
}

}

private static final Setting<Integer> SETTING_FOO_LOW = new Setting<>("foo.low", "10",
Expand Down
Loading