Zen2: Rename tombstones to exclusions (#36226)

Renames the withdrawal / tombstones APIs to voting configuration exclusions.
This commit is contained in:
Yannick Welsch 2018-12-05 23:12:28 +01:00 committed by GitHub
parent 5d6602120f
commit 03d0ea91ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 412 additions and 398 deletions

View File

@ -91,7 +91,8 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
public void doAfterNodes(int n, Client client) throws IOException { public void doAfterNodes(int n, Client client) throws IOException {
ensureGreen("test"); ensureGreen("test");
Response response = Response response =
restClient.performRequest(new Request("POST", "/_cluster/withdrawn_votes/" + internalCluster().getNodeNames()[n])); restClient.performRequest(new Request("POST", "/_cluster/voting_config_exclusions/" +
internalCluster().getNodeNames()[n]));
assertThat(response.getStatusLine().getStatusCode(), is(200)); assertThat(response.getStatusLine().getStatusCode(), is(200));
} }
@ -111,7 +112,7 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
) )
) )
); );
Response deleteResponse = restClient.performRequest(new Request("DELETE", "/_cluster/withdrawn_votes")); Response deleteResponse = restClient.performRequest(new Request("DELETE", "/_cluster/voting_config_exclusions"));
assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200)); assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200));
ClusterHealthResponse clusterHealthResponse = client(viaNode).admin().cluster().prepareHealth() ClusterHealthResponse clusterHealthResponse = client(viaNode).admin().cluster().prepareHealth()
@ -135,10 +136,11 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
public void testClearVotingTombstonesNotWaitingForRemoval() throws Exception { public void testClearVotingTombstonesNotWaitingForRemoval() throws Exception {
List<String> nodes = internalCluster().startNodes(3); List<String> nodes = internalCluster().startNodes(3);
RestClient restClient = getRestClient(); RestClient restClient = getRestClient();
Response response = restClient.performRequest(new Request("POST", "/_cluster/withdrawn_votes/" + nodes.get(2))); Response response = restClient.performRequest(new Request("POST", "/_cluster/voting_config_exclusions/" + nodes.get(2)));
assertThat(response.getStatusLine().getStatusCode(), is(200)); assertThat(response.getStatusLine().getStatusCode(), is(200));
assertThat(response.getEntity().getContentLength(), is(0L)); assertThat(response.getEntity().getContentLength(), is(0L));
Response deleteResponse = restClient.performRequest(new Request("DELETE", "/_cluster/withdrawn_votes/?wait_for_removal=false")); Response deleteResponse = restClient.performRequest(
new Request("DELETE", "/_cluster/voting_config_exclusions/?wait_for_removal=false"));
assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200)); assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200));
assertThat(deleteResponse.getEntity().getContentLength(), is(0L)); assertThat(deleteResponse.getEntity().getContentLength(), is(0L));
} }
@ -147,11 +149,11 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
List<String> nodes = internalCluster().startNodes(3); List<String> nodes = internalCluster().startNodes(3);
RestClient restClient = getRestClient(); RestClient restClient = getRestClient();
String nodeToWithdraw = nodes.get(randomIntBetween(0, 2)); String nodeToWithdraw = nodes.get(randomIntBetween(0, 2));
Response response = restClient.performRequest(new Request("POST", "/_cluster/withdrawn_votes/" + nodeToWithdraw)); Response response = restClient.performRequest(new Request("POST", "/_cluster/voting_config_exclusions/" + nodeToWithdraw));
assertThat(response.getStatusLine().getStatusCode(), is(200)); assertThat(response.getStatusLine().getStatusCode(), is(200));
assertThat(response.getEntity().getContentLength(), is(0L)); assertThat(response.getEntity().getContentLength(), is(0L));
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(nodeToWithdraw)); internalCluster().stopRandomNode(InternalTestCluster.nameFilter(nodeToWithdraw));
Response deleteResponse = restClient.performRequest(new Request("DELETE", "/_cluster/withdrawn_votes")); Response deleteResponse = restClient.performRequest(new Request("DELETE", "/_cluster/voting_config_exclusions"));
assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200)); assertThat(deleteResponse.getStatusLine().getStatusCode(), is(200));
assertThat(deleteResponse.getEntity().getContentLength(), is(0L)); assertThat(deleteResponse.getEntity().getContentLength(), is(0L));
} }
@ -160,13 +162,13 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
internalCluster().startNodes(3); internalCluster().startNodes(3);
RestClient restClient = getRestClient(); RestClient restClient = getRestClient();
try { try {
restClient.performRequest(new Request("POST", "/_cluster/withdrawn_votes/invalid")); restClient.performRequest(new Request("POST", "/_cluster/voting_config_exclusions/invalid"));
fail("Invalid node name should throw."); fail("Invalid node name should throw.");
} catch (ResponseException e) { } catch (ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(400)); assertThat(e.getResponse().getStatusLine().getStatusCode(), is(400));
assertThat( assertThat(
e.getCause().getMessage(), e.getCause().getMessage(),
Matchers.containsString("add voting tombstones request for [invalid] matched no master-eligible nodes") Matchers.containsString("add voting config exclusions request for [invalid] matched no master-eligible nodes")
); );
} }
} }

View File

@ -27,10 +27,10 @@ import org.elasticsearch.action.admin.cluster.bootstrap.BootstrapClusterAction;
import org.elasticsearch.action.admin.cluster.bootstrap.GetDiscoveredNodesAction; import org.elasticsearch.action.admin.cluster.bootstrap.GetDiscoveredNodesAction;
import org.elasticsearch.action.admin.cluster.bootstrap.TransportBootstrapClusterAction; import org.elasticsearch.action.admin.cluster.bootstrap.TransportBootstrapClusterAction;
import org.elasticsearch.action.admin.cluster.bootstrap.TransportGetDiscoveredNodesAction; import org.elasticsearch.action.admin.cluster.bootstrap.TransportGetDiscoveredNodesAction;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.configuration.TransportClearVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.TransportClearVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction;
import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction; import org.elasticsearch.action.admin.cluster.health.TransportClusterHealthAction;
import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsAction; import org.elasticsearch.action.admin.cluster.node.hotthreads.NodesHotThreadsAction;
@ -225,7 +225,7 @@ import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.action.RestFieldCapabilitiesAction; import org.elasticsearch.rest.action.RestFieldCapabilitiesAction;
import org.elasticsearch.rest.action.RestMainAction; import org.elasticsearch.rest.action.RestMainAction;
import org.elasticsearch.rest.action.admin.cluster.RestCancelTasksAction; import org.elasticsearch.rest.action.admin.cluster.RestCancelTasksAction;
import org.elasticsearch.rest.action.admin.cluster.RestClearVotingTombstonesAction; import org.elasticsearch.rest.action.admin.cluster.RestClearVotingConfigExclusionsAction;
import org.elasticsearch.rest.action.admin.cluster.RestClusterAllocationExplainAction; import org.elasticsearch.rest.action.admin.cluster.RestClusterAllocationExplainAction;
import org.elasticsearch.rest.action.admin.cluster.RestClusterGetSettingsAction; import org.elasticsearch.rest.action.admin.cluster.RestClusterGetSettingsAction;
import org.elasticsearch.rest.action.admin.cluster.RestClusterHealthAction; import org.elasticsearch.rest.action.admin.cluster.RestClusterHealthAction;
@ -255,7 +255,7 @@ import org.elasticsearch.rest.action.admin.cluster.RestRemoteClusterInfoAction;
import org.elasticsearch.rest.action.admin.cluster.RestRestoreSnapshotAction; import org.elasticsearch.rest.action.admin.cluster.RestRestoreSnapshotAction;
import org.elasticsearch.rest.action.admin.cluster.RestSnapshotsStatusAction; import org.elasticsearch.rest.action.admin.cluster.RestSnapshotsStatusAction;
import org.elasticsearch.rest.action.admin.cluster.RestVerifyRepositoryAction; import org.elasticsearch.rest.action.admin.cluster.RestVerifyRepositoryAction;
import org.elasticsearch.rest.action.admin.cluster.RestAddVotingTombstonesAction; import org.elasticsearch.rest.action.admin.cluster.RestAddVotingConfigExclusionAction;
import org.elasticsearch.rest.action.admin.indices.RestAnalyzeAction; import org.elasticsearch.rest.action.admin.indices.RestAnalyzeAction;
import org.elasticsearch.rest.action.admin.indices.RestClearIndicesCacheAction; import org.elasticsearch.rest.action.admin.indices.RestClearIndicesCacheAction;
import org.elasticsearch.rest.action.admin.indices.RestCloseIndexAction; import org.elasticsearch.rest.action.admin.indices.RestCloseIndexAction;
@ -435,8 +435,8 @@ public class ActionModule extends AbstractModule {
actions.register(GetDiscoveredNodesAction.INSTANCE, TransportGetDiscoveredNodesAction.class); actions.register(GetDiscoveredNodesAction.INSTANCE, TransportGetDiscoveredNodesAction.class);
actions.register(BootstrapClusterAction.INSTANCE, TransportBootstrapClusterAction.class); actions.register(BootstrapClusterAction.INSTANCE, TransportBootstrapClusterAction.class);
actions.register(AddVotingTombstonesAction.INSTANCE, TransportAddVotingTombstonesAction.class); actions.register(AddVotingConfigExclusionsAction.INSTANCE, TransportAddVotingConfigExclusionsAction.class);
actions.register(ClearVotingTombstonesAction.INSTANCE, TransportClearVotingTombstonesAction.class); actions.register(ClearVotingConfigExclusionsAction.INSTANCE, TransportClearVotingConfigExclusionsAction.class);
actions.register(ClusterAllocationExplainAction.INSTANCE, TransportClusterAllocationExplainAction.class); actions.register(ClusterAllocationExplainAction.INSTANCE, TransportClusterAllocationExplainAction.class);
actions.register(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class); actions.register(ClusterStatsAction.INSTANCE, TransportClusterStatsAction.class);
actions.register(ClusterStateAction.INSTANCE, TransportClusterStateAction.class); actions.register(ClusterStateAction.INSTANCE, TransportClusterStateAction.class);
@ -545,8 +545,8 @@ public class ActionModule extends AbstractModule {
catActions.add((AbstractCatAction) a); catActions.add((AbstractCatAction) a);
} }
}; };
registerHandler.accept(new RestAddVotingTombstonesAction(settings, restController)); registerHandler.accept(new RestAddVotingConfigExclusionAction(settings, restController));
registerHandler.accept(new RestClearVotingTombstonesAction(settings, restController)); registerHandler.accept(new RestClearVotingConfigExclusionsAction(settings, restController));
registerHandler.accept(new RestMainAction(settings, restController)); registerHandler.accept(new RestMainAction(settings, restController));
registerHandler.accept(new RestNodesInfoAction(settings, restController, settingsFilter)); registerHandler.accept(new RestNodesInfoAction(settings, restController, settingsFilter));
registerHandler.accept(new RestRemoteClusterInfoAction(settings, restController)); registerHandler.accept(new RestRemoteClusterInfoAction(settings, restController));

View File

@ -21,21 +21,21 @@ package org.elasticsearch.action.admin.cluster.configuration;
import org.elasticsearch.action.Action; import org.elasticsearch.action.Action;
import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.common.io.stream.Writeable.Reader;
public class AddVotingTombstonesAction extends Action<AddVotingTombstonesResponse> { public class AddVotingConfigExclusionsAction extends Action<AddVotingConfigExclusionsResponse> {
public static final AddVotingTombstonesAction INSTANCE = new AddVotingTombstonesAction(); public static final AddVotingConfigExclusionsAction INSTANCE = new AddVotingConfigExclusionsAction();
public static final String NAME = "cluster:admin/voting/add_tombstones"; public static final String NAME = "cluster:admin/voting_config/add_exclusions";
private AddVotingTombstonesAction() { private AddVotingConfigExclusionsAction() {
super(NAME); super(NAME);
} }
@Override @Override
public AddVotingTombstonesResponse newResponse() { public AddVotingConfigExclusionsResponse newResponse() {
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
} }
@Override @Override
public Reader<AddVotingTombstonesResponse> getResponseReader() { public Reader<AddVotingConfigExclusionsResponse> getResponseReader() {
return AddVotingTombstonesResponse::new; return AddVotingConfigExclusionsResponse::new;
} }
} }

View File

