Skip to content

Commit

Permalink
Add ref docs links to allocation explain text (elastic#110571)
Browse files Browse the repository at this point in the history
We say "specify the target shard in the request" but this doesn't in
itself help users work out how to do this. Linking to the docs should
help.
  • Loading branch information
DaveCTurner authored Jul 8, 2024
1 parent 9c0c708 commit 402b747
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.cluster.routing.allocation.AllocationDecision;
import org.elasticsearch.cluster.routing.allocation.ShardAllocationDecision;
import org.elasticsearch.common.ReferenceDocs;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Iterators;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
Expand Down Expand Up @@ -43,10 +45,14 @@
*/
public final class ClusterAllocationExplanation implements ChunkedToXContentObject, Writeable {

static final String NO_SHARD_SPECIFIED_MESSAGE = "No shard was specified in the explain API request, so this response "
+ "explains a randomly chosen unassigned shard. There may be other unassigned shards in this cluster which cannot be assigned for "
+ "different reasons. It may not be possible to assign this shard until one of the other shards is assigned correctly. To explain "
+ "the allocation of other shards (whether assigned or unassigned) you must specify the target shard in the request to this API.";
static final String NO_SHARD_SPECIFIED_MESSAGE = Strings.format(
"""
No shard was specified in the explain API request, so this response explains a randomly chosen unassigned shard. There may be \
other unassigned shards in this cluster which cannot be assigned for different reasons. It may not be possible to assign this \
shard until one of the other shards is assigned correctly. To explain the allocation of other shards (whether assigned or \
unassigned) you must specify the target shard in the request to this API. See %s for more information.""",
ReferenceDocs.ALLOCATION_EXPLAIN_API
);

private final boolean specificShard;
private final ShardRouting shardRouting;
Expand Down Expand Up @@ -206,25 +212,23 @@ private Iterator<? extends ToXContent> getShardAllocationDecisionChunked(ToXCont
} else {
String explanation;
if (shardRouting.state() == ShardRoutingState.RELOCATING) {
explanation = "the shard is in the process of relocating from node ["
+ currentNode.getName()
+ "] "
+ "to node ["
+ relocationTargetNode.getName()
+ "], wait until relocation has completed";
explanation = Strings.format(
"the shard is in the process of relocating from node [%s] to node [%s], wait until relocation has completed",
currentNode.getName(),
relocationTargetNode.getName()
);
} else {
assert shardRouting.state() == ShardRoutingState.INITIALIZING;
explanation = "the shard is in the process of initializing on node ["
+ currentNode.getName()
+ "], "
+ "wait until initialization has completed";
explanation = Strings.format(
"the shard is in the process of initializing on node [%s], wait until initialization has completed",
currentNode.getName()
);
}
return Iterators.single((builder, p) -> builder.field("explanation", explanation));
}
}

private static XContentBuilder unassignedInfoToXContent(UnassignedInfo unassignedInfo, XContentBuilder builder) throws IOException {

private static void unassignedInfoToXContent(UnassignedInfo unassignedInfo, XContentBuilder builder) throws IOException {
builder.startObject("unassigned_info");
builder.field("reason", unassignedInfo.reason());
builder.field("at", UnassignedInfo.DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(unassignedInfo.unassignedTimeMillis())));
Expand All @@ -237,6 +241,5 @@ private static XContentBuilder unassignedInfoToXContent(UnassignedInfo unassigne
}
builder.field("last_allocation_status", AllocationDecision.fromAllocationStatus(unassignedInfo.lastAllocationStatus()));
builder.endObject();
return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import org.elasticsearch.cluster.routing.allocation.ShardAllocationDecision;
import org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.ReferenceDocs;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.snapshots.SnapshotsInfoService;
import org.elasticsearch.tasks.Task;
Expand Down Expand Up @@ -160,11 +162,10 @@ public static ShardRouting findShardToExplain(ClusterAllocationExplainRequest re
}
}
if (foundShard == null) {
throw new IllegalArgumentException(
"No shard was specified in the request which means the response should explain a randomly-chosen unassigned shard, "
+ "but there are no unassigned shards in this cluster. To explain the allocation of an assigned shard you must "
+ "specify the target shard in the request."
);
throw new IllegalArgumentException(Strings.format("""
No shard was specified in the request which means the response should explain a randomly-chosen unassigned shard, but \
there are no unassigned shards in this cluster. To explain the allocation of an assigned shard you must specify the \
target shard in the request. See %s for more information.""", ReferenceDocs.ALLOCATION_EXPLAIN_API));
}
} else {
String index = request.getIndex();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public enum ReferenceDocs {
UNASSIGNED_SHARDS,
EXECUTABLE_JNA_TMPDIR,
NETWORK_THREADING_MODEL,
ALLOCATION_EXPLAIN_API,
// this comment keeps the ';' on the next line so every entry above has a trailing ',' which makes the diff for adding new links cleaner
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
"CONTACT_SUPPORT": "troubleshooting.html#troubleshooting-contact-support",
"UNASSIGNED_SHARDS": "red-yellow-cluster-status.html",
"EXECUTABLE_JNA_TMPDIR": "executable-jna-tmpdir.html",
"NETWORK_THREADING_MODEL": "modules-network.html#modules-network-threading-model"
"NETWORK_THREADING_MODEL": "modules-network.html#modules-network-threading-model",
"ALLOCATION_EXPLAIN_API": "cluster-allocation-explain.html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ public void testFindAnyUnassignedShardToExplain() {
allOf(
// no point in asserting the precise wording of the message into this test, but we care that it contains these bits:
containsString("No shard was specified in the request"),
containsString("specify the target shard in the request")
containsString("specify the target shard in the request"),
containsString("https://www.elastic.co/guide/en/elasticsearch/reference"),
containsString("cluster-allocation-explain.html")
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ public void testRandomShardExplanationToXContent() throws Exception {
allOf(
// no point in asserting the precise wording of the message into this test, but we care that the note contains these bits:
containsString("No shard was specified in the explain API request"),
containsString("specify the target shard in the request")
containsString("specify the target shard in the request"),
containsString("https://www.elastic.co/guide/en/elasticsearch/reference"),
containsString("cluster-allocation-explain.html")
)
);

Expand Down

0 comments on commit 402b747

Please sign in to comment.