|  | @@ -9,14 +9,18 @@
 | 
	
		
			
				|  |  |  package org.elasticsearch.cluster;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import org.apache.lucene.tests.util.LuceneTestCase;
 | 
	
		
			
				|  |  | +import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainRequest;
 | 
	
		
			
				|  |  | +import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.admin.cluster.node.shutdown.NodePrevalidateShardPathResponse;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.admin.cluster.node.shutdown.PrevalidateShardPathRequest;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.admin.cluster.node.shutdown.PrevalidateShardPathResponse;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.admin.cluster.node.shutdown.TransportPrevalidateShardPathAction;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.metadata.IndexMetadata;
 | 
	
		
			
				|  |  |  import org.elasticsearch.cluster.routing.ShardRouting;
 | 
	
		
			
				|  |  | +import org.elasticsearch.common.Strings;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.UUIDs;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.settings.Settings;
 | 
	
		
			
				|  |  | +import org.elasticsearch.common.xcontent.ChunkedToXContent;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.shard.ShardId;
 | 
	
		
			
				|  |  |  import org.elasticsearch.test.ESIntegTestCase;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -77,7 +81,31 @@ public class PrevalidateShardPathIT extends ESIntegTestCase {
 | 
	
		
			
				|  |  |                  assertThat(resp2.getNodes().size(), equalTo(1));
 | 
	
		
			
				|  |  |                  assertThat(resp2.getNodes().get(0).getNode().getId(), equalTo(node2Id));
 | 
	
		
			
				|  |  |                  assertTrue("There should be no failures in the response", resp.failures().isEmpty());
 | 
	
		
			
				|  |  | -                assertTrue("The relocation source node should have removed the shard(s)", resp2.getNodes().get(0).getShardIds().isEmpty());
 | 
	
		
			
				|  |  | +                Set<ShardId> node2ShardIds = resp2.getNodes().get(0).getShardIds();
 | 
	
		
			
				|  |  | +                if (node2ShardIds.size() > 0) {
 | 
	
		
			
				|  |  | +                    for (var node2Shard : clusterService().state()
 | 
	
		
			
				|  |  | +                        .routingTable()
 | 
	
		
			
				|  |  | +                        .allShards()
 | 
	
		
			
				|  |  | +                        .filter(s -> s.getIndexName().equals(indexName))
 | 
	
		
			
				|  |  | +                        .filter(s -> node2ShardIds.contains(s.shardId()))
 | 
	
		
			
				|  |  | +                        .filter(s -> s.currentNodeId().equals(node2Id))
 | 
	
		
			
				|  |  | +                        .toList()) {
 | 
	
		
			
				|  |  | +                        var explanation = client().execute(
 | 
	
		
			
				|  |  | +                            TransportClusterAllocationExplainAction.TYPE,
 | 
	
		
			
				|  |  | +                            new ClusterAllocationExplainRequest().setIndex(node2Shard.getIndexName())
 | 
	
		
			
				|  |  | +                                .setCurrentNode(node2Shard.currentNodeId())
 | 
	
		
			
				|  |  | +                                .setShard(node2Shard.id())
 | 
	
		
			
				|  |  | +                                .setPrimary(node2Shard.primary())
 | 
	
		
			
				|  |  | +                        ).get();
 | 
	
		
			
				|  |  | +                        logger.info(
 | 
	
		
			
				|  |  | +                            "Shard: {} is still located on relocation source node: {}. Allocation explanation: {}",
 | 
	
		
			
				|  |  | +                            node2Shard.shardId(),
 | 
	
		
			
				|  |  | +                            node2,
 | 
	
		
			
				|  |  | +                            Strings.toString(ChunkedToXContent.wrapAsToXContent(explanation), false, true)
 | 
	
		
			
				|  |  | +                        );
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    throw new AssertionError("The relocation source node should have removed the shard(s)");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              } catch (AssertionError e) {
 | 
	
		
			
				|  |  |                  // Removal of shards which are no longer allocated to the node is attempted on every cluster state change in IndicesStore.
 | 
	
		
			
				|  |  |                  // If for whatever reason the removal is not triggered (e.g. not enough nodes reported that the shards are active) or it
 |