package org.elasticsearch.test.unit.cluster.routing.allocation; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.routing.RoutingNodes; import org.elasticsearch.cluster.routing.RoutingTable; import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.testng.annotations.Test; import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder; import static org.elasticsearch.cluster.metadata.IndexMetaData.newIndexMetaDataBuilder; import static org.elasticsearch.cluster.metadata.MetaData.newMetaDataBuilder; import static org.elasticsearch.cluster.node.DiscoveryNodes.newNodesBuilder; import static org.elasticsearch.cluster.routing.RoutingBuilders.routingTable; import static org.elasticsearch.cluster.routing.ShardRoutingState.*; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; import static org.elasticsearch.test.unit.cluster.routing.allocation.RoutingAllocationTests.newNode; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; /** * */ public class UpdateNumberOfReplicasTests { private final ESLogger logger = Loggers.getLogger(UpdateNumberOfReplicasTests.class); @Test public void testUpdateNumberOfReplicas() { AllocationService strategy = new AllocationService(settingsBuilder().put("cluster.routing.allocation.concurrent_recoveries", 10).build()); logger.info("Building initial routing table"); MetaData metaData = newMetaDataBuilder() .put(newIndexMetaDataBuilder("test").numberOfShards(1).numberOfReplicas(1)) .build(); RoutingTable routingTable = routingTable() .addAsNew(metaData.index("test")) .build(); ClusterState clusterState = newClusterStateBuilder().metaData(metaData).routingTable(routingTable).build(); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().get(0).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(1).state(), equalTo(UNASSIGNED)); assertThat(routingTable.index("test").shard(0).shards().get(0).currentNodeId(), nullValue()); assertThat(routingTable.index("test").shard(0).shards().get(1).currentNodeId(), nullValue()); logger.info("Adding two nodes and performing rerouting"); clusterState = newClusterStateBuilder().state(clusterState).nodes(newNodesBuilder().put(newNode("node1")).put(newNode("node2"))).build(); RoutingTable prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); logger.info("Start all the primary shards"); RoutingNodes routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy.applyStartedShards(clusterState, routingNodes.node("node1").shardsWithState(INITIALIZING)).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); logger.info("Start all the replica shards"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy.applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).shards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo("node1")); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo("node2")); logger.info("add another replica"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = RoutingTable.builder().routingTable(routingTable).updateNumberOfReplicas(2).build(); metaData = MetaData.newMetaDataBuilder().metaData(clusterState.metaData()).updateNumberOfReplicas(2).build(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).metaData(metaData).build(); assertThat(clusterState.metaData().index("test").numberOfReplicas(), equalTo(2)); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo("node1")); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo("node2")); assertThat(routingTable.index("test").shard(0).replicaShards().get(1).state(), equalTo(UNASSIGNED)); logger.info("Add another node and start the added replica"); clusterState = newClusterStateBuilder().state(clusterState).nodes(newNodesBuilder().putAll(clusterState.nodes()).put(newNode("node3"))).build(); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo("node1")); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo("node2")); assertThat(routingTable.index("test").shard(0).replicaShards().get(1).state(), equalTo(INITIALIZING)); assertThat(routingTable.index("test").shard(0).replicaShards().get(1).currentNodeId(), equalTo("node3")); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = strategy.applyStartedShards(clusterState, routingNodes.shardsWithState(INITIALIZING)).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(3)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo("node1")); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), equalTo("node2")); assertThat(routingTable.index("test").shard(0).replicaShards().get(1).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(1).currentNodeId(), equalTo("node3")); logger.info("now remove a replica"); routingNodes = clusterState.routingNodes(); prevRoutingTable = routingTable; routingTable = RoutingTable.builder().routingTable(routingTable).updateNumberOfReplicas(1).build(); metaData = MetaData.newMetaDataBuilder().metaData(clusterState.metaData()).updateNumberOfReplicas(1).build(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).metaData(metaData).build(); assertThat(clusterState.metaData().index("test").numberOfReplicas(), equalTo(1)); assertThat(prevRoutingTable != routingTable, equalTo(true)); assertThat(routingTable.index("test").shards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).size(), equalTo(2)); assertThat(routingTable.index("test").shard(0).primaryShard().state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).primaryShard().currentNodeId(), equalTo("node1")); assertThat(routingTable.index("test").shard(0).replicaShards().size(), equalTo(1)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).state(), equalTo(STARTED)); assertThat(routingTable.index("test").shard(0).replicaShards().get(0).currentNodeId(), anyOf(equalTo("node2"), equalTo("node3"))); logger.info("do a reroute, should remain the same"); prevRoutingTable = routingTable; routingTable = strategy.reroute(clusterState).routingTable(); clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); assertThat(prevRoutingTable != routingTable, equalTo(false)); } }