diff --git a/core/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java b/core/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java index 1cbf8605210..10d7ff9deaf 100644 --- a/core/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java +++ b/core/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java @@ -350,7 +350,7 @@ public class RoutingTable implements Iterable, Diffable indicesRouting = ImmutableOpenMap.builder(); + private ImmutableOpenMap.Builder indicesRouting = ImmutableOpenMap.builder(); public Builder() { @@ -406,6 +406,9 @@ public class RoutingTable implements Iterable, Diffable, Diffable, Diffable indicesRouting) { + if (indicesRouting == null) { + throw new IllegalStateException("once build is called the builder cannot be reused"); + } this.indicesRouting.putAll(indicesRouting); return this; } public Builder remove(String index) { + if (indicesRouting == null) { + throw new IllegalStateException("once build is called the builder cannot be reused"); + } indicesRouting.remove(index); return this; } @@ -518,16 +530,21 @@ public class RoutingTable implements Iterable, Diffable indexRoutingTable : indicesRouting.values()) { indicesRouting.put(indexRoutingTable.value.index(), indexRoutingTable.value.normalizeVersions()); } - return new RoutingTable(version, indicesRouting.build()); + RoutingTable table = new RoutingTable(version, indicesRouting.build()); + indicesRouting = null; + return table; } public static RoutingTable readFrom(StreamInput in) throws IOException { diff --git a/core/src/test/java/org/elasticsearch/cluster/routing/RoutingTableTests.java b/core/src/test/java/org/elasticsearch/cluster/routing/RoutingTableTests.java index ea5dda0128b..2a7ed6a4a93 100644 --- a/core/src/test/java/org/elasticsearch/cluster/routing/RoutingTableTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/routing/RoutingTableTests.java @@ -35,6 +35,7 @@ import org.junit.Test; import static org.elasticsearch.cluster.routing.ShardRoutingState.INITIALIZING; import static org.elasticsearch.common.settings.Settings.settingsBuilder; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; @@ -55,6 +56,7 @@ public class RoutingTableTests extends ESAllocationTestCase { .build()); private ClusterState clusterState; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -264,4 +266,34 @@ public class RoutingTableTests extends ESAllocationTestCase { fail("Calling with non-existing index should be ignored at the moment"); } } + + public void testRoutingTableBuiltMoreThanOnce() { + RoutingTable.Builder b = RoutingTable.builder(); + b.build(); // Ok the first time + try { + b.build(); + fail("expected exception"); + } catch (IllegalStateException e) { + assertThat(e.getMessage(), containsString("cannot be reused")); + } + try { + b.add((IndexRoutingTable) null); + fail("expected exception"); + } catch (IllegalStateException e) { + assertThat(e.getMessage(), containsString("cannot be reused")); + } + try { + b.updateNumberOfReplicas(1, "foo"); + fail("expected exception"); + } catch (IllegalStateException e) { + assertThat(e.getMessage(), containsString("cannot be reused")); + } + try { + b.remove("foo"); + fail("expected exception"); + } catch (IllegalStateException e) { + assertThat(e.getMessage(), containsString("cannot be reused")); + } + + } }