@ -21,7 +21,7 @@ package org.elasticsearch.action.admin.cluster.configuration;
import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.master.MasterNodeRequest; import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
@ -34,29 +34,29 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* A request to add voting tombstones for certain master-eligible nodes, and wait for these nodes to be removed from the voting * A request to add voting config exclusions for certain master-eligible nodes, and wait for these nodes to be removed from the voting
* configuration. * configuration.
*/ */
public class AddVotingTombstonesRequest extends MasterNodeRequest<AddVotingTombstonesRequest> { public class AddVotingConfigExclusionsRequest extends MasterNodeRequest<AddVotingConfigExclusionsRequest> {
private final String[] nodeDescriptions; private final String[] nodeDescriptions;
private final TimeValue timeout; private final TimeValue timeout;
/** /**
* Construct a request to add voting tombstones for master-eligible nodes matching the given descriptions, and wait for a default 30 * Construct a request to add voting config exclusions for master-eligible nodes matching the given descriptions, and wait for a
* seconds for these nodes to be removed from the voting configuration. * default 30 seconds for these exclusions to take effect, removing the nodes from the voting configuration.
* @param nodeDescriptions Descriptions of the nodes to add - see {@link DiscoveryNodes#resolveNodes(String...)} * @param nodeDescriptions Descriptions of the nodes to add - see {@link DiscoveryNodes#resolveNodes(String...)}
*/ */
public AddVotingTombstonesRequest(String[] nodeDescriptions) { public AddVotingConfigExclusionsRequest(String[] nodeDescriptions) {
this(nodeDescriptions, TimeValue.timeValueSeconds(30)); this(nodeDescriptions, TimeValue.timeValueSeconds(30));
} }
/** /**
* Construct a request to add voting tombstones for master-eligible nodes matching the given descriptions, and wait for these nodes to * Construct a request to add voting config exclusions for master-eligible nodes matching the given descriptions, and wait for these
* be removed from the voting configuration. * nodes to be removed from the voting configuration.
* @param nodeDescriptions Descriptions of the nodes whose tombstones to add - see {@link DiscoveryNodes#resolveNodes(String...)}. * @param nodeDescriptions Descriptions of the nodes whose exclusions to add - see {@link DiscoveryNodes#resolveNodes(String...)}.
* @param timeout How long to wait for the nodes to be removed from the voting configuration. * @param timeout How long to wait for the added exclusions to take effect and be removed from the voting configuration.
*/ */
public AddVotingTombstonesRequest(String[] nodeDescriptions, TimeValue timeout) { public AddVotingConfigExclusionsRequest(String[] nodeDescriptions, TimeValue timeout) {
if (timeout.compareTo(TimeValue.ZERO) < 0) { if (timeout.compareTo(TimeValue.ZERO) < 0) {
throw new IllegalArgumentException("timeout [" + timeout + "] must be non-negative"); throw new IllegalArgumentException("timeout [" + timeout + "] must be non-negative");
} }
@ -64,50 +64,50 @@ public class AddVotingTombstonesRequest extends MasterNodeRequest<AddVotingTombs
this.timeout = timeout; this.timeout = timeout;
} }
public AddVotingTombstonesRequest(StreamInput in) throws IOException { public AddVotingConfigExclusionsRequest(StreamInput in) throws IOException {
super(in); super(in);
nodeDescriptions = in.readStringArray(); nodeDescriptions = in.readStringArray();
timeout = in.readTimeValue(); timeout = in.readTimeValue();
} }
Set<VotingTombstone> resolveVotingTombstones(ClusterState currentState) { Set<VotingConfigExclusion> resolveVotingConfigExclusions(ClusterState currentState) {
final DiscoveryNodes allNodes = currentState.nodes(); final DiscoveryNodes allNodes = currentState.nodes();
final Set<VotingTombstone> resolvedNodes = Arrays.stream(allNodes.resolveNodes(nodeDescriptions)) final Set<VotingConfigExclusion> resolvedNodes = Arrays.stream(allNodes.resolveNodes(nodeDescriptions))
.map(allNodes::get).filter(DiscoveryNode::isMasterNode).map(VotingTombstone::new).collect(Collectors.toSet()); .map(allNodes::get).filter(DiscoveryNode::isMasterNode).map(VotingConfigExclusion::new).collect(Collectors.toSet());
if (resolvedNodes.isEmpty()) { if (resolvedNodes.isEmpty()) {
throw new IllegalArgumentException("add voting tombstones request for " + Arrays.asList(nodeDescriptions) throw new IllegalArgumentException("add voting config exclusions request for " + Arrays.asList(nodeDescriptions)
+ " matched no master-eligible nodes"); + " matched no master-eligible nodes");
} }
resolvedNodes.removeIf(n -> currentState.getVotingTombstones().contains(n)); resolvedNodes.removeIf(n -> currentState.getVotingConfigExclusions().contains(n));
return resolvedNodes; return resolvedNodes;
} }
Set<VotingTombstone> resolveVotingTombstonesAndCheckMaximum(ClusterState currentState, int maxTombstoneCount, Set<VotingConfigExclusion> resolveVotingConfigExclusionsAndCheckMaximum(ClusterState currentState, int maxExclusionsCount,
String maximumSettingKey) { String maximumSettingKey) {
final Set<VotingTombstone> resolvedNodes = resolveVotingTombstones(currentState); final Set<VotingConfigExclusion> resolvedExclusions = resolveVotingConfigExclusions(currentState);
final int oldTombstoneCount = currentState.getVotingTombstones().size(); final int oldExclusionsCount = currentState.getVotingConfigExclusions().size();
final int newTombstoneCount = resolvedNodes.size(); final int newExclusionsCount = resolvedExclusions.size();
if (oldTombstoneCount + newTombstoneCount > maxTombstoneCount) { if (oldExclusionsCount + newExclusionsCount > maxExclusionsCount) {
throw new IllegalArgumentException("add voting tombstones request for " + Arrays.asList(nodeDescriptions) throw new IllegalArgumentException("add voting config exclusions request for " + Arrays.asList(nodeDescriptions)
+ " would add [" + newTombstoneCount + "] voting tombstones to the existing [" + oldTombstoneCount + " would add [" + newExclusionsCount + "] exclusions to the existing [" + oldExclusionsCount
+ "] which would exceed the maximum of [" + maxTombstoneCount + "] set by [" + "] which would exceed the maximum of [" + maxExclusionsCount + "] set by ["
+ maximumSettingKey + "]"); + maximumSettingKey + "]");
} }
return resolvedNodes; return resolvedExclusions;
} }
/** /**
* @return descriptions of the nodes for whom to add tombstones. * @return descriptions of the nodes for whom to add voting config exclusions.
*/ */
public String[] getNodeDescriptions() { public String[] getNodeDescriptions() {
return nodeDescriptions; return nodeDescriptions;
} }
/** /**
* @return how long to wait after adding the tombstones for the nodes to be removed from the voting configuration. * @return how long to wait after adding the exclusions for the nodes to be removed from the voting configuration.
*/ */
public TimeValue getTimeout() { public TimeValue getTimeout() {
return timeout; return timeout;
@ -132,7 +132,7 @@ public class AddVotingTombstonesRequest extends MasterNodeRequest<AddVotingTombs
@Override @Override
public String toString() { public String toString() {
return "AddVotingTombstonesRequest{" + return "AddVotingConfigExclusionsRequest{" +
"nodeDescriptions=" + Arrays.asList(nodeDescriptions) + "nodeDescriptions=" + Arrays.asList(nodeDescriptions) +
", timeout=" + timeout + ", timeout=" + timeout +
'}'; '}';

View File

@ -27,15 +27,15 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException; import java.io.IOException;
/** /**
* A response to {@link AddVotingTombstonesRequest} indicating that voting tombstones have been added for the requested nodes and these * A response to {@link AddVotingConfigExclusionsRequest} indicating that voting config exclusions have been added for the requested nodes
* nodes have been removed from the voting configuration. * and these nodes have been removed from the voting configuration.
*/ */
public class AddVotingTombstonesResponse extends ActionResponse implements ToXContentObject { public class AddVotingConfigExclusionsResponse extends ActionResponse implements ToXContentObject {
public AddVotingTombstonesResponse() { public AddVotingConfigExclusionsResponse() {
} }
public AddVotingTombstonesResponse(StreamInput in) throws IOException { public AddVotingConfigExclusionsResponse(StreamInput in) throws IOException {
super(in); super(in);
} }

View File

@ -21,21 +21,21 @@ package org.elasticsearch.action.admin.cluster.configuration;
import org.elasticsearch.action.Action; import org.elasticsearch.action.Action;
import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.common.io.stream.Writeable.Reader;
public class ClearVotingTombstonesAction extends Action<ClearVotingTombstonesResponse> { public class ClearVotingConfigExclusionsAction extends Action<ClearVotingConfigExclusionsResponse> {
public static final ClearVotingTombstonesAction INSTANCE = new ClearVotingTombstonesAction(); public static final ClearVotingConfigExclusionsAction INSTANCE = new ClearVotingConfigExclusionsAction();
public static final String NAME = "cluster:admin/voting/clear_tombstones"; public static final String NAME = "cluster:admin/voting_config/clear_exclusions";
private ClearVotingTombstonesAction() { private ClearVotingConfigExclusionsAction() {
super(NAME); super(NAME);
} }
@Override @Override
public ClearVotingTombstonesResponse newResponse() { public ClearVotingConfigExclusionsResponse newResponse() {
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
} }
@Override @Override
public Reader<ClearVotingTombstonesResponse> getResponseReader() { public Reader<ClearVotingConfigExclusionsResponse> getResponseReader() {
return ClearVotingTombstonesResponse::new; return ClearVotingConfigExclusionsResponse::new;
} }
} }

View File

@ -27,41 +27,43 @@ import org.elasticsearch.common.unit.TimeValue;
import java.io.IOException; import java.io.IOException;
/** /**
* A request to clear the voting tombstones from the cluster state, optionally waiting for these nodes to be removed from the cluster first. * A request to clear the voting config exclusions from the cluster state, optionally waiting for these nodes to be removed from the
* cluster first.
*/ */
public class ClearVotingTombstonesRequest extends MasterNodeRequest<ClearVotingTombstonesRequest> { public class ClearVotingConfigExclusionsRequest extends MasterNodeRequest<ClearVotingConfigExclusionsRequest> {
private boolean waitForRemoval = true; private boolean waitForRemoval = true;
private TimeValue timeout = TimeValue.timeValueSeconds(30); private TimeValue timeout = TimeValue.timeValueSeconds(30);
/** /**
* Construct a request to remove all the voting tombstones from the cluster state. * Construct a request to remove all the voting config exclusions from the cluster state.
*/ */
public ClearVotingTombstonesRequest() { public ClearVotingConfigExclusionsRequest() {
} }
public ClearVotingTombstonesRequest(StreamInput in) throws IOException { public ClearVotingConfigExclusionsRequest(StreamInput in) throws IOException {
super(in); super(in);
waitForRemoval = in.readBoolean(); waitForRemoval = in.readBoolean();
timeout = in.readTimeValue(); timeout = in.readTimeValue();
} }
/** /**
* @return whether to wait for the tombstoned nodes to be removed from the cluster before removing their tombstones. True by default. * @return whether to wait for the currently excluded nodes to be removed from the cluster before removing their exclusions.
* True by default.
*/ */
public boolean getWaitForRemoval() { public boolean getWaitForRemoval() {
return waitForRemoval; return waitForRemoval;
} }
/** /**
* @param waitForRemoval whether to wait for the tombstoned nodes to be removed from the cluster before removing their tombstones. True * @param waitForRemoval whether to wait for the currently excluded nodes to be removed from the cluster before removing their
* by default. * exclusions. True by default.
*/ */
public void setWaitForRemoval(boolean waitForRemoval) { public void setWaitForRemoval(boolean waitForRemoval) {
this.waitForRemoval = waitForRemoval; this.waitForRemoval = waitForRemoval;
} }
/** /**
* @param timeout how long to wait for the tombstoned nodes to be removed if {@link ClearVotingTombstonesRequest#waitForRemoval} is * @param timeout how long to wait for the excluded nodes to be removed if {@link ClearVotingConfigExclusionsRequest#waitForRemoval} is
* true. Defaults to 30 seconds. * true. Defaults to 30 seconds.
*/ */
public void setTimeout(TimeValue timeout) { public void setTimeout(TimeValue timeout) {
@ -69,7 +71,7 @@ public class ClearVotingTombstonesRequest extends MasterNodeRequest<ClearVotingT
} }
/** /**
* @return how long to wait for the tombstoned nodes to be removed if {@link ClearVotingTombstonesRequest#waitForRemoval} is * @return how long to wait for the excluded nodes to be removed if {@link ClearVotingConfigExclusionsRequest#waitForRemoval} is
* true. Defaults to 30 seconds. * true. Defaults to 30 seconds.
*/ */
public TimeValue getTimeout() { public TimeValue getTimeout() {
@ -95,7 +97,7 @@ public class ClearVotingTombstonesRequest extends MasterNodeRequest<ClearVotingT
@Override @Override
public String toString() { public String toString() {
return "ClearVotingTombstonesRequest{" + return "ClearVotingConfigExclusionsRequest{" +
", waitForRemoval=" + waitForRemoval + ", waitForRemoval=" + waitForRemoval +
", timeout=" + timeout + ", timeout=" + timeout +
'}'; '}';

View File

@ -27,13 +27,14 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException; import java.io.IOException;
/** /**
* A response to {@link ClearVotingTombstonesRequest} indicating that voting tombstones have been cleared from the cluster state. * A response to {@link ClearVotingConfigExclusionsRequest} indicating that voting config exclusions have been cleared from the
* cluster state.
*/ */
public class ClearVotingTombstonesResponse extends ActionResponse implements ToXContentObject { public class ClearVotingConfigExclusionsResponse extends ActionResponse implements ToXContentObject {
public ClearVotingTombstonesResponse() { public ClearVotingConfigExclusionsResponse() {
} }
public ClearVotingTombstonesResponse(StreamInput in) throws IOException { public ClearVotingConfigExclusionsResponse(StreamInput in) throws IOException {
super(in); super(in);
} }

View File

@ -30,7 +30,7 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
@ -49,16 +49,17 @@ import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class TransportAddVotingTombstonesAction extends TransportMasterNodeAction<AddVotingTombstonesRequest, AddVotingTombstonesResponse> { public class TransportAddVotingConfigExclusionsAction extends TransportMasterNodeAction<AddVotingConfigExclusionsRequest,
AddVotingConfigExclusionsResponse> {
public static final Setting<Integer> MAXIMUM_VOTING_TOMBSTONES_SETTING public static final Setting<Integer> MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING
= Setting.intSetting("cluster.max_voting_tombstones", 10, 1, Property.Dynamic, Property.NodeScope); = Setting.intSetting("cluster.max_voting_config_exclusions", 10, 1, Property.Dynamic, Property.NodeScope);
@Inject @Inject
public TransportAddVotingTombstonesAction(TransportService transportService, ClusterService clusterService, ThreadPool threadPool, public TransportAddVotingConfigExclusionsAction(TransportService transportService, ClusterService clusterService, ThreadPool threadPool,
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
super(AddVotingTombstonesAction.NAME, transportService, clusterService, threadPool, actionFilters, AddVotingTombstonesRequest::new, super(AddVotingConfigExclusionsAction.NAME, transportService, clusterService, threadPool, actionFilters,
indexNameExpressionResolver); AddVotingConfigExclusionsRequest::new, indexNameExpressionResolver);
} }
@Override @Override
@ -67,35 +68,36 @@ public class TransportAddVotingTombstonesAction extends TransportMasterNodeActio
} }
@Override @Override
protected AddVotingTombstonesResponse newResponse() { protected AddVotingConfigExclusionsResponse newResponse() {
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
} }
@Override @Override
protected AddVotingTombstonesResponse read(StreamInput in) throws IOException { protected AddVotingConfigExclusionsResponse read(StreamInput in) throws IOException {
return new AddVotingTombstonesResponse(in); return new AddVotingConfigExclusionsResponse(in);
} }
@Override @Override
protected void masterOperation(AddVotingTombstonesRequest request, ClusterState state, protected void masterOperation(AddVotingConfigExclusionsRequest request, ClusterState state,
ActionListener<AddVotingTombstonesResponse> listener) throws Exception { ActionListener<AddVotingConfigExclusionsResponse> listener) throws Exception {
resolveVotingTombstonesAndCheckMaximum(request, state); // throws IllegalArgumentException if no nodes matched or maximum exceeded resolveVotingConfigExclusionsAndCheckMaximum(request, state); // throws IAE if no nodes matched or maximum exceeded
clusterService.submitStateUpdateTask("add-voting-tombstones", new ClusterStateUpdateTask(Priority.URGENT) { clusterService.submitStateUpdateTask("add-voting-config-exclusions", new ClusterStateUpdateTask(Priority.URGENT) {
private Set<VotingTombstone> resolvedNodes; private Set<VotingConfigExclusion> resolvedExclusions;
@Override @Override
public ClusterState execute(ClusterState currentState) { public ClusterState execute(ClusterState currentState) {
assert resolvedNodes == null : resolvedNodes; assert resolvedExclusions == null : resolvedExclusions;
resolvedNodes = resolveVotingTombstonesAndCheckMaximum(request, currentState); resolvedExclusions = resolveVotingConfigExclusionsAndCheckMaximum(request, currentState);
final CoordinationMetaData.Builder builder = CoordinationMetaData.builder(currentState.coordinationMetaData()); final CoordinationMetaData.Builder builder = CoordinationMetaData.builder(currentState.coordinationMetaData());
resolvedNodes.forEach(builder::addVotingTombstone); resolvedExclusions.forEach(builder::addVotingConfigExclusion);
final MetaData newMetaData = MetaData.builder(currentState.metaData()).coordinationMetaData(builder.build()).build(); final MetaData newMetaData = MetaData.builder(currentState.metaData()).coordinationMetaData(builder.build()).build();
final ClusterState newState = ClusterState.builder(currentState).metaData(newMetaData).build(); final ClusterState newState = ClusterState.builder(currentState).metaData(newMetaData).build();
assert newState.getVotingTombstones().size() <= MAXIMUM_VOTING_TOMBSTONES_SETTING.get(currentState.metaData().settings()); assert newState.getVotingConfigExclusions().size() <= MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING.get(
currentState.metaData().settings());
return newState; return newState;
} }
@ -110,29 +112,30 @@ public class TransportAddVotingTombstonesAction extends TransportMasterNodeActio
final ClusterStateObserver observer final ClusterStateObserver observer
= new ClusterStateObserver(clusterService, request.getTimeout(), logger, threadPool.getThreadContext()); = new ClusterStateObserver(clusterService, request.getTimeout(), logger, threadPool.getThreadContext());
final Set<String> resolvedNodeIds = resolvedNodes.stream().map(VotingTombstone::getNodeId).collect(Collectors.toSet()); final Set<String> excludedNodeIds = resolvedExclusions.stream().map(VotingConfigExclusion::getNodeId)
.collect(Collectors.toSet());
final Predicate<ClusterState> allNodesRemoved = clusterState -> { final Predicate<ClusterState> allNodesRemoved = clusterState -> {
final Set<String> votingNodeIds = clusterState.getLastCommittedConfiguration().getNodeIds(); final Set<String> votingConfigNodeIds = clusterState.getLastCommittedConfiguration().getNodeIds();
return resolvedNodeIds.stream().noneMatch(votingNodeIds::contains); return excludedNodeIds.stream().noneMatch(votingConfigNodeIds::contains);
}; };
final Listener clusterStateListener = new Listener() { final Listener clusterStateListener = new Listener() {
@Override @Override
public void onNewClusterState(ClusterState state) { public void onNewClusterState(ClusterState state) {
listener.onResponse(new AddVotingTombstonesResponse()); listener.onResponse(new AddVotingConfigExclusionsResponse());
} }
@Override @Override
public void onClusterServiceClose() { public void onClusterServiceClose() {
listener.onFailure(new ElasticsearchException("cluster service closed while waiting for withdrawal of votes from " listener.onFailure(new ElasticsearchException("cluster service closed while waiting for voting config exclusions " +
+ resolvedNodes)); resolvedExclusions + " to take effect"));
} }
@Override @Override
public void onTimeout(TimeValue timeout) { public void onTimeout(TimeValue timeout) {
listener.onFailure(new ElasticsearchTimeoutException("timed out waiting for withdrawal of votes from " listener.onFailure(new ElasticsearchTimeoutException("timed out waiting for voting config exclusions "
+ resolvedNodes)); + resolvedExclusions + " to take effect"));
} }
}; };
@ -145,13 +148,14 @@ public class TransportAddVotingTombstonesAction extends TransportMasterNodeActio
}); });
} }
private static Set<VotingTombstone> resolveVotingTombstonesAndCheckMaximum(AddVotingTombstonesRequest request, ClusterState state) { private static Set<VotingConfigExclusion> resolveVotingConfigExclusionsAndCheckMaximum(AddVotingConfigExclusionsRequest request,
return request.resolveVotingTombstonesAndCheckMaximum(state, ClusterState state) {
MAXIMUM_VOTING_TOMBSTONES_SETTING.get(state.metaData().settings()), MAXIMUM_VOTING_TOMBSTONES_SETTING.getKey()); return request.resolveVotingConfigExclusionsAndCheckMaximum(state,
MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING.get(state.metaData().settings()), MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING.getKey());
} }
@Override @Override
protected ClusterBlockException checkBlock(AddVotingTombstonesRequest request, ClusterState state) { protected ClusterBlockException checkBlock(AddVotingConfigExclusionsRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
} }
} }

View File

@ -30,7 +30,7 @@ import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
@ -45,14 +45,15 @@ import org.elasticsearch.transport.TransportService;
import java.io.IOException; import java.io.IOException;
import java.util.function.Predicate; import java.util.function.Predicate;
public class TransportClearVotingTombstonesAction public class TransportClearVotingConfigExclusionsAction
extends TransportMasterNodeAction<ClearVotingTombstonesRequest, ClearVotingTombstonesResponse> { extends TransportMasterNodeAction<ClearVotingConfigExclusionsRequest, ClearVotingConfigExclusionsResponse> {
@Inject @Inject
public TransportClearVotingTombstonesAction(TransportService transportService, ClusterService clusterService, ThreadPool threadPool, public TransportClearVotingConfigExclusionsAction(TransportService transportService, ClusterService clusterService,
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { ThreadPool threadPool, ActionFilters actionFilters,
super(ClearVotingTombstonesAction.NAME, transportService, clusterService, threadPool, actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
ClearVotingTombstonesRequest::new, indexNameExpressionResolver); super(ClearVotingConfigExclusionsAction.NAME, transportService, clusterService, threadPool, actionFilters,
ClearVotingConfigExclusionsRequest::new, indexNameExpressionResolver);
} }
@Override @Override
@ -61,23 +62,23 @@ public class TransportClearVotingTombstonesAction
} }
@Override @Override
protected ClearVotingTombstonesResponse newResponse() { protected ClearVotingConfigExclusionsResponse newResponse() {
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
} }
@Override @Override
protected ClearVotingTombstonesResponse read(StreamInput in) throws IOException { protected ClearVotingConfigExclusionsResponse read(StreamInput in) throws IOException {
return new ClearVotingTombstonesResponse(in); return new ClearVotingConfigExclusionsResponse(in);
} }
@Override @Override
protected void masterOperation(ClearVotingTombstonesRequest request, ClusterState initialState, protected void masterOperation(ClearVotingConfigExclusionsRequest request, ClusterState initialState,
ActionListener<ClearVotingTombstonesResponse> listener) throws Exception { ActionListener<ClearVotingConfigExclusionsResponse> listener) throws Exception {
final long startTimeMillis = threadPool.relativeTimeInMillis(); final long startTimeMillis = threadPool.relativeTimeInMillis();
final Predicate<ClusterState> allTombstonedNodesRemoved = newState -> { final Predicate<ClusterState> allExclusionsRemoved = newState -> {
for (VotingTombstone tombstone : initialState.getVotingTombstones()) { for (VotingConfigExclusion tombstone : initialState.getVotingConfigExclusions()) {
// NB checking for the existence of any node with this persistent ID, because persistent IDs are how votes are counted. // NB checking for the existence of any node with this persistent ID, because persistent IDs are how votes are counted.
if (newState.nodes().nodeExists(tombstone.getNodeId())) { if (newState.nodes().nodeExists(tombstone.getNodeId())) {
return false; return false;
@ -86,41 +87,41 @@ public class TransportClearVotingTombstonesAction
return true; return true;
}; };
if (request.getWaitForRemoval() && allTombstonedNodesRemoved.test(initialState) == false) { if (request.getWaitForRemoval() && allExclusionsRemoved.test(initialState) == false) {
final ClusterStateObserver clusterStateObserver = new ClusterStateObserver(initialState, clusterService, request.getTimeout(), final ClusterStateObserver clusterStateObserver = new ClusterStateObserver(initialState, clusterService, request.getTimeout(),
logger, threadPool.getThreadContext()); logger, threadPool.getThreadContext());
clusterStateObserver.waitForNextChange(new Listener() { clusterStateObserver.waitForNextChange(new Listener() {
@Override @Override
public void onNewClusterState(ClusterState state) { public void onNewClusterState(ClusterState state) {
submitClearTombstonesTask(request, startTimeMillis, listener); submitClearVotingConfigExclusionsTask(request, startTimeMillis, listener);
} }
@Override @Override
public void onClusterServiceClose() { public void onClusterServiceClose() {
listener.onFailure(new ElasticsearchException("cluster service closed while waiting for removal of nodes " listener.onFailure(new ElasticsearchException("cluster service closed while waiting for removal of nodes "
+ initialState.getVotingTombstones())); + initialState.getVotingConfigExclusions()));
} }
@Override @Override
public void onTimeout(TimeValue timeout) { public void onTimeout(TimeValue timeout) {
listener.onFailure(new ElasticsearchTimeoutException( listener.onFailure(new ElasticsearchTimeoutException(
"timed out waiting for removal of nodes; if nodes should not be removed, set waitForRemoval to false. " "timed out waiting for removal of nodes; if nodes should not be removed, set waitForRemoval to false. "
+ initialState.getVotingTombstones())); + initialState.getVotingConfigExclusions()));
} }
}, allTombstonedNodesRemoved); }, allExclusionsRemoved);
} else { } else {
submitClearTombstonesTask(request, startTimeMillis, listener); submitClearVotingConfigExclusionsTask(request, startTimeMillis, listener);
} }
} }
private void submitClearTombstonesTask(ClearVotingTombstonesRequest request, long startTimeMillis, private void submitClearVotingConfigExclusionsTask(ClearVotingConfigExclusionsRequest request, long startTimeMillis,
ActionListener<ClearVotingTombstonesResponse> listener) { ActionListener<ClearVotingConfigExclusionsResponse> listener) {
clusterService.submitStateUpdateTask("clear-voting-tombstones", new ClusterStateUpdateTask(Priority.URGENT) { clusterService.submitStateUpdateTask("clear-voting-config-exclusions", new ClusterStateUpdateTask(Priority.URGENT) {
@Override @Override
public ClusterState execute(ClusterState currentState) { public ClusterState execute(ClusterState currentState) {
final CoordinationMetaData newCoordinationMetaData = final CoordinationMetaData newCoordinationMetaData =
CoordinationMetaData.builder(currentState.coordinationMetaData()).clearVotingTombstones().build(); CoordinationMetaData.builder(currentState.coordinationMetaData()).clearVotingConfigExclusions().build();
final MetaData newMetaData = MetaData.builder(currentState.metaData()). final MetaData newMetaData = MetaData.builder(currentState.metaData()).
coordinationMetaData(newCoordinationMetaData).build(); coordinationMetaData(newCoordinationMetaData).build();
return ClusterState.builder(currentState).metaData(newMetaData).build(); return ClusterState.builder(currentState).metaData(newMetaData).build();
@ -138,13 +139,13 @@ public class TransportClearVotingTombstonesAction
@Override @Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) { public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
listener.onResponse(new ClearVotingTombstonesResponse()); listener.onResponse(new ClearVotingConfigExclusionsResponse());
} }
}); });
} }
@Override @Override
protected ClusterBlockException checkBlock(ClearVotingTombstonesRequest request, ClusterState state) { protected ClusterBlockException checkBlock(ClearVotingConfigExclusionsRequest request, ClusterState state) {
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
} }
} }

View File

@ -28,7 +28,7 @@ import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlocks; import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData; import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData; import org.elasticsearch.cluster.metadata.MappingMetaData;
@ -278,8 +278,8 @@ public class ClusterState implements ToXContentFragment, Diffable<ClusterState>
return coordinationMetaData().getLastCommittedConfiguration(); return coordinationMetaData().getLastCommittedConfiguration();
} }
public Set<VotingTombstone> getVotingTombstones() { public Set<VotingConfigExclusion> getVotingConfigExclusions() {
return coordinationMetaData().getVotingTombstones(); return coordinationMetaData().getVotingConfigExclusions();
} }
// Used for testing and logging to determine how this cluster state was send over the wire // Used for testing and logging to determine how this cluster state was send over the wire
@ -314,7 +314,7 @@ public class ClusterState implements ToXContentFragment, Diffable<ClusterState>
sb.append(TAB).append(TAB) sb.append(TAB).append(TAB)
.append("last_accepted_config: ").append(coordinationMetaData().getLastAcceptedConfiguration()).append("\n"); .append("last_accepted_config: ").append(coordinationMetaData().getLastAcceptedConfiguration()).append("\n");
sb.append(TAB).append(TAB) sb.append(TAB).append(TAB)
.append("voting tombstones: ").append(coordinationMetaData().getVotingTombstones()).append("\n"); .append("voting tombstones: ").append(coordinationMetaData().getVotingConfigExclusions()).append("\n");
for (IndexMetaData indexMetaData : metaData) { for (IndexMetaData indexMetaData : metaData) {
sb.append(TAB).append(indexMetaData.getIndex()); sb.append(TAB).append(indexMetaData.getIndex());
sb.append(": v[").append(indexMetaData.getVersion()) sb.append(": v[").append(indexMetaData.getVersion())

View File

@ -49,12 +49,12 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
private final VotingConfiguration lastAcceptedConfiguration; private final VotingConfiguration lastAcceptedConfiguration;
private final Set<VotingTombstone> votingTombstones; private final Set<VotingConfigExclusion> votingConfigExclusions;
private static final ParseField TERM_PARSE_FIELD = new ParseField("term"); private static final ParseField TERM_PARSE_FIELD = new ParseField("term");
private static final ParseField LAST_COMMITTED_CONFIGURATION_FIELD = new ParseField("last_committed_config"); private static final ParseField LAST_COMMITTED_CONFIGURATION_FIELD = new ParseField("last_committed_config");
private static final ParseField LAST_ACCEPTED_CONFIGURATION_FIELD = new ParseField("last_accepted_config"); private static final ParseField LAST_ACCEPTED_CONFIGURATION_FIELD = new ParseField("last_accepted_config");
private static final ParseField VOTING_TOMBSTONES_FIELD = new ParseField("voting_tombstones"); private static final ParseField VOTING_CONFIG_EXCLUSIONS_FIELD = new ParseField("voting_config_exclusions");
private static long term(Object[] termAndConfigs) { private static long term(Object[] termAndConfigs) {
return (long)termAndConfigs[0]; return (long)termAndConfigs[0];
@ -73,35 +73,35 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static Set<VotingTombstone> votingTombstones(Object[] fields) { private static Set<VotingConfigExclusion> votingConfigExclusions(Object[] fields) {
Set<VotingTombstone> votingTombstones = new HashSet<>((List<VotingTombstone>) fields[3]); Set<VotingConfigExclusion> votingTombstones = new HashSet<>((List<VotingConfigExclusion>) fields[3]);
return votingTombstones; return votingTombstones;
} }
private static final ConstructingObjectParser<CoordinationMetaData, Void> PARSER = new ConstructingObjectParser<>( private static final ConstructingObjectParser<CoordinationMetaData, Void> PARSER = new ConstructingObjectParser<>(
"coordination_metadata", "coordination_metadata",
fields -> new CoordinationMetaData(term(fields), lastCommittedConfig(fields), fields -> new CoordinationMetaData(term(fields), lastCommittedConfig(fields),
lastAcceptedConfig(fields), votingTombstones(fields))); lastAcceptedConfig(fields), votingConfigExclusions(fields)));
static { static {
PARSER.declareLong(ConstructingObjectParser.constructorArg(), TERM_PARSE_FIELD); PARSER.declareLong(ConstructingObjectParser.constructorArg(), TERM_PARSE_FIELD);
PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), LAST_COMMITTED_CONFIGURATION_FIELD); PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), LAST_COMMITTED_CONFIGURATION_FIELD);
PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), LAST_ACCEPTED_CONFIGURATION_FIELD); PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), LAST_ACCEPTED_CONFIGURATION_FIELD);
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), VotingTombstone.PARSER, VOTING_TOMBSTONES_FIELD); PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), VotingConfigExclusion.PARSER, VOTING_CONFIG_EXCLUSIONS_FIELD);
} }
public CoordinationMetaData(long term, VotingConfiguration lastCommittedConfiguration, VotingConfiguration lastAcceptedConfiguration, public CoordinationMetaData(long term, VotingConfiguration lastCommittedConfiguration, VotingConfiguration lastAcceptedConfiguration,
Set<VotingTombstone> votingTombstones) { Set<VotingConfigExclusion> votingConfigExclusions) {
this.term = term; this.term = term;
this.lastCommittedConfiguration = lastCommittedConfiguration; this.lastCommittedConfiguration = lastCommittedConfiguration;
this.lastAcceptedConfiguration = lastAcceptedConfiguration; this.lastAcceptedConfiguration = lastAcceptedConfiguration;
this.votingTombstones = Collections.unmodifiableSet(new HashSet<>(votingTombstones)); this.votingConfigExclusions = Collections.unmodifiableSet(new HashSet<>(votingConfigExclusions));
} }
public CoordinationMetaData(StreamInput in) throws IOException { public CoordinationMetaData(StreamInput in) throws IOException {
term = in.readLong(); term = in.readLong();
lastCommittedConfiguration = new VotingConfiguration(in); lastCommittedConfiguration = new VotingConfiguration(in);
lastAcceptedConfiguration = new VotingConfiguration(in); lastAcceptedConfiguration = new VotingConfiguration(in);
votingTombstones = Collections.unmodifiableSet(in.readSet(VotingTombstone::new)); votingConfigExclusions = Collections.unmodifiableSet(in.readSet(VotingConfigExclusion::new));
} }
public static Builder builder() { public static Builder builder() {
@ -117,7 +117,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
out.writeLong(term); out.writeLong(term);
lastCommittedConfiguration.writeTo(out); lastCommittedConfiguration.writeTo(out);
lastAcceptedConfiguration.writeTo(out); lastAcceptedConfiguration.writeTo(out);
out.writeCollection(votingTombstones, (o, v) -> v.writeTo(o)); out.writeCollection(votingConfigExclusions, (o, v) -> v.writeTo(o));
} }
@Override @Override
@ -126,7 +126,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
.field(TERM_PARSE_FIELD.getPreferredName(), term) .field(TERM_PARSE_FIELD.getPreferredName(), term)
.field(LAST_COMMITTED_CONFIGURATION_FIELD.getPreferredName(), lastCommittedConfiguration) .field(LAST_COMMITTED_CONFIGURATION_FIELD.getPreferredName(), lastCommittedConfiguration)
.field(LAST_ACCEPTED_CONFIGURATION_FIELD.getPreferredName(), lastAcceptedConfiguration) .field(LAST_ACCEPTED_CONFIGURATION_FIELD.getPreferredName(), lastAcceptedConfiguration)
.field(VOTING_TOMBSTONES_FIELD.getPreferredName(), votingTombstones); .field(VOTING_CONFIG_EXCLUSIONS_FIELD.getPreferredName(), votingConfigExclusions);
} }
public static CoordinationMetaData fromXContent(XContentParser parser) throws IOException { public static CoordinationMetaData fromXContent(XContentParser parser) throws IOException {
@ -145,8 +145,8 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
return lastCommittedConfiguration; return lastCommittedConfiguration;
} }
public Set<VotingTombstone> getVotingTombstones() { public Set<VotingConfigExclusion> getVotingConfigExclusions() {
return votingTombstones; return votingConfigExclusions;
} }
@Override @Override
@ -159,7 +159,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
if (term != that.term) return false; if (term != that.term) return false;
if (!lastCommittedConfiguration.equals(that.lastCommittedConfiguration)) return false; if (!lastCommittedConfiguration.equals(that.lastCommittedConfiguration)) return false;
if (!lastAcceptedConfiguration.equals(that.lastAcceptedConfiguration)) return false; if (!lastAcceptedConfiguration.equals(that.lastAcceptedConfiguration)) return false;
return votingTombstones.equals(that.votingTombstones); return votingConfigExclusions.equals(that.votingConfigExclusions);
} }
@Override @Override
@ -167,7 +167,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
int result = (int) (term ^ (term >>> 32)); int result = (int) (term ^ (term >>> 32));
result = 31 * result + lastCommittedConfiguration.hashCode(); result = 31 * result + lastCommittedConfiguration.hashCode();
result = 31 * result + lastAcceptedConfiguration.hashCode(); result = 31 * result + lastAcceptedConfiguration.hashCode();
result = 31 * result + votingTombstones.hashCode(); result = 31 * result + votingConfigExclusions.hashCode();
return result; return result;
} }
@ -177,7 +177,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
"term=" + term + "term=" + term +
", lastCommittedConfiguration=" + lastCommittedConfiguration + ", lastCommittedConfiguration=" + lastCommittedConfiguration +
", lastAcceptedConfiguration=" + lastAcceptedConfiguration + ", lastAcceptedConfiguration=" + lastAcceptedConfiguration +
", votingTombstones=" + votingTombstones + ", votingConfigExclusions=" + votingConfigExclusions +
'}'; '}';
} }
@ -185,7 +185,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
private long term = 0; private long term = 0;
private VotingConfiguration lastCommittedConfiguration = VotingConfiguration.EMPTY_CONFIG; private VotingConfiguration lastCommittedConfiguration = VotingConfiguration.EMPTY_CONFIG;
private VotingConfiguration lastAcceptedConfiguration = VotingConfiguration.EMPTY_CONFIG; private VotingConfiguration lastAcceptedConfiguration = VotingConfiguration.EMPTY_CONFIG;
private final Set<VotingTombstone> votingTombstones = new HashSet<>(); private final Set<VotingConfigExclusion> votingConfigExclusions = new HashSet<>();
public Builder() { public Builder() {
@ -195,7 +195,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
this.term = state.term; this.term = state.term;
this.lastCommittedConfiguration = state.lastCommittedConfiguration; this.lastCommittedConfiguration = state.lastCommittedConfiguration;
this.lastAcceptedConfiguration = state.lastAcceptedConfiguration; this.lastAcceptedConfiguration = state.lastAcceptedConfiguration;
this.votingTombstones.addAll(state.votingTombstones); this.votingConfigExclusions.addAll(state.votingConfigExclusions);
} }
public Builder term(long term) { public Builder term(long term) {
@ -213,35 +213,35 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
return this; return this;
} }
public Builder addVotingTombstone(VotingTombstone tombstone) { public Builder addVotingConfigExclusion(VotingConfigExclusion exclusion) {
votingTombstones.add(tombstone); votingConfigExclusions.add(exclusion);
return this; return this;
} }
public Builder clearVotingTombstones() { public Builder clearVotingConfigExclusions() {
votingTombstones.clear(); votingConfigExclusions.clear();
return this; return this;
} }
public CoordinationMetaData build() { public CoordinationMetaData build() {
return new CoordinationMetaData(term, lastCommittedConfiguration, lastAcceptedConfiguration, votingTombstones); return new CoordinationMetaData(term, lastCommittedConfiguration, lastAcceptedConfiguration, votingConfigExclusions);
} }
} }
public static class VotingTombstone implements Writeable, ToXContentFragment { public static class VotingConfigExclusion implements Writeable, ToXContentFragment {
private final String nodeId; private final String nodeId;
private final String nodeName; private final String nodeName;
public VotingTombstone(DiscoveryNode node) { public VotingConfigExclusion(DiscoveryNode node) {
this(node.getId(), node.getName()); this(node.getId(), node.getName());
} }
public VotingTombstone(StreamInput in) throws IOException { public VotingConfigExclusion(StreamInput in) throws IOException {
this.nodeId = in.readString(); this.nodeId = in.readString();
this.nodeName = in.readString(); this.nodeName = in.readString();
} }
public VotingTombstone(String nodeId, String nodeName) { public VotingConfigExclusion(String nodeId, String nodeName) {
this.nodeId = nodeId; this.nodeId = nodeId;
this.nodeName = nodeName; this.nodeName = nodeName;
} }
@ -271,9 +271,9 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
return (String) nodeIdAndName[1]; return (String) nodeIdAndName[1];
} }
private static final ConstructingObjectParser<VotingTombstone, Void> PARSER = new ConstructingObjectParser<>( private static final ConstructingObjectParser<VotingConfigExclusion, Void> PARSER = new ConstructingObjectParser<>(
"voting_tombstone", "voting_config_exclusion",
nodeIdAndName -> new VotingTombstone(nodeId(nodeIdAndName), nodeName(nodeIdAndName)) nodeIdAndName -> new VotingConfigExclusion(nodeId(nodeIdAndName), nodeName(nodeIdAndName))
); );
static { static {
@ -281,7 +281,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
PARSER.declareString(ConstructingObjectParser.constructorArg(), NODE_NAME_PARSE_FIELD); PARSER.declareString(ConstructingObjectParser.constructorArg(), NODE_NAME_PARSE_FIELD);
} }
public static VotingTombstone fromXContent(XContentParser parser) throws IOException { public static VotingConfigExclusion fromXContent(XContentParser parser) throws IOException {
return PARSER.parse(parser, null); return PARSER.parse(parser, null);
} }
@ -297,7 +297,7 @@ public class CoordinationMetaData implements Writeable, ToXContentFragment {
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
VotingTombstone that = (VotingTombstone) o; VotingConfigExclusion that = (VotingConfigExclusion) o;
return Objects.equals(nodeId, that.nodeId) && return Objects.equals(nodeId, that.nodeId) &&
Objects.equals(nodeName, that.nodeName); Objects.equals(nodeName, that.nodeName);
} }

