diff --git a/core/src/main/java/org/elasticsearch/gateway/BaseGatewayShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/BaseGatewayShardAllocator.java index 1b2d8b794f5..275311cf6a8 100644 --- a/core/src/main/java/org/elasticsearch/gateway/BaseGatewayShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/BaseGatewayShardAllocator.java @@ -20,14 +20,20 @@ package org.elasticsearch.gateway; import org.apache.logging.log4j.Logger; +import org.elasticsearch.cluster.routing.RoutingNode; import org.elasticsearch.cluster.routing.RoutingNodes; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.allocation.AllocateUnassignedDecision; import org.elasticsearch.cluster.routing.allocation.AllocationDecision; +import org.elasticsearch.cluster.routing.allocation.NodeAllocationResult; import org.elasticsearch.cluster.routing.allocation.RoutingAllocation; +import org.elasticsearch.cluster.routing.allocation.decider.Decision; import org.elasticsearch.common.component.AbstractComponent; import org.elasticsearch.common.settings.Settings; +import java.util.ArrayList; +import java.util.List; + /** * An abstract class that implements basic functionality for allocating * shards to nodes based on shard copies that already exist in the cluster. @@ -85,4 +91,17 @@ public abstract class BaseGatewayShardAllocator extends AbstractComponent { public abstract AllocateUnassignedDecision makeAllocationDecision(ShardRouting unassignedShard, RoutingAllocation allocation, Logger logger); + + /** + * Builds decisions for all nodes in the cluster, so that the explain API can provide information on + * allocation decisions for each node, while still waiting to allocate the shard (e.g. due to fetching shard data). + */ + protected List buildDecisionsForAllNodes(ShardRouting shard, RoutingAllocation allocation) { + List results = new ArrayList<>(); + for (RoutingNode node : allocation.routingNodes()) { + Decision decision = allocation.deciders().canAllocate(shard, node, allocation); + results.add(new NodeAllocationResult(node.node(), null, decision)); + } + return results; + } } diff --git a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java index 2a858dd6e85..2200ed1b4f2 100644 --- a/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/PrimaryShardAllocator.java @@ -124,9 +124,11 @@ public abstract class PrimaryShardAllocator extends BaseGatewayShardAllocator { final FetchResult shardState = fetchData(unassignedShard, allocation); if (shardState.hasData() == false) { allocation.setHasPendingAsyncFetch(); - if (explain == false) { - return AllocateUnassignedDecision.no(AllocationStatus.FETCHING_SHARD_DATA, null); + List nodeDecisions = null; + if (explain) { + nodeDecisions = buildDecisionsForAllNodes(unassignedShard, allocation); } + return AllocateUnassignedDecision.no(AllocationStatus.FETCHING_SHARD_DATA, nodeDecisions); } // don't create a new IndexSetting object for every shard as this could cause a lot of garbage diff --git a/core/src/main/java/org/elasticsearch/gateway/ReplicaShardAllocator.java b/core/src/main/java/org/elasticsearch/gateway/ReplicaShardAllocator.java index a5f3bd6a8fb..3a838ef3785 100644 --- a/core/src/main/java/org/elasticsearch/gateway/ReplicaShardAllocator.java +++ b/core/src/main/java/org/elasticsearch/gateway/ReplicaShardAllocator.java @@ -238,19 +238,6 @@ public abstract class ReplicaShardAllocator extends BaseGatewayShardAllocator { return AllocateUnassignedDecision.NOT_TAKEN; } - /** - * Builds decisions for all nodes in the cluster, so that the explain API can provide information on - * allocation decisions for each node, while still waiting to allocate the shard (e.g. due to fetching shard data). - */ - private List buildDecisionsForAllNodes(ShardRouting shard, RoutingAllocation allocation) { - List results = new ArrayList<>(); - for (RoutingNode node : allocation.routingNodes()) { - Decision decision = allocation.deciders().canAllocate(shard, node, allocation); - results.add(new NodeAllocationResult(node.node(), null, decision)); - } - return results; - } - /** * Determines if the shard can be allocated on at least one node based on the allocation deciders. *