diff --git a/docs/reference/shutdown/apis/shutdown-get.asciidoc b/docs/reference/shutdown/apis/shutdown-get.asciidoc index b022cf2d13d55..b0097eb0caf7f 100644 --- a/docs/reference/shutdown/apis/shutdown-get.asciidoc +++ b/docs/reference/shutdown/apis/shutdown-get.asciidoc @@ -78,6 +78,7 @@ including the status of shard migration, task migration, and plugin cleanup: "nodes": [ { "node_id": "USpTGYaBSIKbgSUJR2Z9lg", + "node_ephemeral_id": null, "type": "RESTART", "reason": "Demonstrating how the node shutdown API works", "shutdown_startedmillis": 1624406108685, diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotShutdownIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotShutdownIT.java index 3c71b50321c76..53263468bf0de 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotShutdownIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotShutdownIT.java @@ -502,11 +502,16 @@ private static void putShutdownMetadata( clusterService.submitUnbatchedStateUpdateTask("mark node for removal", new ClusterStateUpdateTask() { @Override public ClusterState execute(ClusterState currentState) { - final var nodeId = currentState.nodes().resolveNode(nodeName).getId(); + final var node = currentState.nodes().resolveNode(nodeName); return currentState.copyAndUpdateMetadata( mdb -> mdb.putCustom( NodesShutdownMetadata.TYPE, - new NodesShutdownMetadata(Map.of(nodeId, shutdownMetadataBuilder.setNodeId(nodeId).build())) + new NodesShutdownMetadata( + Map.of( + node.getId(), + shutdownMetadataBuilder.setNodeId(node.getId()).setNodeEphemeralId(node.getEphemeralId()).build() + ) + ) ) ); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStressTestsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStressTestsIT.java index 15c5e3379734a..ac322868989bb 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStressTestsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SnapshotStressTestsIT.java @@ -1235,15 +1235,16 @@ public ClusterState execute(ClusterState currentState) { Strings.toString(currentState), currentState.metadata().nodeShutdowns().getAll().isEmpty() ); - final var nodeId = currentState.nodes().resolveNode(node.nodeName).getId(); + final var discoveryNode = currentState.nodes().resolveNode(node.nodeName); return currentState.copyAndUpdateMetadata( mdb -> mdb.putCustom( NodesShutdownMetadata.TYPE, new NodesShutdownMetadata( Map.of( - nodeId, + discoveryNode.getId(), SingleNodeShutdownMetadata.builder() - .setNodeId(nodeId) + .setNodeId(discoveryNode.getId()) + .setNodeEphemeralId(discoveryNode.getEphemeralId()) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(clusterService.threadPool().absoluteTimeInMillis()) .setReason("test") diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/SingleNodeShutdownMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/SingleNodeShutdownMetadata.java index aa8b092ffcca0..ebd7a7db13f82 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/SingleNodeShutdownMetadata.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/SingleNodeShutdownMetadata.java @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.Objects; +import static org.elasticsearch.TransportVersions.NODE_SHUTDOWN_EPHEMERAL_ID_ADDED; import static org.elasticsearch.core.Strings.format; /** @@ -40,6 +41,7 @@ public class SingleNodeShutdownMetadata implements SimpleDiffable new SingleNodeShutdownMetadata( (String) a[0], - Type.valueOf((String) a[1]), - (String) a[2], - (long) a[3], - (boolean) a[4], - (TimeValue) a[5], - (String) a[6], - (TimeValue) a[7] + (String) a[1], + Type.valueOf((String) a[2]), + (String) a[3], + (long) a[4], + (boolean) a[5], + (TimeValue) a[6], + (String) a[7], + (TimeValue) a[8] ) ); static { PARSER.declareString(ConstructingObjectParser.constructorArg(), NODE_ID_FIELD); + PARSER.declareField( + ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> p.textOrNull(), + NODE_EPHEMERAL_ID_FIELD, + ObjectParser.ValueType.STRING_OR_NULL + ); PARSER.declareString(ConstructingObjectParser.constructorArg(), TYPE_FIELD); PARSER.declareString(ConstructingObjectParser.constructorArg(), REASON_FIELD); PARSER.declareLong(ConstructingObjectParser.constructorArg(), STARTED_AT_MILLIS_FIELD); @@ -91,6 +100,8 @@ public static SingleNodeShutdownMetadata parse(XContentParser parser) { public static final TimeValue DEFAULT_RESTART_SHARD_ALLOCATION_DELAY = TimeValue.timeValueMinutes(5); private final String nodeId; + @Nullable + private final String nodeEphemeralId; private final Type type; private final String reason; private final long startedAtMillis; @@ -110,6 +121,7 @@ public static SingleNodeShutdownMetadata parse(XContentParser parser) { */ private SingleNodeShutdownMetadata( String nodeId, + @Nullable String nodeEphemeralId, Type type, String reason, long startedAtMillis, @@ -119,6 +131,7 @@ private SingleNodeShutdownMetadata( @Nullable TimeValue gracePeriod ) { this.nodeId = Objects.requireNonNull(nodeId, "node ID must not be null"); + this.nodeEphemeralId = nodeEphemeralId; this.type = Objects.requireNonNull(type, "shutdown type must not be null"); this.reason = Objects.requireNonNull(reason, "shutdown reason must not be null"); this.startedAtMillis = startedAtMillis; @@ -157,6 +170,11 @@ private SingleNodeShutdownMetadata( public SingleNodeShutdownMetadata(StreamInput in) throws IOException { this.nodeId = in.readString(); + if (in.getTransportVersion().onOrAfter(NODE_SHUTDOWN_EPHEMERAL_ID_ADDED)) { + this.nodeEphemeralId = in.readOptionalString(); + } else { + this.nodeEphemeralId = null; // empty when talking to old nodes, meaning the persistent node id is the only differentiator + } this.type = in.readEnum(Type.class); this.reason = in.readString(); this.startedAtMillis = in.readVLong(); @@ -181,6 +199,15 @@ public String getNodeId() { return nodeId; } + /** + * @return The ephemeral ID of the node this {@link SingleNodeShutdownMetadata} concerns, or + * {@code null} if the ephemeral id is unknown. + */ + @Nullable + public String getNodeEphemeralId() { + return nodeEphemeralId; + } + /** * @return The type of shutdown this is (shutdown vs. permanent). */ @@ -241,6 +268,9 @@ public TimeValue getGracePeriod() { @Override public void writeTo(StreamOutput out) throws IOException { out.writeString(nodeId); + if (out.getTransportVersion().onOrAfter(NODE_SHUTDOWN_EPHEMERAL_ID_ADDED)) { + out.writeOptionalString(nodeEphemeralId); + } if ((out.getTransportVersion().before(REPLACE_SHUTDOWN_TYPE_ADDED_VERSION) && this.type == SingleNodeShutdownMetadata.Type.REPLACE) || (out.getTransportVersion().before(SIGTERM_ADDED_VERSION) && this.type == Type.SIGTERM)) { out.writeEnum(SingleNodeShutdownMetadata.Type.REMOVE); @@ -264,6 +294,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); { builder.field(NODE_ID_FIELD.getPreferredName(), nodeId); + builder.field(NODE_EPHEMERAL_ID_FIELD.getPreferredName(), nodeEphemeralId); builder.field(TYPE_FIELD.getPreferredName(), type); builder.field(REASON_FIELD.getPreferredName(), reason); builder.timestampFieldsFromUnixEpochMillis( @@ -295,6 +326,7 @@ public boolean equals(Object o) { return getStartedAtMillis() == that.getStartedAtMillis() && getNodeSeen() == that.getNodeSeen() && getNodeId().equals(that.getNodeId()) + && Objects.equals(getNodeEphemeralId(), that.getNodeEphemeralId()) && getType() == that.getType() && getReason().equals(that.getReason()) && Objects.equals(getAllocationDelay(), that.getAllocationDelay()) @@ -306,6 +338,7 @@ && getReason().equals(that.getReason()) public int hashCode() { return Objects.hash( getNodeId(), + getNodeEphemeralId(), getType(), getReason(), getStartedAtMillis(), @@ -322,6 +355,8 @@ public String toString() { stringBuilder.append("{") .append("nodeId=[") .append(nodeId) + .append("], nodeEphemeralId=[") + .append(nodeEphemeralId) .append(']') .append(", type=[") .append(type) @@ -350,6 +385,7 @@ public static Builder builder(SingleNodeShutdownMetadata original) { return builder(); } return new Builder().setNodeId(original.getNodeId()) + .setNodeEphemeralId(original.getNodeEphemeralId()) .setType(original.getType()) .setReason(original.getReason()) .setStartedAtMillis(original.getStartedAtMillis()) @@ -359,6 +395,7 @@ public static Builder builder(SingleNodeShutdownMetadata original) { public static class Builder { private String nodeId; + private String nodeEphemeralId; private Type type; private String reason; private long startedAtMillis = -1; @@ -378,6 +415,15 @@ public Builder setNodeId(String nodeId) { return this; } + /** + * @param nodeEphemeralId The node ephemeral ID this metadata refers to. + * @return This builder. + */ + public Builder setNodeEphemeralId(String nodeEphemeralId) { + this.nodeEphemeralId = nodeEphemeralId; + return this; + } + /** * @param type The type of shutdown. * @return This builder. @@ -444,6 +490,7 @@ public SingleNodeShutdownMetadata build() { return new SingleNodeShutdownMetadata( nodeId, + nodeEphemeralId, type, reason, startedAtMillis, diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/NodesShutdownMetadataTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/NodesShutdownMetadataTests.java index f3c38efb09ce9..8a801d1ece816 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/NodesShutdownMetadataTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/NodesShutdownMetadataTests.java @@ -78,6 +78,7 @@ public void testIsNodeShuttingDown() { "this_node", SingleNodeShutdownMetadata.builder() .setNodeId("this_node") + .setNodeEphemeralId("this_node") .setReason("shutdown for a unit test") .setType(type) .setStartedAtMillis(randomNonNegativeLong()) @@ -106,6 +107,7 @@ public void testIsNodeShuttingDown() { public void testSigtermIsRemoveInOlderVersions() throws IOException { SingleNodeShutdownMetadata metadata = SingleNodeShutdownMetadata.builder() .setNodeId("myid") + .setNodeEphemeralId("myid") .setType(SingleNodeShutdownMetadata.Type.SIGTERM) .setReason("myReason") .setStartedAtMillis(0L) @@ -127,6 +129,7 @@ public void testIsNodeMarkedForRemoval() { SingleNodeShutdownMetadata.Type type; SingleNodeShutdownMetadata.Builder builder = SingleNodeShutdownMetadata.builder() .setNodeId("thenode") + .setNodeEphemeralId("thenode") .setReason("myReason") .setStartedAtMillis(0L); switch (type = randomFrom(SingleNodeShutdownMetadata.Type.values())) { @@ -182,6 +185,7 @@ private SingleNodeShutdownMetadata randomNodeShutdownInfo() { final SingleNodeShutdownMetadata.Type type = randomFrom(SingleNodeShutdownMetadata.Type.values()); final SingleNodeShutdownMetadata.Builder builder = SingleNodeShutdownMetadata.builder() .setNodeId(randomAlphaOfLength(5)) + .setNodeEphemeralId(randomAlphaOfLength(5)) .setType(type) .setReason(randomAlphaOfLength(5)) .setStartedAtMillis(randomNonNegativeLong()); diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java index e81b85e4fec8f..88633b14ac461 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java @@ -638,6 +638,7 @@ public void testRemainingDelayCalculationsWithUnrelatedShutdowns() { shutdowns = shutdowns.putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(randomValueOtherThan(lastNodeId, () -> randomAlphaOfLengthBetween(5, 10))) + .setNodeEphemeralId(randomValueOtherThan(lastNodeId, () -> randomAlphaOfLengthBetween(5, 10))) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) .setType(type) @@ -658,6 +659,7 @@ public void testRemainingDelayCalculationWhenNodeIsShuttingDownForRemoval() { NodesShutdownMetadata shutdowns = NodesShutdownMetadata.EMPTY.putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(lastNodeId) + .setNodeEphemeralId(lastNodeId) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) .setType(type) @@ -678,6 +680,7 @@ public void testRemainingDelayCalculationWhenNodeIsKnownToBeRestartingWithCustom NodesShutdownMetadata shutdowns = NodesShutdownMetadata.EMPTY.putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(lastNodeId) + .setNodeEphemeralId(lastNodeId) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) .setType(SingleNodeShutdownMetadata.Type.RESTART) @@ -700,6 +703,7 @@ public void testRemainingDelayCalculationWhenNodeIsKnownToBeRestartingWithDefaul NodesShutdownMetadata shutdowns = NodesShutdownMetadata.EMPTY.putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(lastNodeId) + .setNodeEphemeralId(lastNodeId) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) .setType(SingleNodeShutdownMetadata.Type.RESTART) @@ -728,6 +732,7 @@ public void testRemainingDelayUsesIndexLevelDelayIfNodeWasNotRestartingWhenShard NodesShutdownMetadata shutdowns = NodesShutdownMetadata.EMPTY.putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(lastNodeId) + .setNodeEphemeralId(lastNodeId) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) .setType(SingleNodeShutdownMetadata.Type.RESTART) diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DiskThresholdMonitorTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DiskThresholdMonitorTests.java index 201fbc9e3ca18..5a6e8e65495a0 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DiskThresholdMonitorTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DiskThresholdMonitorTests.java @@ -909,6 +909,7 @@ protected void updateIndicesReadOnly(Set indicesToUpdate, Releasable onC sourceNode, SingleNodeShutdownMetadata.builder() .setNodeId(sourceNode) + .setNodeEphemeralId(sourceNode) .setReason("testing") .setType(SingleNodeShutdownMetadata.Type.REPLACE) .setTargetNodeName(targetNode) @@ -1293,6 +1294,7 @@ public void testSkipDiskThresholdMonitorWhenStateNotRecovered() { "node1", SingleNodeShutdownMetadata.builder() .setNodeId("node1") + .setNodeEphemeralId("node1") .setReason("testing") .setType(SingleNodeShutdownMetadata.Type.REPLACE) .setTargetNodeName("node3") diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceReconcilerTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceReconcilerTests.java index 1f80160c92ffd..14801c961129f 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceReconcilerTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceReconcilerTests.java @@ -923,6 +923,7 @@ public Decision canAllocate(ShardRouting shardRouting, RoutingAllocation allocat "node-0", SingleNodeShutdownMetadata.builder() .setNodeId("node-0") + .setNodeEphemeralId("node-0") .setType(SingleNodeShutdownMetadata.Type.REPLACE) .setTargetNodeName("node-2") .setStartedAtMillis(System.currentTimeMillis()) diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceShardsAllocatorTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceShardsAllocatorTests.java index 18055865c18ae..ce9c72318d9f3 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceShardsAllocatorTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/DesiredBalanceShardsAllocatorTests.java @@ -857,6 +857,7 @@ public void resetDesiredBalance() { final var shutdownType = randomFrom(Type.SIGTERM, Type.REMOVE, Type.REPLACE); final var singleShutdownMetadataBuilder = SingleNodeShutdownMetadata.builder() .setNodeId(node2.getId()) + .setNodeEphemeralId(node2.getEphemeralId()) .setReason("test") .setType(shutdownType) .setStartedAtMillis(randomNonNegativeLong()); diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeReplacementAllocationDeciderTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeReplacementAllocationDeciderTests.java index e8ac6d22698dd..7750a01a13a84 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeReplacementAllocationDeciderTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeReplacementAllocationDeciderTests.java @@ -420,6 +420,7 @@ private NodesShutdownMetadata createNodeShutdownReplacementMetadata(String sourc return new NodesShutdownMetadata(new HashMap<>()).putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(sourceNodeId) + .setNodeEphemeralId(sourceNodeId) .setTargetNodeName(targetNodeName) .setType(SingleNodeShutdownMetadata.Type.REPLACE) .setReason(this.getTestName()) diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeShutdownAllocationDeciderTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeShutdownAllocationDeciderTests.java index e81e27a7343f3..d795c80bf5b96 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeShutdownAllocationDeciderTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/NodeShutdownAllocationDeciderTests.java @@ -227,6 +227,7 @@ private NodesShutdownMetadata createNodesShutdownMetadata(SingleNodeShutdownMeta return new NodesShutdownMetadata(new HashMap<>()).putSingleNodeMetadata( SingleNodeShutdownMetadata.builder() .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) .setType(shutdownType) .setReason(this.getTestName()) .setStartedAtMillis(1L) diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDeciderTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDeciderTests.java index 0ef5fcc624e1f..7f42beb5181ec 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDeciderTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/decider/SnapshotInProgressAllocationDeciderTests.java @@ -216,6 +216,7 @@ public void testYesWhenSnapshotInProgressButShardIsPausedDueToShutdown() { nodeId, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(randomNonNegativeLong()) .setReason("test") diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/shards/ShardsAvailabilityHealthIndicatorServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/shards/ShardsAvailabilityHealthIndicatorServiceTests.java index a6c8064ad551b..586f088d554a5 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/shards/ShardsAvailabilityHealthIndicatorServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/shards/ShardsAvailabilityHealthIndicatorServiceTests.java @@ -2254,6 +2254,7 @@ private static ClusterState createClusterStateWith( it -> it.nodeId, it -> SingleNodeShutdownMetadata.builder() .setNodeId(it.nodeId) + .setNodeEphemeralId(it.nodeId) .setType(it.type) .setReason("test") .setNodeSeen(true) diff --git a/server/src/test/java/org/elasticsearch/health/node/selection/HealthNodeTaskExecutorTests.java b/server/src/test/java/org/elasticsearch/health/node/selection/HealthNodeTaskExecutorTests.java index 92bfabf6f1972..51dadd8154549 100644 --- a/server/src/test/java/org/elasticsearch/health/node/selection/HealthNodeTaskExecutorTests.java +++ b/server/src/test/java/org/elasticsearch/health/node/selection/HealthNodeTaskExecutorTests.java @@ -196,6 +196,7 @@ private ClusterState stateWithNodeShuttingDown(ClusterState clusterState, Single localNodeId, SingleNodeShutdownMetadata.builder() .setNodeId(localNodeId) + .setNodeEphemeralId(localNodeId) .setReason("shutdown for a unit test") .setType(type) .setStartedAtMillis(randomNonNegativeLong()) diff --git a/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java b/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java index c568f6a38a5fb..5aa9b89595915 100644 --- a/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java +++ b/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java @@ -628,6 +628,7 @@ public void testTasksNotAssignedToShuttingDownNodes() { DiscoveryNode::getId, node -> SingleNodeShutdownMetadata.builder() .setNodeId(node.getId()) + .setNodeEphemeralId(node.getEphemeralId()) .setReason("shutdown for a unit test") .setType(type) .setStartedAtMillis(randomNonNegativeLong()) diff --git a/server/src/test/java/org/elasticsearch/readiness/ReadinessServiceTests.java b/server/src/test/java/org/elasticsearch/readiness/ReadinessServiceTests.java index 8644dfc033c95..15febaa8db2ab 100644 --- a/server/src/test/java/org/elasticsearch/readiness/ReadinessServiceTests.java +++ b/server/src/test/java/org/elasticsearch/readiness/ReadinessServiceTests.java @@ -246,6 +246,7 @@ public void testStatusChange() throws Exception { httpTransport.node.getId(), SingleNodeShutdownMetadata.builder() .setNodeId(httpTransport.node.getId()) + .setNodeEphemeralId(httpTransport.node.getEphemeralId()) .setReason("testing") .setType(SingleNodeShutdownMetadata.Type.RESTART) .setStartedAtMillis(randomNonNegativeLong()) diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java index a92d55f6d419c..dafd27947f68b 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java @@ -88,6 +88,7 @@ private ClusterState getClusterStateWithNodeShutdownMetadata(List nodeId nodeId -> SingleNodeShutdownMetadata.builder() .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) .setStartedAtMillis(randomNonNegativeLong()) .setReason(getTestName()) .build() @@ -476,6 +477,7 @@ public void testXContent() throws IOException { "node-id", SingleNodeShutdownMetadata.builder() .setNodeId("node-id") + .setNodeEphemeralId("node-id") .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(randomNonNegativeLong()) .setReason("test") diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderTests.java index c42f0c008548c..692835c9123a6 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/cluster/routing/allocation/DataTierAllocationDeciderTests.java @@ -759,27 +759,15 @@ private SingleNodeShutdownMetadata randomShutdownMetadataRemovingNode(String nod SingleNodeShutdownMetadata.Type.REPLACE, SingleNodeShutdownMetadata.Type.REMOVE ); + var builder = SingleNodeShutdownMetadata.builder() + .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) + .setType(type) + .setReason(this.getTestName()); return switch (type) { - case REMOVE -> SingleNodeShutdownMetadata.builder() - .setNodeId(nodeId) - .setType(type) - .setReason(this.getTestName()) - .setStartedAtMillis(randomNonNegativeLong()) - .build(); - case REPLACE -> SingleNodeShutdownMetadata.builder() - .setNodeId(nodeId) - .setType(type) - .setTargetNodeName(randomAlphaOfLength(10)) - .setReason(this.getTestName()) - .setStartedAtMillis(randomNonNegativeLong()) - .build(); - case SIGTERM -> SingleNodeShutdownMetadata.builder() - .setNodeId(nodeId) - .setType(type) - .setGracePeriod(randomTimeValue()) - .setReason(this.getTestName()) - .setStartedAtMillis(randomNonNegativeLong()) - .build(); + case REMOVE -> builder.setStartedAtMillis(randomNonNegativeLong()).build(); + case REPLACE -> builder.setTargetNodeName(randomAlphaOfLength(10)).setStartedAtMillis(randomNonNegativeLong()).build(); + case SIGTERM -> builder.setGracePeriod(randomTimeValue()).setStartedAtMillis(randomNonNegativeLong()).build(); case RESTART -> throw new AssertionError("bad randomization, this method only generates removal type shutdowns"); }; } @@ -1019,6 +1007,7 @@ private NodesShutdownMetadata randomRestartInCluster(Set currentNodes) { nodeId, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) .setType(SingleNodeShutdownMetadata.Type.RESTART) .setReason(this.getTestName()) .setStartedAtMillis(randomNonNegativeLong()) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CheckShrinkReadyStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CheckShrinkReadyStepTests.java index 72bf7cedb2fb9..a427f8c9154cc 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CheckShrinkReadyStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/CheckShrinkReadyStepTests.java @@ -465,6 +465,7 @@ public void testStepCompletableIfAllShardsActive() { .setStartedAtMillis(randomNonNegativeLong()) .setReason("test") .setNodeId("node1") + .setNodeEphemeralId("node1") .setTargetNodeName(targetNodeName) .setGracePeriod(grace) .build() @@ -544,6 +545,7 @@ public void testStepBecomesUncompletable() { .setStartedAtMillis(randomNonNegativeLong()) .setReason("test") .setNodeId("node1") + .setNodeEphemeralId("node1") .setTargetNodeName(targetNodeName) .setGracePeriod(grace) .build() diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java index b77e643bc2853..e70b1be1d108d 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java @@ -601,6 +601,7 @@ public void testIndicesOnShuttingDownNodesInDangerousStep() { "shutdown_node", SingleNodeShutdownMetadata.builder() .setNodeId("shutdown_node") + .setNodeEphemeralId("shutdown_node") .setReason("shut down for test") .setStartedAtMillis(randomNonNegativeLong()) .setType(SingleNodeShutdownMetadata.Type.RESTART) @@ -632,6 +633,7 @@ public void testIndicesOnShuttingDownNodesInDangerousStep() { "shutdown_node", SingleNodeShutdownMetadata.builder() .setNodeId("shutdown_node") + .setNodeEphemeralId("shutdown_node") .setReason("shut down for test") .setStartedAtMillis(randomNonNegativeLong()) .setType(type) diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/assignment/TrainedModelAssignmentClusterServiceTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/assignment/TrainedModelAssignmentClusterServiceTests.java index 5a358ef833cb5..28d81b7464e58 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/assignment/TrainedModelAssignmentClusterServiceTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/inference/assignment/TrainedModelAssignmentClusterServiceTests.java @@ -1556,6 +1556,7 @@ public void testAreAssignedNodesRemoved_GivenShuttingDownNodeThatIsRouted() { nodeId1, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId1) + .setNodeEphemeralId(nodeId1) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(System.currentTimeMillis()) .setReason("test") @@ -1599,6 +1600,7 @@ public void testAreAssignedNodesRemoved_GivenShuttingDownNodeThatIsNotRouted() { nodeId1, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId1) + .setNodeEphemeralId(nodeId1) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(System.currentTimeMillis()) .setReason("test") @@ -1645,6 +1647,7 @@ public void testRemoveRoutingToUnassignableNodes_RemovesRouteForRemovedNodes() { nodeId3, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId3) + .setNodeEphemeralId(nodeId3) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(System.currentTimeMillis()) .setReason("test") @@ -1703,6 +1706,7 @@ public void testRemoveRoutingToUnassignableNodes_AddsAStoppingRouteForShuttingDo nodeId3, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId3) + .setNodeEphemeralId(nodeId3) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(System.currentTimeMillis()) .setReason("test") @@ -1763,6 +1767,7 @@ public void testRemoveRoutingToUnassignableNodes_IgnoresARouteThatIsStoppedForSh nodeId3, SingleNodeShutdownMetadata.builder() .setNodeId(nodeId3) + .setNodeEphemeralId(nodeId3) .setType(SingleNodeShutdownMetadata.Type.REMOVE) .setStartedAtMillis(System.currentTimeMillis()) .setReason("test") @@ -1993,6 +1998,7 @@ private NodesShutdownMetadata nodesShutdownMetadata(DiscoveryNode nodeToShutdown nodeToShutdown.getId(), SingleNodeShutdownMetadata.builder() .setNodeId(nodeToShutdown.getId()) + .setNodeEphemeralId(nodeToShutdown.getEphemeralId()) .setStartedAtMillis(1L) .setType(SingleNodeShutdownMetadata.Type.RESTART) .setReason("because this cannot be null") @@ -2049,6 +2055,7 @@ static NodesShutdownMetadata shutdownMetadata(String nodeId) { .setStartedAtMillis(randomNonNegativeLong()) .setReason("tests") .setNodeId(nodeId) + .setNodeEphemeralId(nodeId) .build() ) ); diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/SingleNodeShutdownStatus.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/SingleNodeShutdownStatus.java index 95fd97cd5931f..33398aa8493cf 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/SingleNodeShutdownStatus.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/SingleNodeShutdownStatus.java @@ -114,6 +114,7 @@ public Iterator toXContentChunked(ToXContent.Params params return ChunkedToXContent.builder(params).object(b -> { b.append((builder, p) -> { builder.field(SingleNodeShutdownMetadata.NODE_ID_FIELD.getPreferredName(), metadata.getNodeId()); + builder.field(SingleNodeShutdownMetadata.NODE_EPHEMERAL_ID_FIELD.getPreferredName(), metadata.getNodeEphemeralId()); builder.field(SingleNodeShutdownMetadata.TYPE_FIELD.getPreferredName(), metadata.getType()); builder.field(SingleNodeShutdownMetadata.REASON_FIELD.getPreferredName(), metadata.getReason()); if (metadata.getAllocationDelay() != null) { diff --git a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java index 4e1b8c3cf3b9a..98ad9a48e2c72 100644 --- a/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java +++ b/x-pack/plugin/shutdown/src/main/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeAction.java @@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.NodesShutdownMetadata; import org.elasticsearch.cluster.metadata.SingleNodeShutdownMetadata; +import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.MasterService; @@ -49,7 +50,8 @@ public class TransportPutShutdownNodeAction extends AcknowledgedTransportMasterN private static boolean putShutdownNodeState( Map shutdownMetadata, Predicate nodeExists, - Request request + Request request, + String nodeEphemeralId ) { if (isNoop(shutdownMetadata, request)) { return false; @@ -58,6 +60,7 @@ private static boolean putShutdownNodeState( final boolean nodeSeen = nodeExists.test(request.getNodeId()); SingleNodeShutdownMetadata newNodeMetadata = SingleNodeShutdownMetadata.builder() .setNodeId(request.getNodeId()) + .setNodeEphemeralId(nodeEphemeralId) .setType(request.getType()) .setReason(request.getReason()) .setStartedAtMillis(System.currentTimeMillis()) @@ -103,8 +106,13 @@ public ClusterState execute(BatchExecutionContext batchExec boolean needsReroute = false; for (final var taskContext : batchExecutionContext.taskContexts()) { var request = taskContext.getTask().request(); + String nodeEphemeralId = null; + DiscoveryNode discoveryNode = initialState.nodes().getNodes().get(request.getNodeId()); + if (discoveryNode != null) { + nodeEphemeralId = discoveryNode.getEphemeralId(); + } try (var ignored = taskContext.captureResponseHeaders()) { - changed |= putShutdownNodeState(shutdownMetadata, nodeExistsPredicate, request); + changed |= putShutdownNodeState(shutdownMetadata, nodeExistsPredicate, request, nodeEphemeralId); } catch (Exception e) { taskContext.onFailure(e); continue; diff --git a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusResponseTests.java b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusResponseTests.java index 2c68e8d7f39be..e3a8fb4482c3d 100644 --- a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusResponseTests.java +++ b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/GetShutdownStatusResponseTests.java @@ -55,6 +55,7 @@ public static SingleNodeShutdownMetadata randomNodeShutdownMetadata() { final TimeValue gracefulShutdown = type == SIGTERM ? randomPositiveTimeValue() : null; return SingleNodeShutdownMetadata.builder() .setNodeId(randomAlphaOfLength(5)) + .setNodeEphemeralId(randomAlphaOfLength(5)) .setType(type) .setReason(randomAlphaOfLength(5)) .setStartedAtMillis(randomNonNegativeLong()) diff --git a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java index 9a1dda99674c9..c8f1d8b58a490 100644 --- a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java +++ b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java @@ -603,6 +603,7 @@ public void testNodeNotInCluster() { .setStartedAtMillis(randomNonNegativeLong()) .setReason(this.getTestName()) .setNodeId(bogusNodeId) + .setNodeEphemeralId(bogusNodeId) .build() ) ) @@ -866,6 +867,7 @@ private ClusterState createTestClusterState( .setStartedAtMillis(randomNonNegativeLong()) .setReason(this.getTestName()) .setNodeId(SHUTTING_DOWN_NODE_ID) + .setNodeEphemeralId(SHUTTING_DOWN_NODE_ID) .build() ) ) diff --git a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeActionTests.java b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeActionTests.java index de5c5d393f39d..ed603d30d0593 100644 --- a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeActionTests.java +++ b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportPutShutdownNodeActionTests.java @@ -15,6 +15,8 @@ import org.elasticsearch.cluster.ClusterStateTaskExecutor.TaskContext; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.SingleNodeShutdownMetadata.Type; +import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.MasterServiceTaskQueue; @@ -32,6 +34,8 @@ import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Set; import static org.elasticsearch.core.Strings.format; import static org.hamcrest.Matchers.containsString; @@ -96,14 +100,16 @@ public void testNoop() throws Exception { targetNodeName, null ); - action.masterOperation(null, request, ClusterState.EMPTY_STATE, ActionListener.noop()); + var dummyNode = new DiscoveryNode(targetNodeName, "node1", "eph-node1", "abc", "abc", null, Map.of(), Set.of(), null); + var state = ClusterState.builder(ClusterState.EMPTY_STATE).nodes(DiscoveryNodes.builder().add(dummyNode).build()).build(); + action.masterOperation(null, request, state, ActionListener.noop()); var updateTask = ArgumentCaptor.forClass(PutShutdownNodeTask.class); var taskExecutor = ArgumentCaptor.forClass(PutShutdownNodeExecutor.class); verify(clusterService).createTaskQueue(any(), any(), taskExecutor.capture()); verify(taskQueue).submitTask(any(), updateTask.capture(), any()); when(taskContext.getTask()).thenReturn(updateTask.getValue()); ClusterState stableState = taskExecutor.getValue() - .execute(new ClusterStateTaskExecutor.BatchExecutionContext<>(ClusterState.EMPTY_STATE, List.of(taskContext), () -> null)); + .execute(new ClusterStateTaskExecutor.BatchExecutionContext<>(state, List.of(taskContext), () -> null)); // run the request again, there should be no call to submit an update task clearTaskQueueInvocations(); diff --git a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformNodeTests.java b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformNodeTests.java index 3df566fd70047..8c7a6abe3f055 100644 --- a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformNodeTests.java +++ b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformNodeTests.java @@ -88,6 +88,7 @@ private Supplier> clusterState(String nodeId) { SHUTTING_DOWN_ID, SingleNodeShutdownMetadata.builder() .setNodeId(SHUTTING_DOWN_ID) + .setNodeEphemeralId(SHUTTING_DOWN_ID) .setReason("shutdown for a unit test") .setType(SingleNodeShutdownMetadata.Type.RESTART) .setStartedAtMillis(randomNonNegativeLong())