View File

@ -33,7 +33,7 @@ import org.elasticsearch.cluster.ClusterStateTaskConfig;
import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.block.ClusterBlocks; import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.coordination.FollowersChecker.FollowerCheckRequest; import org.elasticsearch.cluster.coordination.FollowersChecker.FollowerCheckRequest;
import org.elasticsearch.cluster.coordination.JoinHelper.InitialJoinAccumulator; import org.elasticsearch.cluster.coordination.JoinHelper.InitialJoinAccumulator;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
@ -671,7 +671,7 @@ public class Coordinator extends AbstractLifecycleComponent implements Discovery
final Set<DiscoveryNode> liveNodes = StreamSupport.stream(clusterState.nodes().spliterator(), false) final Set<DiscoveryNode> liveNodes = StreamSupport.stream(clusterState.nodes().spliterator(), false)
.filter(this::hasJoinVoteFrom).collect(Collectors.toSet()); .filter(this::hasJoinVoteFrom).collect(Collectors.toSet());
final VotingConfiguration newConfig = reconfigurator.reconfigure(liveNodes, final VotingConfiguration newConfig = reconfigurator.reconfigure(liveNodes,
clusterState.getVotingTombstones().stream().map(VotingTombstone::getNodeId).collect(Collectors.toSet()), clusterState.getVotingConfigExclusions().stream().map(VotingConfigExclusion::getNodeId).collect(Collectors.toSet()),
clusterState.getLastAcceptedConfiguration()); clusterState.getLastAcceptedConfiguration());
if (newConfig.equals(clusterState.getLastAcceptedConfiguration()) == false) { if (newConfig.equals(clusterState.getLastAcceptedConfiguration()) == false) {
assert coordinationState.get().joinVotesHaveQuorumFor(newConfig); assert coordinationState.get().joinVotesHaveQuorumFor(newConfig);

View File

@ -19,7 +19,7 @@
package org.elasticsearch.common.settings; package org.elasticsearch.common.settings;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction;
import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.action.search.TransportSearchAction;
import org.elasticsearch.action.support.AutoCreateIndex; import org.elasticsearch.action.support.AutoCreateIndex;
@ -470,7 +470,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
LeaderChecker.LEADER_CHECK_INTERVAL_SETTING, LeaderChecker.LEADER_CHECK_INTERVAL_SETTING,
LeaderChecker.LEADER_CHECK_RETRY_COUNT_SETTING, LeaderChecker.LEADER_CHECK_RETRY_COUNT_SETTING,
Reconfigurator.CLUSTER_AUTO_SHRINK_VOTING_CONFIGURATION, Reconfigurator.CLUSTER_AUTO_SHRINK_VOTING_CONFIGURATION,
TransportAddVotingTombstonesAction.MAXIMUM_VOTING_TOMBSTONES_SETTING, TransportAddVotingConfigExclusionsAction.MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING,
ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING, ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING,
ClusterBootstrapService.INITIAL_MASTER_NODE_COUNT_SETTING, ClusterBootstrapService.INITIAL_MASTER_NODE_COUNT_SETTING,
LagDetector.CLUSTER_FOLLOWER_LAG_TIMEOUT_SETTING LagDetector.CLUSTER_FOLLOWER_LAG_TIMEOUT_SETTING

View File

@ -19,8 +19,8 @@
package org.elasticsearch.rest.action.admin.cluster; package org.elasticsearch.rest.action.admin.cluster;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsRequest;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingTombstonesRequest; import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsAction;
import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
@ -31,30 +31,30 @@ import org.elasticsearch.rest.action.RestToXContentListener;
import java.io.IOException; import java.io.IOException;
public class RestAddVotingTombstonesAction extends BaseRestHandler { public class RestAddVotingConfigExclusionAction extends BaseRestHandler {
private static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueSeconds(30L); private static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueSeconds(30L);
public RestAddVotingTombstonesAction(Settings settings, RestController controller) { public RestAddVotingConfigExclusionAction(Settings settings, RestController controller) {
super(settings); super(settings);
controller.registerHandler(RestRequest.Method.POST, "/_cluster/withdrawn_votes/{node_name}", this); controller.registerHandler(RestRequest.Method.POST, "/_cluster/voting_config_exclusions/{node_name}", this);
} }
@Override @Override
public String getName() { public String getName() {
return "add_voting_tombstones_action"; return "add_voting_config_exclusions_action";
} }
@Override @Override
protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
String nodeName = request.param("node_name"); String nodeName = request.param("node_name");
AddVotingTombstonesRequest addVotingTombstonesRequest = new AddVotingTombstonesRequest( AddVotingConfigExclusionsRequest votingConfigExclusionsRequest = new AddVotingConfigExclusionsRequest(
new String[]{nodeName}, new String[]{nodeName},
TimeValue.parseTimeValue(request.param("timeout"), DEFAULT_TIMEOUT, getClass().getSimpleName() + ".timeout") TimeValue.parseTimeValue(request.param("timeout"), DEFAULT_TIMEOUT, getClass().getSimpleName() + ".timeout")
); );
return channel -> client.execute( return channel -> client.execute(
AddVotingTombstonesAction.INSTANCE, AddVotingConfigExclusionsAction.INSTANCE,
addVotingTombstonesRequest, votingConfigExclusionsRequest,
new RestToXContentListener<>(channel) new RestToXContentListener<>(channel)
); );
} }

View File

@ -19,8 +19,8 @@
package org.elasticsearch.rest.action.admin.cluster; package org.elasticsearch.rest.action.admin.cluster;
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsRequest;
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingTombstonesRequest; import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsAction;
import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.BaseRestHandler;
@ -30,24 +30,24 @@ import org.elasticsearch.rest.action.RestToXContentListener;
import java.io.IOException; import java.io.IOException;
public class RestClearVotingTombstonesAction extends BaseRestHandler { public class RestClearVotingConfigExclusionsAction extends BaseRestHandler {
public RestClearVotingTombstonesAction(Settings settings, RestController controller) { public RestClearVotingConfigExclusionsAction(Settings settings, RestController controller) {
super(settings); super(settings);
controller.registerHandler(RestRequest.Method.DELETE, "/_cluster/withdrawn_votes", this); controller.registerHandler(RestRequest.Method.DELETE, "/_cluster/voting_config_exclusions", this);
} }
@Override @Override
public String getName() { public String getName() {
return "clear_voting_tombstones_action"; return "clear_voting_config_exclusions_action";
} }
@Override @Override
protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
ClearVotingTombstonesRequest req = new ClearVotingTombstonesRequest(); ClearVotingConfigExclusionsRequest req = new ClearVotingConfigExclusionsRequest();
if (request.hasParam("wait_for_removal")) { if (request.hasParam("wait_for_removal")) {
req.setWaitForRemoval(request.paramAsBoolean("wait_for_removal", true)); req.setWaitForRemoval(request.paramAsBoolean("wait_for_removal", true));
} }
return channel -> client.execute(ClearVotingTombstonesAction.INSTANCE, req, new RestToXContentListener<>(channel)); return channel -> client.execute(ClearVotingConfigExclusionsAction.INSTANCE, req, new RestToXContentListener<>(channel));
} }
} }

