Reject null customs at build time (#41782)
Today you can add a null `Custom` to the cluster state or its metadata, but attempting to publish such a cluster state will fail. Unfortunately, the publication-time failure gives very little information about the source of the problem. This change causes the failure to manifest earlier and adds information about which `Custom` was null in order to simplify the investigation. Relates #41090.
This commit is contained in:
parent
00af42fefe
commit
873d0020a5
|
@ -66,8 +66,10 @@ import java.util.EnumSet;
|
|||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static org.elasticsearch.cluster.coordination.Coordinator.ZEN1_BWC_TERM;
|
||||
|
||||
|
@ -736,7 +738,7 @@ public class ClusterState implements ToXContentFragment, Diffable<ClusterState>
|
|||
}
|
||||
|
||||
public Builder putCustom(String type, Custom custom) {
|
||||
customs.put(type, custom);
|
||||
customs.put(type, Objects.requireNonNull(custom, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -746,6 +748,7 @@ public class ClusterState implements ToXContentFragment, Diffable<ClusterState>
|
|||
}
|
||||
|
||||
public Builder customs(ImmutableOpenMap<String, Custom> customs) {
|
||||
StreamSupport.stream(customs.spliterator(), false).forEach(cursor -> Objects.requireNonNull(cursor.value, cursor.key));
|
||||
this.customs.putAll(customs);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -74,11 +74,13 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static org.elasticsearch.common.settings.Settings.readSettingsFromStream;
|
||||
import static org.elasticsearch.common.settings.Settings.writeSettingsToStream;
|
||||
|
@ -1069,7 +1071,7 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, To
|
|||
}
|
||||
|
||||
public Builder putCustom(String type, Custom custom) {
|
||||
customs.put(type, custom);
|
||||
customs.put(type, Objects.requireNonNull(custom, type));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1081,7 @@ public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData>, To
|
|||
}
|
||||
|
||||
public Builder customs(ImmutableOpenMap<String, Custom> customs) {
|
||||
StreamSupport.stream(customs.spliterator(), false).forEach(cursor -> Objects.requireNonNull(cursor.value, cursor.key));
|
||||
this.customs.putAll(customs);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -21,11 +21,13 @@ package org.elasticsearch.cluster;
|
|||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.emptySet;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class ClusterStateTests extends ESTestCase {
|
||||
|
@ -56,4 +58,19 @@ public class ClusterStateTests extends ESTestCase {
|
|||
// state from the same master compare by version
|
||||
assertThat(withMaster1a.supersedes(withMaster1b), equalTo(withMaster1a.version() > withMaster1b.version()));
|
||||
}
|
||||
|
||||
public void testBuilderRejectsNullCustom() {
|
||||
final ClusterState.Builder builder = ClusterState.builder(ClusterName.DEFAULT);
|
||||
final String key = randomAlphaOfLength(10);
|
||||
assertThat(expectThrows(NullPointerException.class, () -> builder.putCustom(key, null)).getMessage(), containsString(key));
|
||||
}
|
||||
|
||||
public void testBuilderRejectsNullInCustoms() {
|
||||
final ClusterState.Builder builder = ClusterState.builder(ClusterName.DEFAULT);
|
||||
final String key = randomAlphaOfLength(10);
|
||||
final ImmutableOpenMap.Builder<String, ClusterState.Custom> mapBuilder = ImmutableOpenMap.builder();
|
||||
mapBuilder.put(key, null);
|
||||
final ImmutableOpenMap<String, ClusterState.Custom> map = mapBuilder.build();
|
||||
assertThat(expectThrows(NullPointerException.class, () -> builder.customs(map)).getMessage(), containsString(key));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
@ -891,4 +892,19 @@ public class MetaDataTests extends ESTestCase {
|
|||
.transientSettings(Settings.builder().put(setting.getKey(), "transient-value").build()).build();
|
||||
assertThat(setting.get(metaData.settings()), equalTo("transient-value"));
|
||||
}
|
||||
|
||||
public void testBuilderRejectsNullCustom() {
|
||||
final MetaData.Builder builder = MetaData.builder();
|
||||
final String key = randomAlphaOfLength(10);
|
||||
assertThat(expectThrows(NullPointerException.class, () -> builder.putCustom(key, null)).getMessage(), containsString(key));
|
||||
}
|
||||
|
||||
public void testBuilderRejectsNullInCustoms() {
|
||||
final MetaData.Builder builder = MetaData.builder();
|
||||
final String key = randomAlphaOfLength(10);
|
||||
final ImmutableOpenMap.Builder<String, MetaData.Custom> mapBuilder = ImmutableOpenMap.builder();
|
||||
mapBuilder.put(key, null);
|
||||
final ImmutableOpenMap<String, MetaData.Custom> map = mapBuilder.build();
|
||||
assertThat(expectThrows(NullPointerException.class, () -> builder.customs(map)).getMessage(), containsString(key));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue