-
Notifications
You must be signed in to change notification settings - Fork 25k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creating a transport action for the CoordinationDiagnosticsService (#…
…87984) This exposes the CoordinationDiagnosticsService (#87672) through a transport action so that it can be called remotely as part of the health API in the event that: (1) there has been no master recently, (2) there are master-eligible nodes in the cluster, (3) none are elected, and (4) the current node is not master eligible.
- Loading branch information
Showing
7 changed files
with
449 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 87984 | ||
summary: Creating a transport action for the `CoordinationDiagnosticsService` | ||
area: Health | ||
type: enhancement | ||
issues: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
...va/org/elasticsearch/action/admin/cluster/coordination/CoordinationDiagnosticsAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.action.admin.cluster.coordination; | ||
|
||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.action.ActionRequest; | ||
import org.elasticsearch.action.ActionRequestValidationException; | ||
import org.elasticsearch.action.ActionResponse; | ||
import org.elasticsearch.action.ActionType; | ||
import org.elasticsearch.action.support.ActionFilters; | ||
import org.elasticsearch.action.support.HandledTransportAction; | ||
import org.elasticsearch.cluster.coordination.CoordinationDiagnosticsService; | ||
import org.elasticsearch.common.inject.Inject; | ||
import org.elasticsearch.common.io.stream.StreamInput; | ||
import org.elasticsearch.common.io.stream.StreamOutput; | ||
import org.elasticsearch.tasks.Task; | ||
import org.elasticsearch.transport.TransportService; | ||
|
||
import java.io.IOException; | ||
import java.util.Objects; | ||
|
||
import static org.elasticsearch.cluster.coordination.CoordinationDiagnosticsService.CoordinationDiagnosticsResult; | ||
|
||
/** | ||
* This action exposes CoordinationDiagnosticsService#diagnoseMasterStability so that a node can get a remote node's view of | ||
* coordination diagnostics (including master stability). | ||
*/ | ||
public class CoordinationDiagnosticsAction extends ActionType<CoordinationDiagnosticsAction.Response> { | ||
|
||
public static final CoordinationDiagnosticsAction INSTANCE = new CoordinationDiagnosticsAction(); | ||
public static final String NAME = "cluster:internal/coordination_diagnostics/info"; | ||
|
||
private CoordinationDiagnosticsAction() { | ||
super(NAME, CoordinationDiagnosticsAction.Response::new); | ||
} | ||
|
||
public static class Request extends ActionRequest { | ||
final boolean explain; // Non-private for testing | ||
|
||
public Request(boolean explain) { | ||
this.explain = explain; | ||
} | ||
|
||
@Override | ||
public ActionRequestValidationException validate() { | ||
return null; | ||
} | ||
|
||
public Request(StreamInput in) throws IOException { | ||
super(in); | ||
this.explain = in.readBoolean(); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
super.writeTo(out); | ||
out.writeBoolean(explain); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
return explain == ((Request) o).explain; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hashCode(explain); | ||
} | ||
|
||
} | ||
|
||
public static class Response extends ActionResponse { | ||
|
||
private final CoordinationDiagnosticsResult result; | ||
|
||
public Response(StreamInput in) throws IOException { | ||
super(in); | ||
result = new CoordinationDiagnosticsResult(in); | ||
} | ||
|
||
public Response(CoordinationDiagnosticsResult result) { | ||
this.result = result; | ||
} | ||
|
||
public CoordinationDiagnosticsResult getCoordinationDiagnosticsResult() { | ||
return result; | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
result.writeTo(out); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
CoordinationDiagnosticsAction.Response response = (CoordinationDiagnosticsAction.Response) o; | ||
return result.equals(response.result); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(result); | ||
} | ||
} | ||
|
||
/** | ||
* This transport action calls CoordinationDiagnosticsService#diagnoseMasterStability | ||
*/ | ||
public static class TransportAction extends HandledTransportAction<Request, Response> { | ||
private final CoordinationDiagnosticsService coordinationDiagnosticsService; | ||
|
||
@Inject | ||
public TransportAction( | ||
TransportService transportService, | ||
ActionFilters actionFilters, | ||
CoordinationDiagnosticsService coordinationDiagnosticsService | ||
) { | ||
super(CoordinationDiagnosticsAction.NAME, transportService, actionFilters, CoordinationDiagnosticsAction.Request::new); | ||
this.coordinationDiagnosticsService = coordinationDiagnosticsService; | ||
} | ||
|
||
@Override | ||
protected void doExecute(Task task, CoordinationDiagnosticsAction.Request request, ActionListener<Response> listener) { | ||
listener.onResponse(new Response(coordinationDiagnosticsService.diagnoseMasterStability(request.explain))); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...g/elasticsearch/action/admin/cluster/coordination/CoordinationDiagnosticsActionTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.action.admin.cluster.coordination; | ||
|
||
import org.elasticsearch.Version; | ||
import org.elasticsearch.cluster.node.DiscoveryNode; | ||
import org.elasticsearch.cluster.node.DiscoveryNodeRole; | ||
import org.elasticsearch.test.ESTestCase; | ||
import org.elasticsearch.test.EqualsHashCodeTestUtils; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
import static org.elasticsearch.cluster.coordination.CoordinationDiagnosticsService.CoordinationDiagnosticsDetails; | ||
import static org.elasticsearch.cluster.coordination.CoordinationDiagnosticsService.CoordinationDiagnosticsResult; | ||
import static org.elasticsearch.cluster.coordination.CoordinationDiagnosticsService.CoordinationDiagnosticsStatus; | ||
|
||
public class CoordinationDiagnosticsActionTests extends ESTestCase { | ||
|
||
public void testSerialization() { | ||
DiscoveryNode node1 = new DiscoveryNode( | ||
"node1", | ||
UUID.randomUUID().toString(), | ||
buildNewFakeTransportAddress(), | ||
Collections.emptyMap(), | ||
DiscoveryNodeRole.roles(), | ||
Version.CURRENT | ||
); | ||
DiscoveryNode node2 = new DiscoveryNode( | ||
"node2", | ||
UUID.randomUUID().toString(), | ||
buildNewFakeTransportAddress(), | ||
Collections.emptyMap(), | ||
DiscoveryNodeRole.roles(), | ||
Version.CURRENT | ||
); | ||
CoordinationDiagnosticsDetails details = new CoordinationDiagnosticsDetails( | ||
node1, | ||
List.of(node1, node2), | ||
randomAlphaOfLengthBetween(0, 30), | ||
randomAlphaOfLengthBetween(0, 30), | ||
randomAlphaOfLengthBetween(0, 30) | ||
); | ||
CoordinationDiagnosticsResult result = new CoordinationDiagnosticsResult( | ||
randomFrom(CoordinationDiagnosticsStatus.values()), | ||
randomAlphaOfLength(100), | ||
details | ||
); | ||
CoordinationDiagnosticsAction.Response response = new CoordinationDiagnosticsAction.Response(result); | ||
EqualsHashCodeTestUtils.checkEqualsAndHashCode( | ||
response, | ||
history -> copyWriteable(history, writableRegistry(), CoordinationDiagnosticsAction.Response::new), | ||
this::mutateResponse | ||
); | ||
|
||
CoordinationDiagnosticsAction.Request request = new CoordinationDiagnosticsAction.Request(randomBoolean()); | ||
EqualsHashCodeTestUtils.checkEqualsAndHashCode( | ||
request, | ||
history -> copyWriteable(history, writableRegistry(), CoordinationDiagnosticsAction.Request::new), | ||
this::mutateRequest | ||
); | ||
} | ||
|
||
private CoordinationDiagnosticsAction.Request mutateRequest(CoordinationDiagnosticsAction.Request originalRequest) { | ||
return new CoordinationDiagnosticsAction.Request(originalRequest.explain == false); | ||
} | ||
|
||
private CoordinationDiagnosticsAction.Response mutateResponse(CoordinationDiagnosticsAction.Response originalResponse) { | ||
CoordinationDiagnosticsResult originalResult = originalResponse.getCoordinationDiagnosticsResult(); | ||
return new CoordinationDiagnosticsAction.Response( | ||
new CoordinationDiagnosticsResult(originalResult.status(), randomAlphaOfLength(100), originalResult.details()) | ||
); | ||
} | ||
} |
Oops, something went wrong.