View File

@ -22,7 +22,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNode.Role; import org.elasticsearch.cluster.node.DiscoveryNode.Role;
@ -39,7 +39,7 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
public class AddVotingTombstonesRequestTests extends ESTestCase { public class AddVotingConfigExclusionsRequestTests extends ESTestCase {
public void testSerialization() throws IOException { public void testSerialization() throws IOException {
int descriptionCount = between(0, 5); int descriptionCount = between(0, 5);
String[] descriptions = new String[descriptionCount]; String[] descriptions = new String[descriptionCount];
@ -47,8 +47,9 @@ public class AddVotingTombstonesRequestTests extends ESTestCase {
descriptions[i] = randomAlphaOfLength(10); descriptions[i] = randomAlphaOfLength(10);
} }
TimeValue timeout = TimeValue.timeValueMillis(between(0, 30000)); TimeValue timeout = TimeValue.timeValueMillis(between(0, 30000));
final AddVotingTombstonesRequest originalRequest = new AddVotingTombstonesRequest(descriptions, timeout); final AddVotingConfigExclusionsRequest originalRequest = new AddVotingConfigExclusionsRequest(descriptions, timeout);
final AddVotingTombstonesRequest deserialized = copyWriteable(originalRequest, writableRegistry(), AddVotingTombstonesRequest::new); final AddVotingConfigExclusionsRequest deserialized = copyWriteable(originalRequest, writableRegistry(),
AddVotingConfigExclusionsRequest::new);
assertThat(deserialized.getNodeDescriptions(), equalTo(originalRequest.getNodeDescriptions())); assertThat(deserialized.getNodeDescriptions(), equalTo(originalRequest.getNodeDescriptions()));
assertThat(deserialized.getTimeout(), equalTo(originalRequest.getTimeout())); assertThat(deserialized.getTimeout(), equalTo(originalRequest.getTimeout()));
} }
@ -56,66 +57,66 @@ public class AddVotingTombstonesRequestTests extends ESTestCase {
public void testResolve() { public void testResolve() {
final DiscoveryNode localNode final DiscoveryNode localNode
= new DiscoveryNode("local", "local", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("local", "local", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone localNodeTombstone = new VotingTombstone(localNode); final VotingConfigExclusion localNodeExclusion = new VotingConfigExclusion(localNode);
final DiscoveryNode otherNode1 final DiscoveryNode otherNode1
= new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone otherNode1Tombstone = new VotingTombstone(otherNode1); final VotingConfigExclusion otherNode1Exclusion = new VotingConfigExclusion(otherNode1);
final DiscoveryNode otherNode2 final DiscoveryNode otherNode2
= new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone otherNode2Tombstone = new VotingTombstone(otherNode2); final VotingConfigExclusion otherNode2Exclusion = new VotingConfigExclusion(otherNode2);
final DiscoveryNode otherDataNode final DiscoveryNode otherDataNode
= new DiscoveryNode("data", "data", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT); = new DiscoveryNode("data", "data", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
final ClusterState clusterState = ClusterState.builder(new ClusterName("cluster")).nodes(new Builder() final ClusterState clusterState = ClusterState.builder(new ClusterName("cluster")).nodes(new Builder()
.add(localNode).add(otherNode1).add(otherNode2).add(otherDataNode).localNodeId(localNode.getId())).build(); .add(localNode).add(otherNode1).add(otherNode2).add(otherDataNode).localNodeId(localNode.getId())).build();
assertThat(makeRequest().resolveVotingTombstones(clusterState), assertThat(makeRequest().resolveVotingConfigExclusions(clusterState),
containsInAnyOrder(localNodeTombstone, otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(localNodeExclusion, otherNode1Exclusion, otherNode2Exclusion));
assertThat(makeRequest("_all").resolveVotingTombstones(clusterState), assertThat(makeRequest("_all").resolveVotingConfigExclusions(clusterState),
containsInAnyOrder(localNodeTombstone, otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(localNodeExclusion, otherNode1Exclusion, otherNode2Exclusion));
assertThat(makeRequest("_local").resolveVotingTombstones(clusterState), assertThat(makeRequest("_local").resolveVotingConfigExclusions(clusterState),
contains(localNodeTombstone)); contains(localNodeExclusion));
assertThat(makeRequest("other*").resolveVotingTombstones(clusterState), assertThat(makeRequest("other*").resolveVotingConfigExclusions(clusterState),
containsInAnyOrder(otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(otherNode1Exclusion, otherNode2Exclusion));
assertThat(expectThrows(IllegalArgumentException.class, assertThat(expectThrows(IllegalArgumentException.class,
() -> makeRequest("not-a-node").resolveVotingTombstones(clusterState)).getMessage(), () -> makeRequest("not-a-node").resolveVotingConfigExclusions(clusterState)).getMessage(),
equalTo("add voting tombstones request for [not-a-node] matched no master-eligible nodes")); equalTo("add voting config exclusions request for [not-a-node] matched no master-eligible nodes"));
} }
public void testResolveAndCheckMaximum() { public void testResolveAndCheckMaximum() {
final DiscoveryNode localNode final DiscoveryNode localNode
= new DiscoveryNode("local", "local", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("local", "local", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone localNodeTombstone = new VotingTombstone(localNode); final VotingConfigExclusion localNodeExclusion = new VotingConfigExclusion(localNode);
final DiscoveryNode otherNode1 final DiscoveryNode otherNode1
= new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone otherNode1Tombstone = new VotingTombstone(otherNode1); final VotingConfigExclusion otherNode1Exclusion = new VotingConfigExclusion(otherNode1);
final DiscoveryNode otherNode2 final DiscoveryNode otherNode2
= new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT); = new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), singleton(Role.MASTER), Version.CURRENT);
final VotingTombstone otherNode2Tombstone = new VotingTombstone(otherNode2); final VotingConfigExclusion otherNode2Exclusion = new VotingConfigExclusion(otherNode2);
final ClusterState.Builder builder = ClusterState.builder(new ClusterName("cluster")).nodes(new Builder() final ClusterState.Builder builder = ClusterState.builder(new ClusterName("cluster")).nodes(new Builder()
.add(localNode).add(otherNode1).add(otherNode2).localNodeId(localNode.getId())); .add(localNode).add(otherNode1).add(otherNode2).localNodeId(localNode.getId()));
builder.metaData(MetaData.builder() builder.metaData(MetaData.builder()
.coordinationMetaData(CoordinationMetaData.builder().addVotingTombstone(otherNode1Tombstone).build())); .coordinationMetaData(CoordinationMetaData.builder().addVotingConfigExclusion(otherNode1Exclusion).build()));
final ClusterState clusterState = builder.build(); final ClusterState clusterState = builder.build();
assertThat(makeRequest().resolveVotingTombstonesAndCheckMaximum(clusterState, 3, "setting.name"), assertThat(makeRequest().resolveVotingConfigExclusionsAndCheckMaximum(clusterState, 3, "setting.name"),
containsInAnyOrder(localNodeTombstone, otherNode2Tombstone)); containsInAnyOrder(localNodeExclusion, otherNode2Exclusion));
assertThat(makeRequest("_local").resolveVotingTombstonesAndCheckMaximum(clusterState, 2, "setting.name"), assertThat(makeRequest("_local").resolveVotingConfigExclusionsAndCheckMaximum(clusterState, 2, "setting.name"),
contains(localNodeTombstone)); contains(localNodeExclusion));
assertThat(expectThrows(IllegalArgumentException.class, assertThat(expectThrows(IllegalArgumentException.class,
() -> makeRequest().resolveVotingTombstonesAndCheckMaximum(clusterState, 2, "setting.name")).getMessage(), () -> makeRequest().resolveVotingConfigExclusionsAndCheckMaximum(clusterState, 2, "setting.name")).getMessage(),
equalTo("add voting tombstones request for [] would add [2] voting tombstones to the existing [1] which would exceed the " + equalTo("add voting config exclusions request for [] would add [2] exclusions to the existing [1] which would exceed " +
"maximum of [2] set by [setting.name]")); "the maximum of [2] set by [setting.name]"));
assertThat(expectThrows(IllegalArgumentException.class, assertThat(expectThrows(IllegalArgumentException.class,
() -> makeRequest("_local").resolveVotingTombstonesAndCheckMaximum(clusterState, 1, "setting.name")).getMessage(), () -> makeRequest("_local").resolveVotingConfigExclusionsAndCheckMaximum(clusterState, 1, "setting.name")).getMessage(),
equalTo("add voting tombstones request for [_local] would add [1] voting tombstones to the existing [1] which would exceed " + equalTo("add voting config exclusions request for [_local] would add [1] exclusions to the existing [1] which would " +
"the maximum of [1] set by [setting.name]")); "exceed the maximum of [1] set by [setting.name]"));
} }
private static AddVotingTombstonesRequest makeRequest(String... descriptions) { private static AddVotingConfigExclusionsRequest makeRequest(String... descriptions) {
return new AddVotingTombstonesRequest(descriptions); return new AddVotingConfigExclusionsRequest(descriptions);
} }
} }

View File

@ -22,10 +22,10 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException; import java.io.IOException;
public class AddVotingTombstonesResponseTests extends ESTestCase { public class AddVotingConfigExclusionsResponseTests extends ESTestCase {
public void testSerialization() throws IOException { public void testSerialization() throws IOException {
final AddVotingTombstonesResponse originalRequest = new AddVotingTombstonesResponse(); final AddVotingConfigExclusionsResponse originalRequest = new AddVotingConfigExclusionsResponse();
copyWriteable(originalRequest, writableRegistry(), AddVotingTombstonesResponse::new); copyWriteable(originalRequest, writableRegistry(), AddVotingConfigExclusionsResponse::new);
// there are no fields so we're just checking that this doesn't throw anything // there are no fields so we're just checking that this doesn't throw anything
} }
} }

View File

@ -25,17 +25,17 @@ import java.io.IOException;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
public class ClearVotingTombstonesRequestTests extends ESTestCase { public class ClearVotingConfigExclusionsRequestTests extends ESTestCase {
public void testSerialization() throws IOException { public void testSerialization() throws IOException {
final ClearVotingTombstonesRequest originalRequest = new ClearVotingTombstonesRequest(); final ClearVotingConfigExclusionsRequest originalRequest = new ClearVotingConfigExclusionsRequest();
if (randomBoolean()) { if (randomBoolean()) {
originalRequest.setWaitForRemoval(randomBoolean()); originalRequest.setWaitForRemoval(randomBoolean());
} }
if (randomBoolean()) { if (randomBoolean()) {
originalRequest.setTimeout(TimeValue.timeValueMillis(randomLongBetween(0, 30000))); originalRequest.setTimeout(TimeValue.timeValueMillis(randomLongBetween(0, 30000)));
} }
final ClearVotingTombstonesRequest deserialized final ClearVotingConfigExclusionsRequest deserialized
= copyWriteable(originalRequest, writableRegistry(), ClearVotingTombstonesRequest::new); = copyWriteable(originalRequest, writableRegistry(), ClearVotingConfigExclusionsRequest::new);
assertThat(deserialized.getWaitForRemoval(), equalTo(originalRequest.getWaitForRemoval())); assertThat(deserialized.getWaitForRemoval(), equalTo(originalRequest.getWaitForRemoval()));
assertThat(deserialized.getTimeout(), equalTo(originalRequest.getTimeout())); assertThat(deserialized.getTimeout(), equalTo(originalRequest.getTimeout()));
} }

View File

@ -22,10 +22,10 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException; import java.io.IOException;
public class ClearVotingTombstonesResponseTests extends ESTestCase { public class ClearVotingConfigExclusionsResponseTests extends ESTestCase {
public void testSerialization() throws IOException { public void testSerialization() throws IOException {
final ClearVotingTombstonesResponse originalRequest = new ClearVotingTombstonesResponse(); final ClearVotingConfigExclusionsResponse originalRequest = new ClearVotingConfigExclusionsResponse();
copyWriteable(originalRequest, writableRegistry(), ClearVotingTombstonesResponse::new); copyWriteable(originalRequest, writableRegistry(), ClearVotingConfigExclusionsResponse::new);
// there are no fields so we're just checking that this doesn't throw anything // there are no fields so we're just checking that this doesn't throw anything
} }
} }

View File

@ -29,7 +29,7 @@ import org.elasticsearch.cluster.ClusterStateObserver.Listener;
import org.elasticsearch.cluster.ClusterStateUpdateTask; import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
@ -61,7 +61,7 @@ import java.util.function.Consumer;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet; import static java.util.Collections.emptySet;
import static java.util.Collections.singleton; import static java.util.Collections.singleton;
import static org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingTombstonesAction.MAXIMUM_VOTING_TOMBSTONES_SETTING; import static org.elasticsearch.action.admin.cluster.configuration.TransportAddVotingConfigExclusionsAction.MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING;
import static org.elasticsearch.cluster.ClusterState.builder; import static org.elasticsearch.cluster.ClusterState.builder;
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService; import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
import static org.elasticsearch.test.ClusterServiceUtils.setState; import static org.elasticsearch.test.ClusterServiceUtils.setState;
@ -72,12 +72,12 @@ import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
public class TransportAddVotingTombstonesActionTests extends ESTestCase { public class TransportAddVotingConfigExclusionsActionTests extends ESTestCase {
private static ThreadPool threadPool; private static ThreadPool threadPool;
private static ClusterService clusterService; private static ClusterService clusterService;
private static DiscoveryNode localNode, otherNode1, otherNode2, otherDataNode; private static DiscoveryNode localNode, otherNode1, otherNode2, otherDataNode;
private static VotingTombstone localNodeTombstone, otherNode1Tombstone, otherNode2Tombstone; private static VotingConfigExclusion localNodeExclusion, otherNode1Exclusion, otherNode2Exclusion;
private TransportService transportService; private TransportService transportService;
private ClusterStateObserver clusterStateObserver; private ClusterStateObserver clusterStateObserver;
@ -86,11 +86,11 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
public static void createThreadPoolAndClusterService() { public static void createThreadPoolAndClusterService() {
threadPool = new TestThreadPool("test", Settings.EMPTY); threadPool = new TestThreadPool("test", Settings.EMPTY);
localNode = makeDiscoveryNode("local"); localNode = makeDiscoveryNode("local");
localNodeTombstone = new VotingTombstone(localNode); localNodeExclusion = new VotingConfigExclusion(localNode);
otherNode1 = makeDiscoveryNode("other1"); otherNode1 = makeDiscoveryNode("other1");
otherNode1Tombstone = new VotingTombstone(otherNode1); otherNode1Exclusion = new VotingConfigExclusion(otherNode1);
otherNode2 = makeDiscoveryNode("other2"); otherNode2 = makeDiscoveryNode("other2");
otherNode2Tombstone = new VotingTombstone(otherNode2); otherNode2Exclusion = new VotingConfigExclusion(otherNode2);
otherDataNode = new DiscoveryNode("data", "data", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT); otherDataNode = new DiscoveryNode("data", "data", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
clusterService = createClusterService(threadPool, localNode); clusterService = createClusterService(threadPool, localNode);
} }
@ -111,7 +111,7 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
transportService = transport.createTransportService(Settings.EMPTY, threadPool, transportService = transport.createTransportService(Settings.EMPTY, threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR, boundTransportAddress -> localNode, null, emptySet()); TransportService.NOOP_TRANSPORT_INTERCEPTOR, boundTransportAddress -> localNode, null, emptySet());
new TransportAddVotingTombstonesAction(transportService, clusterService, threadPool, new ActionFilters(emptySet()), new TransportAddVotingConfigExclusionsAction(transportService, clusterService, threadPool, new ActionFilters(emptySet()),
new IndexNameExpressionResolver()); // registers action new IndexNameExpressionResolver()); // registers action
transportService.start(); transportService.start();
@ -132,9 +132,9 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
public void testWithdrawsVoteFromANode() throws InterruptedException { public void testWithdrawsVoteFromANode() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
clusterStateObserver.waitForNextChange(new AdjustConfigurationForTombstones()); clusterStateObserver.waitForNextChange(new AdjustConfigurationForExclusions());
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other1"}), new AddVotingConfigExclusionsRequest(new String[]{"other1"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -142,15 +142,15 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), contains(otherNode1Tombstone)); assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(), contains(otherNode1Exclusion));
} }
public void testWithdrawsVotesFromMultipleNodes() throws InterruptedException { public void testWithdrawsVotesFromMultipleNodes() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
clusterStateObserver.waitForNextChange(new AdjustConfigurationForTombstones()); clusterStateObserver.waitForNextChange(new AdjustConfigurationForExclusions());
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other1", "other2"}), new AddVotingConfigExclusionsRequest(new String[]{"other1", "other2"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -158,16 +158,16 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
containsInAnyOrder(otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(otherNode1Exclusion, otherNode2Exclusion));
} }
public void testWithdrawsVotesFromNodesMatchingWildcard() throws InterruptedException { public void testWithdrawsVotesFromNodesMatchingWildcard() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
clusterStateObserver.waitForNextChange(new AdjustConfigurationForTombstones()); clusterStateObserver.waitForNextChange(new AdjustConfigurationForExclusions());
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other*"}), new AddVotingConfigExclusionsRequest(new String[]{"other*"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -175,16 +175,16 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
containsInAnyOrder(otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(otherNode1Exclusion, otherNode2Exclusion));
} }
public void testWithdrawsVotesFromAllMasterEligibleNodes() throws InterruptedException { public void testWithdrawsVotesFromAllMasterEligibleNodes() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
clusterStateObserver.waitForNextChange(new AdjustConfigurationForTombstones()); clusterStateObserver.waitForNextChange(new AdjustConfigurationForExclusions());
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"_all"}), new AddVotingConfigExclusionsRequest(new String[]{"_all"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -192,16 +192,16 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
containsInAnyOrder(localNodeTombstone, otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(localNodeExclusion, otherNode1Exclusion, otherNode2Exclusion));
} }
public void testWithdrawsVoteFromLocalNode() throws InterruptedException { public void testWithdrawsVoteFromLocalNode() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
clusterStateObserver.waitForNextChange(new AdjustConfigurationForTombstones()); clusterStateObserver.waitForNextChange(new AdjustConfigurationForExclusions());
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"_local"}), new AddVotingConfigExclusionsRequest(new String[]{"_local"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -209,8 +209,8 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
contains(localNodeTombstone)); contains(localNodeExclusion));
} }
public void testReturnsImmediatelyIfVoteAlreadyWithdrawn() throws InterruptedException { public void testReturnsImmediatelyIfVoteAlreadyWithdrawn() throws InterruptedException {
@ -225,8 +225,8 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
// no observer to reconfigure // no observer to reconfigure
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other1"}, TimeValue.ZERO), new AddVotingConfigExclusionsRequest(new String[]{"other1"}, TimeValue.ZERO),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -234,34 +234,16 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
contains(otherNode1Tombstone)); contains(otherNode1Exclusion));
} }
public void testReturnsErrorIfNoMatchingNodes() throws InterruptedException { public void testReturnsErrorIfNoMatchingNodes() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> exceptionHolder = new SetOnce<>(); final SetOnce<TransportException> exceptionHolder = new SetOnce<>();
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"not-a-node"}), new AddVotingConfigExclusionsRequest(new String[]{"not-a-node"}),
expectError(e -> {
exceptionHolder.set(e);
countDownLatch.countDown();
})
);
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
final Throwable rootCause = exceptionHolder.get().getRootCause();
assertThat(rootCause, instanceOf(IllegalArgumentException.class));
assertThat(rootCause.getMessage(), equalTo("add voting tombstones request for [not-a-node] matched no master-eligible nodes"));
}
public void testOnlyMatchesMasterEligibleNodes() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> exceptionHolder = new SetOnce<>();
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME,
new AddVotingTombstonesRequest(new String[]{"_all", "master:false"}),
expectError(e -> { expectError(e -> {
exceptionHolder.set(e); exceptionHolder.set(e);
countDownLatch.countDown(); countDownLatch.countDown();
@ -272,23 +254,42 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
final Throwable rootCause = exceptionHolder.get().getRootCause(); final Throwable rootCause = exceptionHolder.get().getRootCause();
assertThat(rootCause, instanceOf(IllegalArgumentException.class)); assertThat(rootCause, instanceOf(IllegalArgumentException.class));
assertThat(rootCause.getMessage(), assertThat(rootCause.getMessage(),
equalTo("add voting tombstones request for [_all, master:false] matched no master-eligible nodes")); equalTo("add voting config exclusions request for [not-a-node] matched no master-eligible nodes"));
} }
public void testSucceedsEvenIfAllTombstonesAlreadyAdded() throws InterruptedException { public void testOnlyMatchesMasterEligibleNodes() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> exceptionHolder = new SetOnce<>();
transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingConfigExclusionsRequest(new String[]{"_all", "master:false"}),
expectError(e -> {
exceptionHolder.set(e);
countDownLatch.countDown();
})
);
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
final Throwable rootCause = exceptionHolder.get().getRootCause();
assertThat(rootCause, instanceOf(IllegalArgumentException.class));
assertThat(rootCause.getMessage(),
equalTo("add voting config exclusions request for [_all, master:false] matched no master-eligible nodes"));
}
public void testSucceedsEvenIfAllExclusionsAlreadyAdded() throws InterruptedException {
final ClusterState state = clusterService.state(); final ClusterState state = clusterService.state();
final ClusterState.Builder builder = builder(state); final ClusterState.Builder builder = builder(state);
builder.metaData(MetaData.builder(state.metaData()). builder.metaData(MetaData.builder(state.metaData()).
coordinationMetaData( coordinationMetaData(
CoordinationMetaData.builder(state.coordinationMetaData()) CoordinationMetaData.builder(state.coordinationMetaData())
.addVotingTombstone(otherNode1Tombstone). .addVotingConfigExclusion(otherNode1Exclusion).
build())); build()));
setState(clusterService, builder); setState(clusterService, builder);
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other1"}), new AddVotingConfigExclusionsRequest(new String[]{"other1"}),
expectSuccess(r -> { expectSuccess(r -> {
assertNotNull(r); assertNotNull(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -296,21 +297,21 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
contains(otherNode1Tombstone)); contains(otherNode1Exclusion));
} }
public void testReturnsErrorIfMaximumTombstoneCountExceeded() throws InterruptedException { public void testReturnsErrorIfMaximumExclusionCountExceeded() throws InterruptedException {
final MetaData.Builder metaDataBuilder = MetaData.builder(clusterService.state().metaData()).persistentSettings( final MetaData.Builder metaDataBuilder = MetaData.builder(clusterService.state().metaData()).persistentSettings(
Settings.builder().put(clusterService.state().metaData().persistentSettings()) Settings.builder().put(clusterService.state().metaData().persistentSettings())
.put(MAXIMUM_VOTING_TOMBSTONES_SETTING.getKey(), 2).build()); .put(MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING.getKey(), 2).build());
CoordinationMetaData.Builder coordinationMetaDataBuilder = CoordinationMetaData.Builder coordinationMetaDataBuilder =
CoordinationMetaData.builder(clusterService.state().coordinationMetaData()) CoordinationMetaData.builder(clusterService.state().coordinationMetaData())
.addVotingTombstone(localNodeTombstone); .addVotingConfigExclusion(localNodeExclusion);
final int existingCount, newCount; final int existingCount, newCount;
if (randomBoolean()) { if (randomBoolean()) {
coordinationMetaDataBuilder.addVotingTombstone(otherNode1Tombstone); coordinationMetaDataBuilder.addVotingConfigExclusion(otherNode1Exclusion);
existingCount = 2; existingCount = 2;
newCount = 1; newCount = 1;
} else { } else {
@ -326,8 +327,8 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> exceptionHolder = new SetOnce<>(); final SetOnce<TransportException> exceptionHolder = new SetOnce<>();
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other*"}), new AddVotingConfigExclusionsRequest(new String[]{"other*"}),
expectError(e -> { expectError(e -> {
exceptionHolder.set(e); exceptionHolder.set(e);
countDownLatch.countDown(); countDownLatch.countDown();
@ -337,17 +338,17 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
final Throwable rootCause = exceptionHolder.get().getRootCause(); final Throwable rootCause = exceptionHolder.get().getRootCause();
assertThat(rootCause, instanceOf(IllegalArgumentException.class)); assertThat(rootCause, instanceOf(IllegalArgumentException.class));
assertThat(rootCause.getMessage(), equalTo("add voting tombstones request for [other*] would add [" + newCount + assertThat(rootCause.getMessage(), equalTo("add voting config exclusions request for [other*] would add [" + newCount +
"] voting tombstones to the existing [" + existingCount + "] exclusions to the existing [" + existingCount +
"] which would exceed the maximum of [2] set by [cluster.max_voting_tombstones]")); "] which would exceed the maximum of [2] set by [cluster.max_voting_config_exclusions]"));
} }
public void testTimesOut() throws InterruptedException { public void testTimesOut() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> exceptionHolder = new SetOnce<>(); final SetOnce<TransportException> exceptionHolder = new SetOnce<>();
transportService.sendRequest(localNode, AddVotingTombstonesAction.NAME, transportService.sendRequest(localNode, AddVotingConfigExclusionsAction.NAME,
new AddVotingTombstonesRequest(new String[]{"other1"}, TimeValue.timeValueMillis(100)), new AddVotingConfigExclusionsRequest(new String[]{"other1"}, TimeValue.timeValueMillis(100)),
expectError(e -> { expectError(e -> {
exceptionHolder.set(e); exceptionHolder.set(e);
countDownLatch.countDown(); countDownLatch.countDown();
@ -357,26 +358,27 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
final Throwable rootCause = exceptionHolder.get().getRootCause(); final Throwable rootCause = exceptionHolder.get().getRootCause();
assertThat(rootCause,instanceOf(ElasticsearchTimeoutException.class)); assertThat(rootCause,instanceOf(ElasticsearchTimeoutException.class));
assertThat(rootCause.getMessage(), startsWith("timed out waiting for withdrawal of votes from [{other1}")); assertThat(rootCause.getMessage(), startsWith("timed out waiting for voting config exclusions [{other1}"));
} }
private TransportResponseHandler<AddVotingTombstonesResponse> expectSuccess(Consumer<AddVotingTombstonesResponse> onResponse) { private TransportResponseHandler<AddVotingConfigExclusionsResponse> expectSuccess(
Consumer<AddVotingConfigExclusionsResponse> onResponse) {
return responseHandler(onResponse, e -> { return responseHandler(onResponse, e -> {
throw new AssertionError("unexpected", e); throw new AssertionError("unexpected", e);
}); });
} }
private TransportResponseHandler<AddVotingTombstonesResponse> expectError(Consumer<TransportException> onException) { private TransportResponseHandler<AddVotingConfigExclusionsResponse> expectError(Consumer<TransportException> onException) {
return responseHandler(r -> { return responseHandler(r -> {
assert false : r; assert false : r;
}, onException); }, onException);
} }
private TransportResponseHandler<AddVotingTombstonesResponse> responseHandler(Consumer<AddVotingTombstonesResponse> onResponse, private TransportResponseHandler<AddVotingConfigExclusionsResponse> responseHandler(
Consumer<TransportException> onException) { Consumer<AddVotingConfigExclusionsResponse> onResponse, Consumer<TransportException> onException) {
return new TransportResponseHandler<AddVotingTombstonesResponse>() { return new TransportResponseHandler<AddVotingConfigExclusionsResponse>() {
@Override @Override
public void handleResponse(AddVotingTombstonesResponse response) { public void handleResponse(AddVotingConfigExclusionsResponse response) {
onResponse.accept(response); onResponse.accept(response);
} }
@ -391,13 +393,13 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
} }
@Override @Override
public AddVotingTombstonesResponse read(StreamInput in) throws IOException { public AddVotingConfigExclusionsResponse read(StreamInput in) throws IOException {
return new AddVotingTombstonesResponse(in); return new AddVotingConfigExclusionsResponse(in);
} }
}; };
} }
private class AdjustConfigurationForTombstones implements Listener { private class AdjustConfigurationForExclusions implements Listener {
@Override @Override
public void onNewClusterState(ClusterState state) { public void onNewClusterState(ClusterState state) {
clusterService.getMasterService().submitStateUpdateTask("reconfiguration", new ClusterStateUpdateTask() { clusterService.getMasterService().submitStateUpdateTask("reconfiguration", new ClusterStateUpdateTask() {
@ -406,7 +408,7 @@ public class TransportAddVotingTombstonesActionTests extends ESTestCase {
assertThat(currentState, sameInstance(state)); assertThat(currentState, sameInstance(state));
final Set<String> votingNodeIds = new HashSet<>(); final Set<String> votingNodeIds = new HashSet<>();
currentState.nodes().forEach(n -> votingNodeIds.add(n.getId())); currentState.nodes().forEach(n -> votingNodeIds.add(n.getId()));
currentState.getVotingTombstones().forEach(t -> votingNodeIds.remove(t.getNodeId())); currentState.getVotingConfigExclusions().forEach(t -> votingNodeIds.remove(t.getNodeId()));
final VotingConfiguration votingConfiguration = new VotingConfiguration(votingNodeIds); final VotingConfiguration votingConfiguration = new VotingConfiguration(votingNodeIds);
return builder(currentState) return builder(currentState)
.metaData(MetaData.builder(currentState.metaData()) .metaData(MetaData.builder(currentState.metaData())

View File

@ -25,7 +25,7 @@ import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNode;
@ -62,12 +62,12 @@ import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
public class TransportClearVotingTombstonesActionTests extends ESTestCase { public class TransportClearVotingConfigExclusionsActionTests extends ESTestCase {
private static ThreadPool threadPool; private static ThreadPool threadPool;
private static ClusterService clusterService; private static ClusterService clusterService;
private static DiscoveryNode localNode, otherNode1, otherNode2; private static DiscoveryNode localNode, otherNode1, otherNode2;
private static VotingTombstone otherNode1Tombstone, otherNode2Tombstone; private static VotingConfigExclusion otherNode1Exclusion, otherNode2Exclusion;
private TransportService transportService; private TransportService transportService;
@ -76,9 +76,9 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
threadPool = new TestThreadPool("test", Settings.EMPTY); threadPool = new TestThreadPool("test", Settings.EMPTY);
localNode = new DiscoveryNode("local", buildNewFakeTransportAddress(), Version.CURRENT); localNode = new DiscoveryNode("local", buildNewFakeTransportAddress(), Version.CURRENT);
otherNode1 = new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT); otherNode1 = new DiscoveryNode("other1", "other1", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
otherNode1Tombstone = new VotingTombstone(otherNode1); otherNode1Exclusion = new VotingConfigExclusion(otherNode1);
otherNode2 = new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT); otherNode2 = new DiscoveryNode("other2", "other2", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
otherNode2Tombstone = new VotingTombstone(otherNode2); otherNode2Exclusion = new VotingConfigExclusion(otherNode2);
clusterService = createClusterService(threadPool, localNode); clusterService = createClusterService(threadPool, localNode);
} }
@ -94,7 +94,7 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
transportService = transport.createTransportService(Settings.EMPTY, threadPool, transportService = transport.createTransportService(Settings.EMPTY, threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR, boundTransportAddress -> localNode, null, emptySet()); TransportService.NOOP_TRANSPORT_INTERCEPTOR, boundTransportAddress -> localNode, null, emptySet());
new TransportClearVotingTombstonesAction(transportService, clusterService, threadPool, new ActionFilters(emptySet()), new TransportClearVotingConfigExclusionsAction(transportService, clusterService, threadPool, new ActionFilters(emptySet()),
new IndexNameExpressionResolver()); // registers action new IndexNameExpressionResolver()); // registers action
transportService.start(); transportService.start();
@ -105,20 +105,20 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
.localNodeId(localNode.getId()).masterNodeId(localNode.getId())); .localNodeId(localNode.getId()).masterNodeId(localNode.getId()));
builder.metaData(MetaData.builder() builder.metaData(MetaData.builder()
.coordinationMetaData(CoordinationMetaData.builder() .coordinationMetaData(CoordinationMetaData.builder()
.addVotingTombstone(otherNode1Tombstone) .addVotingConfigExclusion(otherNode1Exclusion)
.addVotingTombstone(otherNode2Tombstone) .addVotingConfigExclusion(otherNode2Exclusion)
.build())); .build()));
setState(clusterService, builder); setState(clusterService, builder);
} }
public void testClearsVotingTombstones() throws InterruptedException { public void testClearsVotingConfigExclusions() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<ClearVotingTombstonesResponse> responseHolder = new SetOnce<>(); final SetOnce<ClearVotingConfigExclusionsResponse> responseHolder = new SetOnce<>();
final ClearVotingTombstonesRequest clearVotingTombstonesRequest = new ClearVotingTombstonesRequest(); final ClearVotingConfigExclusionsRequest clearVotingConfigExclusionsRequest = new ClearVotingConfigExclusionsRequest();
clearVotingTombstonesRequest.setWaitForRemoval(false); clearVotingConfigExclusionsRequest.setWaitForRemoval(false);
transportService.sendRequest(localNode, ClearVotingTombstonesAction.NAME, transportService.sendRequest(localNode, ClearVotingConfigExclusionsAction.NAME,
clearVotingTombstonesRequest, clearVotingConfigExclusionsRequest,
expectSuccess(r -> { expectSuccess(r -> {
responseHolder.set(r); responseHolder.set(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -127,17 +127,17 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertNotNull(responseHolder.get()); assertNotNull(responseHolder.get());
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), empty()); assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(), empty());
} }
public void testTimesOutIfWaitingForNodesThatAreNotRemoved() throws InterruptedException { public void testTimesOutIfWaitingForNodesThatAreNotRemoved() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<TransportException> responseHolder = new SetOnce<>(); final SetOnce<TransportException> responseHolder = new SetOnce<>();
final ClearVotingTombstonesRequest clearVotingTombstonesRequest = new ClearVotingTombstonesRequest(); final ClearVotingConfigExclusionsRequest clearVotingConfigExclusionsRequest = new ClearVotingConfigExclusionsRequest();
clearVotingTombstonesRequest.setTimeout(TimeValue.timeValueMillis(100)); clearVotingConfigExclusionsRequest.setTimeout(TimeValue.timeValueMillis(100));
transportService.sendRequest(localNode, ClearVotingTombstonesAction.NAME, transportService.sendRequest(localNode, ClearVotingConfigExclusionsAction.NAME,
clearVotingTombstonesRequest, clearVotingConfigExclusionsRequest,
expectError(e -> { expectError(e -> {
responseHolder.set(e); responseHolder.set(e);
countDownLatch.countDown(); countDownLatch.countDown();
@ -145,8 +145,8 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
); );
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(),
containsInAnyOrder(otherNode1Tombstone, otherNode2Tombstone)); containsInAnyOrder(otherNode1Exclusion, otherNode2Exclusion));
final Throwable rootCause = responseHolder.get().getRootCause(); final Throwable rootCause = responseHolder.get().getRootCause();
assertThat(rootCause, instanceOf(ElasticsearchTimeoutException.class)); assertThat(rootCause, instanceOf(ElasticsearchTimeoutException.class));
assertThat(rootCause.getMessage(), assertThat(rootCause.getMessage(),
@ -155,10 +155,10 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
public void testSucceedsIfNodesAreRemovedWhileWaiting() throws InterruptedException { public void testSucceedsIfNodesAreRemovedWhileWaiting() throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1); final CountDownLatch countDownLatch = new CountDownLatch(1);
final SetOnce<ClearVotingTombstonesResponse> responseHolder = new SetOnce<>(); final SetOnce<ClearVotingConfigExclusionsResponse> responseHolder = new SetOnce<>();
transportService.sendRequest(localNode, ClearVotingTombstonesAction.NAME, transportService.sendRequest(localNode, ClearVotingConfigExclusionsAction.NAME,
new ClearVotingTombstonesRequest(), new ClearVotingConfigExclusionsRequest(),
expectSuccess(r -> { expectSuccess(r -> {
responseHolder.set(r); responseHolder.set(r);
countDownLatch.countDown(); countDownLatch.countDown();
@ -170,26 +170,27 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
setState(clusterService, builder); setState(clusterService, builder);
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
assertThat(clusterService.getClusterApplierService().state().getVotingTombstones(), empty()); assertThat(clusterService.getClusterApplierService().state().getVotingConfigExclusions(), empty());
} }
private TransportResponseHandler<ClearVotingTombstonesResponse> expectSuccess(Consumer<ClearVotingTombstonesResponse> onResponse) { private TransportResponseHandler<ClearVotingConfigExclusionsResponse> expectSuccess(
Consumer<ClearVotingConfigExclusionsResponse> onResponse) {
return responseHandler(onResponse, e -> { return responseHandler(onResponse, e -> {
throw new AssertionError("unexpected", e); throw new AssertionError("unexpected", e);
}); });
} }
private TransportResponseHandler<ClearVotingTombstonesResponse> expectError(Consumer<TransportException> onException) { private TransportResponseHandler<ClearVotingConfigExclusionsResponse> expectError(Consumer<TransportException> onException) {
return responseHandler(r -> { return responseHandler(r -> {
assert false : r; assert false : r;
}, onException); }, onException);
} }
private TransportResponseHandler<ClearVotingTombstonesResponse> responseHandler(Consumer<ClearVotingTombstonesResponse> onResponse, private TransportResponseHandler<ClearVotingConfigExclusionsResponse> responseHandler(
Consumer<TransportException> onException) { Consumer<ClearVotingConfigExclusionsResponse> onResponse, Consumer<TransportException> onException) {
return new TransportResponseHandler<ClearVotingTombstonesResponse>() { return new TransportResponseHandler<ClearVotingConfigExclusionsResponse>() {
@Override @Override
public void handleResponse(ClearVotingTombstonesResponse response) { public void handleResponse(ClearVotingConfigExclusionsResponse response) {
onResponse.accept(response); onResponse.accept(response);
} }
@ -204,8 +205,8 @@ public class TransportClearVotingTombstonesActionTests extends ESTestCase {
} }
@Override @Override
public ClearVotingTombstonesResponse read(StreamInput in) throws IOException { public ClearVotingConfigExclusionsResponse read(StreamInput in) throws IOException {
return new ClearVotingTombstonesResponse(in); return new ClearVotingConfigExclusionsResponse(in);
} }
}; };
} }

View File

@ -88,7 +88,7 @@ public class ClusterRerouteResponseTests extends ESTestCase {
" \"term\" : 0,\n" + " \"term\" : 0,\n" +
" \"last_committed_config\" : [ ],\n" + " \"last_committed_config\" : [ ],\n" +
" \"last_accepted_config\" : [ ],\n" + " \"last_accepted_config\" : [ ],\n" +
" \"voting_tombstones\" : [ ]\n" + " \"voting_config_exclusions\" : [ ]\n" +
" },\n" + " },\n" +
" \"templates\" : { },\n" + " \"templates\" : { },\n" +
" \"indices\" : {\n" + " \"indices\" : {\n" +
@ -183,7 +183,7 @@ public class ClusterRerouteResponseTests extends ESTestCase {
" \"term\" : 0,\n" + " \"term\" : 0,\n" +
" \"last_committed_config\" : [ ],\n" + " \"last_committed_config\" : [ ],\n" +
" \"last_accepted_config\" : [ ],\n" + " \"last_accepted_config\" : [ ],\n" +
" \"voting_tombstones\" : [ ]\n" + " \"voting_config_exclusions\" : [ ]\n" +
" },\n" + " },\n" +
" \"templates\" : { },\n" + " \"templates\" : { },\n" +
" \"indices\" : {\n" + " \"indices\" : {\n" +

View File

@ -23,7 +23,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
import org.elasticsearch.cluster.block.ClusterBlock; import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlocks; import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.IndexGraveyard; import org.elasticsearch.cluster.metadata.IndexGraveyard;
import org.elasticsearch.cluster.metadata.IndexGraveyardTests; import org.elasticsearch.cluster.metadata.IndexGraveyardTests;
@ -208,7 +208,7 @@ public class ClusterStateDiffIT extends ESIntegTestCase {
new CoordinationMetaData.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(10, 10, false)))); new CoordinationMetaData.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(10, 10, false))));
} }
if (randomBoolean()) { if (randomBoolean()) {
metaBuilder.addVotingTombstone(new VotingTombstone(randomNode("node-" + randomAlphaOfLength(10)))); metaBuilder.addVotingConfigExclusion(new VotingConfigExclusion(randomNode("node-" + randomAlphaOfLength(10))));
} }
return builder; return builder;
} }

View File

@ -19,7 +19,7 @@
package org.elasticsearch.cluster.coordination; package org.elasticsearch.cluster.coordination;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.util.set.Sets;
@ -94,29 +94,29 @@ public class CoordinationMetaDataTests extends ESTestCase {
} }
public void testVotingTombstoneSerializationEqualsHashCode() { public void testVotingTombstoneSerializationEqualsHashCode() {
VotingTombstone tombstone = new VotingTombstone(randomAlphaOfLength(10), randomAlphaOfLength(10)); VotingConfigExclusion tombstone = new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10));
EqualsHashCodeTestUtils.checkEqualsAndHashCode(tombstone, EqualsHashCodeTestUtils.checkEqualsAndHashCode(tombstone,
orig -> ESTestCase.copyWriteable(orig, new NamedWriteableRegistry(Collections.emptyList()), VotingTombstone::new), orig -> ESTestCase.copyWriteable(orig, new NamedWriteableRegistry(Collections.emptyList()), VotingConfigExclusion::new),
orig -> randomlyChangeVotingTombstone(orig)); orig -> randomlyChangeVotingTombstone(orig));
} }
public void testVotingTombstoneXContent() throws IOException { public void testVotingTombstoneXContent() throws IOException {
VotingTombstone originalTombstone = new VotingTombstone(randomAlphaOfLength(10), randomAlphaOfLength(10)); VotingConfigExclusion originalTombstone = new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10));
final XContentBuilder builder = JsonXContent.contentBuilder(); final XContentBuilder builder = JsonXContent.contentBuilder();
originalTombstone.toXContent(builder, ToXContent.EMPTY_PARAMS); originalTombstone.toXContent(builder, ToXContent.EMPTY_PARAMS);
try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) {
final VotingTombstone fromXContentTombstone = VotingTombstone.fromXContent(parser); final VotingConfigExclusion fromXContentTombstone = VotingConfigExclusion.fromXContent(parser);
assertThat(originalTombstone, equalTo(fromXContentTombstone)); assertThat(originalTombstone, equalTo(fromXContentTombstone));
} }
} }
private VotingTombstone randomlyChangeVotingTombstone(VotingTombstone tombstone) { private VotingConfigExclusion randomlyChangeVotingTombstone(VotingConfigExclusion tombstone) {
if (randomBoolean()) { if (randomBoolean()) {
return new VotingTombstone(randomAlphaOfLength(10), tombstone.getNodeName()); return new VotingConfigExclusion(randomAlphaOfLength(10), tombstone.getNodeName());
} else { } else {
return new VotingTombstone(tombstone.getNodeId(), randomAlphaOfLength(10)); return new VotingConfigExclusion(tombstone.getNodeId(), randomAlphaOfLength(10));
} }
} }
@ -136,11 +136,11 @@ public class CoordinationMetaDataTests extends ESTestCase {
return new VotingConfiguration(newNodeIds); return new VotingConfiguration(newNodeIds);
} }
private Set<VotingTombstone> randomVotingTombstones() { private Set<VotingConfigExclusion> randomVotingTombstones() {
final int size = randomIntBetween(1, 10); final int size = randomIntBetween(1, 10);
final Set<VotingTombstone> nodes = new HashSet<>(size); final Set<VotingConfigExclusion> nodes = new HashSet<>(size);
while (nodes.size() < size) { while (nodes.size() < size) {
assertTrue(nodes.add(new VotingTombstone(randomAlphaOfLength(10), randomAlphaOfLength(10)))); assertTrue(nodes.add(new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10))));
} }
return nodes; return nodes;
} }
@ -163,10 +163,10 @@ public class CoordinationMetaDataTests extends ESTestCase {
builder.lastAcceptedConfiguration(randomlyChangeVotingConfiguration(meta.getLastAcceptedConfiguration())); builder.lastAcceptedConfiguration(randomlyChangeVotingConfiguration(meta.getLastAcceptedConfiguration()));
break; break;
case 3: case 3:
if (meta.getVotingTombstones().isEmpty() == false && randomBoolean()) { if (meta.getVotingConfigExclusions().isEmpty() == false && randomBoolean()) {
builder.clearVotingTombstones(); builder.clearVotingConfigExclusions();
} else { } else {
randomVotingTombstones().forEach(dn -> builder.addVotingTombstone(dn)); randomVotingTombstones().forEach(dn -> builder.addVotingConfigExclusion(dn));
} }
break; break;
} }

View File

@ -23,7 +23,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.cluster.ClusterModule;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
@ -415,18 +415,18 @@ public class MetaDataTests extends ESTestCase {
return new CoordinationMetaData.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(randomInt(10), 20, false))); return new CoordinationMetaData.VotingConfiguration(Sets.newHashSet(generateRandomStringArray(randomInt(10), 20, false)));
} }
private Set<VotingTombstone> randomVotingTombstones() { private Set<VotingConfigExclusion> randomVotingConfigExclusions() {
final int size = randomIntBetween(0, 10); final int size = randomIntBetween(0, 10);
final Set<VotingTombstone> nodes = new HashSet<>(size); final Set<VotingConfigExclusion> nodes = new HashSet<>(size);
while (nodes.size() < size) { while (nodes.size() < size) {
assertTrue(nodes.add(new VotingTombstone(randomAlphaOfLength(10), randomAlphaOfLength(10)))); assertTrue(nodes.add(new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10))));
} }
return nodes; return nodes;
} }
public void testXContentWithCoordinationMetaData() throws IOException { public void testXContentWithCoordinationMetaData() throws IOException {
CoordinationMetaData originalMeta = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(), randomVotingConfig(), CoordinationMetaData originalMeta = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(), randomVotingConfig(),
randomVotingTombstones()); randomVotingConfigExclusions());
MetaData metaData = MetaData.builder().coordinationMetaData(originalMeta).build(); MetaData metaData = MetaData.builder().coordinationMetaData(originalMeta).build();
@ -443,10 +443,10 @@ public class MetaDataTests extends ESTestCase {
public void testGlobalStateEqualsCoordinationMetaData() { public void testGlobalStateEqualsCoordinationMetaData() {
CoordinationMetaData coordinationMetaData1 = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(), CoordinationMetaData coordinationMetaData1 = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(),
randomVotingConfig(), randomVotingTombstones()); randomVotingConfig(), randomVotingConfigExclusions());
MetaData metaData1 = MetaData.builder().coordinationMetaData(coordinationMetaData1).build(); MetaData metaData1 = MetaData.builder().coordinationMetaData(coordinationMetaData1).build();
CoordinationMetaData coordinationMetaData2 = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(), CoordinationMetaData coordinationMetaData2 = new CoordinationMetaData(randomNonNegativeLong(), randomVotingConfig(),
randomVotingConfig(), randomVotingTombstones()); randomVotingConfig(), randomVotingConfigExclusions());
MetaData metaData2 = MetaData.builder().coordinationMetaData(coordinationMetaData2).build(); MetaData metaData2 = MetaData.builder().coordinationMetaData(coordinationMetaData2).build();
assertTrue(MetaData.isGlobalStateEquals(metaData1, metaData1)); assertTrue(MetaData.isGlobalStateEquals(metaData1, metaData1));

View File

@ -23,7 +23,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.coordination.CoordinationMetaData; import org.elasticsearch.cluster.coordination.CoordinationMetaData;
import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingTombstone; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion;
import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.Manifest; import org.elasticsearch.cluster.metadata.Manifest;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
@ -145,7 +145,7 @@ public class GatewayMetaStatePersistedStateTests extends ESTestCase {
new CoordinationMetaData.VotingConfiguration( new CoordinationMetaData.VotingConfiguration(
Sets.newHashSet(generateRandomStringArray(10, 10, false)))); Sets.newHashSet(generateRandomStringArray(10, 10, false))));
for (int i = 0; i < randomIntBetween(0, 5); i++) { for (int i = 0; i < randomIntBetween(0, 5); i++) {
builder.addVotingTombstone(new VotingTombstone(randomAlphaOfLength(10), randomAlphaOfLength(10))); builder.addVotingConfigExclusion(new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10)));
} }
return builder.build(); return builder.build();

View File

@ -31,10 +31,10 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.AlreadyClosedException;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingTombstonesRequest; import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsRequest;
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingTombstonesAction; import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsRequest;
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingTombstonesRequest; import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsAction;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags; import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags;
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags.Flag; import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags.Flag;
@ -1636,7 +1636,7 @@ public final class InternalTestCluster extends TestCluster {
} }
private synchronized void stopNodesAndClients(Collection<NodeAndClient> nodeAndClients) throws IOException { private synchronized void stopNodesAndClients(Collection<NodeAndClient> nodeAndClients) throws IOException {
final Set<String> withdrawnNodeIds = new HashSet<>(); final Set<String> excludedNodeIds = new HashSet<>();
if (autoManageMinMasterNodes && nodeAndClients.size() > 0) { if (autoManageMinMasterNodes && nodeAndClients.size() > 0) {
@ -1649,13 +1649,13 @@ public final class InternalTestCluster extends TestCluster {
// However, we do not yet have a way to be sure there's a majority left, because the voting configuration may not yet have // However, we do not yet have a way to be sure there's a majority left, because the voting configuration may not yet have
// been updated when the previous nodes shut down, so we must always explicitly withdraw votes. // been updated when the previous nodes shut down, so we must always explicitly withdraw votes.
// TODO add cluster health API to check that voting configuration is optimal so this isn't always needed // TODO add cluster health API to check that voting configuration is optimal so this isn't always needed
nodeAndClients.stream().filter(NodeAndClient::isMasterEligible).map(NodeAndClient::getName).forEach(withdrawnNodeIds::add); nodeAndClients.stream().filter(NodeAndClient::isMasterEligible).map(NodeAndClient::getName).forEach(excludedNodeIds::add);
assert withdrawnNodeIds.size() == stoppingMasters; assert excludedNodeIds.size() == stoppingMasters;
logger.info("withdrawing votes from {} prior to shutdown", withdrawnNodeIds); logger.info("adding voting config exclusions {} prior to shutdown", excludedNodeIds);
try { try {
client().execute(AddVotingTombstonesAction.INSTANCE, client().execute(AddVotingConfigExclusionsAction.INSTANCE,
new AddVotingTombstonesRequest(withdrawnNodeIds.toArray(new String[0]))).get(); new AddVotingConfigExclusionsRequest(excludedNodeIds.toArray(new String[0]))).get();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
throw new AssertionError("unexpected", e); throw new AssertionError("unexpected", e);
} }
@ -1673,10 +1673,10 @@ public final class InternalTestCluster extends TestCluster {
nodeAndClient.close(); nodeAndClient.close();
} }
if (withdrawnNodeIds.isEmpty() == false) { if (excludedNodeIds.isEmpty() == false) {
logger.info("removing voting tombstones for {} after shutdown", withdrawnNodeIds); logger.info("removing voting config exclusions for {} after shutdown", excludedNodeIds);
try { try {
client().execute(ClearVotingTombstonesAction.INSTANCE, new ClearVotingTombstonesRequest()).get(); client().execute(ClearVotingConfigExclusionsAction.INSTANCE, new ClearVotingConfigExclusionsRequest()).get();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
throw new AssertionError("unexpected", e); throw new AssertionError("unexpected", e);
} }