|  | @@ -33,11 +33,14 @@ import org.elasticsearch.cluster.routing.ShardRouting;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.routing.ShardRoutingState;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.routing.TestShardRouting;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.settings.Settings;
 | 
	
		
			
				|  |  | +import org.elasticsearch.common.util.set.Sets;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.Index;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.shard.ShardId;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.util.ArrayList;
 | 
	
		
			
				|  |  |  import java.util.Arrays;
 | 
	
		
			
				|  |  |  import java.util.Collections;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.equalTo;
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.not;
 | 
	
	
		
			
				|  | @@ -84,4 +87,69 @@ public class StartedShardsRoutingTests extends ESAllocationTestCase {
 | 
	
		
			
				|  |  |          assertThat(shardRouting.currentNodeId(), equalTo("node2"));
 | 
	
		
			
				|  |  |          assertThat(shardRouting.relocatingNodeId(), nullValue());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public void testRelocatingPrimariesWithInitializingReplicas() {
 | 
	
		
			
				|  |  | +        AllocationService allocation = createAllocationService();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        logger.info("--> building initial cluster state");
 | 
	
		
			
				|  |  | +        AllocationId primaryId = AllocationId.newRelocation(AllocationId.newInitializing());
 | 
	
		
			
				|  |  | +        AllocationId replicaId = AllocationId.newInitializing();
 | 
	
		
			
				|  |  | +        boolean relocatingReplica = randomBoolean();
 | 
	
		
			
				|  |  | +        if (relocatingReplica) {
 | 
	
		
			
				|  |  | +            replicaId = AllocationId.newRelocation(replicaId);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        final IndexMetaData indexMetaData = IndexMetaData.builder("test")
 | 
	
		
			
				|  |  | +            .settings(settings(Version.CURRENT))
 | 
	
		
			
				|  |  | +            .numberOfShards(1).numberOfReplicas(1)
 | 
	
		
			
				|  |  | +            .putInSyncAllocationIds(0,
 | 
	
		
			
				|  |  | +                relocatingReplica ? Sets.newHashSet(primaryId.getId(), replicaId.getId()) : Sets.newHashSet(primaryId.getId()))
 | 
	
		
			
				|  |  | +            .build();
 | 
	
		
			
				|  |  | +        final Index index = indexMetaData.getIndex();
 | 
	
		
			
				|  |  | +        ClusterState.Builder stateBuilder = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY))
 | 
	
		
			
				|  |  | +            .nodes(DiscoveryNodes.builder().add(newNode("node1")).add(newNode("node2")).add(newNode("node3")).add(newNode("node4")))
 | 
	
		
			
				|  |  | +            .metaData(MetaData.builder().put(indexMetaData, false));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        final ShardRouting relocatingPrimary = TestShardRouting.newShardRouting(
 | 
	
		
			
				|  |  | +            new ShardId(index, 0), "node1", "node2", true, ShardRoutingState.RELOCATING, primaryId);
 | 
	
		
			
				|  |  | +        final ShardRouting replica = TestShardRouting.newShardRouting(
 | 
	
		
			
				|  |  | +            new ShardId(index, 0), "node3", relocatingReplica ? "node4" : null, false,
 | 
	
		
			
				|  |  | +            relocatingReplica ? ShardRoutingState.RELOCATING : ShardRoutingState.INITIALIZING, replicaId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        stateBuilder.routingTable(RoutingTable.builder().add(IndexRoutingTable.builder(index)
 | 
	
		
			
				|  |  | +            .addIndexShard(new IndexShardRoutingTable.Builder(relocatingPrimary.shardId())
 | 
	
		
			
				|  |  | +                .addShard(relocatingPrimary)
 | 
	
		
			
				|  |  | +                .addShard(replica)
 | 
	
		
			
				|  |  | +                .build()))
 | 
	
		
			
				|  |  | +            .build());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ClusterState state = stateBuilder.build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        logger.info("--> test starting of relocating primary shard with initializing / relocating replica");
 | 
	
		
			
				|  |  | +        ClusterState newState = allocation.applyStartedShards(state, Arrays.asList(relocatingPrimary.getTargetRelocatingShard()));
 | 
	
		
			
				|  |  | +        assertNotEquals(newState, state);
 | 
	
		
			
				|  |  | +        assertTrue(newState.routingTable().index("test").allPrimaryShardsActive());
 | 
	
		
			
				|  |  | +        ShardRouting startedReplica = newState.routingTable().index("test").shard(0).replicaShards().get(0);
 | 
	
		
			
				|  |  | +        if (relocatingReplica) {
 | 
	
		
			
				|  |  | +            assertTrue(startedReplica.relocating());
 | 
	
		
			
				|  |  | +            assertEquals(replica.currentNodeId(), startedReplica.currentNodeId());
 | 
	
		
			
				|  |  | +            assertEquals(replica.relocatingNodeId(), startedReplica.relocatingNodeId());
 | 
	
		
			
				|  |  | +            assertEquals(replica.allocationId().getId(), startedReplica.allocationId().getId());
 | 
	
		
			
				|  |  | +            assertNotEquals(replica.allocationId().getRelocationId(), startedReplica.allocationId().getRelocationId());
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            assertTrue(startedReplica.initializing());
 | 
	
		
			
				|  |  | +            assertEquals(replica.currentNodeId(), startedReplica.currentNodeId());
 | 
	
		
			
				|  |  | +            assertNotEquals(replica.allocationId().getId(), startedReplica.allocationId().getId());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        logger.info("--> test starting of relocating primary shard together with initializing / relocating replica");
 | 
	
		
			
				|  |  | +        List<ShardRouting> startedShards = new ArrayList<>();
 | 
	
		
			
				|  |  | +        startedShards.add(relocatingPrimary.getTargetRelocatingShard());
 | 
	
		
			
				|  |  | +        startedShards.add(relocatingReplica ? replica.getTargetRelocatingShard() : replica);
 | 
	
		
			
				|  |  | +        Collections.shuffle(startedShards, random());
 | 
	
		
			
				|  |  | +        newState = allocation.applyStartedShards(state, startedShards);
 | 
	
		
			
				|  |  | +        assertNotEquals(newState, state);
 | 
	
		
			
				|  |  | +        assertTrue(newState.routingTable().index("test").shard(0).allShardsStarted());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |