use of org.elasticsearch.cluster.coordination.CoordinationMetadata in project crate by crate.
the class TransportAddVotingConfigExclusionsAction method masterOperation.
@Override
protected void masterOperation(AddVotingConfigExclusionsRequest request, ClusterState state, ActionListener<AddVotingConfigExclusionsResponse> listener) throws Exception {
// throws IAE if no nodes matched or maximum exceeded
resolveVotingConfigExclusionsAndCheckMaximum(request, state);
clusterService.submitStateUpdateTask("add-voting-config-exclusions", new ClusterStateUpdateTask(Priority.URGENT) {
private Set<VotingConfigExclusion> resolvedExclusions;
@Override
public ClusterState execute(ClusterState currentState) {
assert resolvedExclusions == null : resolvedExclusions;
resolvedExclusions = resolveVotingConfigExclusionsAndCheckMaximum(request, currentState);
final CoordinationMetadata.Builder builder = CoordinationMetadata.builder(currentState.coordinationMetadata());
resolvedExclusions.forEach(builder::addVotingConfigExclusion);
final Metadata newMetadata = Metadata.builder(currentState.metadata()).coordinationMetadata(builder.build()).build();
final ClusterState newState = ClusterState.builder(currentState).metadata(newMetadata).build();
assert newState.getVotingConfigExclusions().size() <= MAXIMUM_VOTING_CONFIG_EXCLUSIONS_SETTING.get(currentState.metadata().settings());
return newState;
}
@Override
public void onFailure(String source, Exception e) {
listener.onFailure(e);
}
@Override
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
final ClusterStateObserver observer = new ClusterStateObserver(clusterService, request.getTimeout(), logger);
final Set<String> excludedNodeIds = resolvedExclusions.stream().map(VotingConfigExclusion::getNodeId).collect(Collectors.toSet());
final Predicate<ClusterState> allNodesRemoved = clusterState -> {
final Set<String> votingConfigNodeIds = clusterState.getLastCommittedConfiguration().getNodeIds();
return excludedNodeIds.stream().noneMatch(votingConfigNodeIds::contains);
};
final Listener clusterStateListener = new Listener() {
@Override
public void onNewClusterState(ClusterState state) {
listener.onResponse(new AddVotingConfigExclusionsResponse());
}
@Override
public void onClusterServiceClose() {
listener.onFailure(new ElasticsearchException("cluster service closed while waiting for voting config exclusions " + resolvedExclusions + " to take effect"));
}
@Override
public void onTimeout(TimeValue timeout) {
listener.onFailure(new ElasticsearchTimeoutException("timed out waiting for voting config exclusions " + resolvedExclusions + " to take effect"));
}
};
if (allNodesRemoved.test(newState)) {
clusterStateListener.onNewClusterState(newState);
} else {
observer.waitForNextChange(clusterStateListener, allNodesRemoved);
}
}
});
}
use of org.elasticsearch.cluster.coordination.CoordinationMetadata in project crate by crate.
the class GatewayMetaStatePersistedStateTests method createCoordinationMetadata.
private CoordinationMetadata createCoordinationMetadata(long term) {
CoordinationMetadata.Builder builder = CoordinationMetadata.builder();
builder.term(term);
builder.lastAcceptedConfiguration(new CoordinationMetadata.VotingConfiguration(Set.of(generateRandomStringArray(10, 10, false))));
builder.lastCommittedConfiguration(new CoordinationMetadata.VotingConfiguration(Set.of(generateRandomStringArray(10, 10, false))));
for (int i = 0; i < randomIntBetween(0, 5); i++) {
builder.addVotingConfigExclusion(new VotingConfigExclusion(randomAlphaOfLength(10), randomAlphaOfLength(10)));
}
return builder.build();
}
use of org.elasticsearch.cluster.coordination.CoordinationMetadata in project crate by crate.
the class GatewayMetaStatePersistedStateTests method testDataOnlyNodePersistence.
public void testDataOnlyNodePersistence() throws Exception {
DiscoveryNode localNode = new DiscoveryNode("node1", buildNewFakeTransportAddress(), Collections.emptyMap(), Set.of(DiscoveryNodeRole.DATA_ROLE), Version.CURRENT);
Settings settings = Settings.builder().put(ClusterName.CLUSTER_NAME_SETTING.getKey(), clusterName.value()).put(Node.NODE_MASTER_SETTING.getKey(), false).put(Node.NODE_NAME_SETTING.getKey(), "test").build();
final MockGatewayMetaState gateway = new MockGatewayMetaState(localNode);
final TransportService transportService = mock(TransportService.class);
TestThreadPool threadPool = new TestThreadPool("testMarkAcceptedConfigAsCommittedOnDataOnlyNode");
when(transportService.getThreadPool()).thenReturn(threadPool);
ClusterService clusterService = mock(ClusterService.class);
when(clusterService.getClusterSettings()).thenReturn(new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS));
final PersistedClusterStateService persistedClusterStateService = new PersistedClusterStateService(nodeEnvironment, xContentRegistry(), BigArrays.NON_RECYCLING_INSTANCE, new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L);
gateway.start(settings, transportService, clusterService, new MetaStateService(nodeEnvironment, xContentRegistry()), null, null, persistedClusterStateService);
final CoordinationState.PersistedState persistedState = gateway.getPersistedState();
assertThat(persistedState, instanceOf(GatewayMetaState.AsyncLucenePersistedState.class));
// generate random coordinationMetadata with different lastAcceptedConfiguration and lastCommittedConfiguration
CoordinationMetadata coordinationMetadata;
do {
coordinationMetadata = createCoordinationMetadata(randomNonNegativeLong());
} while (coordinationMetadata.getLastAcceptedConfiguration().equals(coordinationMetadata.getLastCommittedConfiguration()));
ClusterState state = createClusterState(randomNonNegativeLong(), Metadata.builder().coordinationMetadata(coordinationMetadata).clusterUUID(randomAlphaOfLength(10)).build());
persistedState.setLastAcceptedState(state);
assertBusy(() -> assertTrue(gateway.allPendingAsyncStatesWritten()));
assertThat(persistedState.getLastAcceptedState().getLastAcceptedConfiguration(), not(equalTo(persistedState.getLastAcceptedState().getLastCommittedConfiguration())));
CoordinationMetadata persistedCoordinationMetadata = persistedClusterStateService.loadBestOnDiskState().metadata.coordinationMetadata();
assertThat(persistedCoordinationMetadata.getLastAcceptedConfiguration(), equalTo(GatewayMetaState.AsyncLucenePersistedState.STALE_STATE_CONFIG));
assertThat(persistedCoordinationMetadata.getLastCommittedConfiguration(), equalTo(GatewayMetaState.AsyncLucenePersistedState.STALE_STATE_CONFIG));
persistedState.markLastAcceptedStateAsCommitted();
assertBusy(() -> assertTrue(gateway.allPendingAsyncStatesWritten()));
CoordinationMetadata expectedCoordinationMetadata = CoordinationMetadata.builder(coordinationMetadata).lastCommittedConfiguration(coordinationMetadata.getLastAcceptedConfiguration()).build();
ClusterState expectedClusterState = ClusterState.builder(state).metadata(Metadata.builder().coordinationMetadata(expectedCoordinationMetadata).clusterUUID(state.metadata().clusterUUID()).clusterUUIDCommitted(true).build()).build();
assertClusterStateEqual(expectedClusterState, persistedState.getLastAcceptedState());
persistedCoordinationMetadata = persistedClusterStateService.loadBestOnDiskState().metadata.coordinationMetadata();
assertThat(persistedCoordinationMetadata.getLastAcceptedConfiguration(), equalTo(GatewayMetaState.AsyncLucenePersistedState.STALE_STATE_CONFIG));
assertThat(persistedCoordinationMetadata.getLastCommittedConfiguration(), equalTo(GatewayMetaState.AsyncLucenePersistedState.STALE_STATE_CONFIG));
assertTrue(persistedClusterStateService.loadBestOnDiskState().metadata.clusterUUIDCommitted());
// generate a series of updates and check if batching works
final String indexName = randomAlphaOfLength(10);
long currentTerm = state.term();
for (int i = 0; i < 1000; i++) {
if (rarely()) {
// bump term
currentTerm = currentTerm + (rarely() ? randomIntBetween(1, 5) : 0L);
persistedState.setCurrentTerm(currentTerm);
} else {
// update cluster state
final int numberOfShards = randomIntBetween(1, 5);
final long term = Math.min(state.term() + (rarely() ? randomIntBetween(1, 5) : 0L), currentTerm);
final IndexMetadata indexMetadata = createIndexMetadata(indexName, numberOfShards, i);
state = createClusterState(state.version() + 1, Metadata.builder().coordinationMetadata(createCoordinationMetadata(term)).put(indexMetadata, false).build());
persistedState.setLastAcceptedState(state);
}
}
assertEquals(currentTerm, persistedState.getCurrentTerm());
assertClusterStateEqual(state, persistedState.getLastAcceptedState());
assertBusy(() -> assertTrue(gateway.allPendingAsyncStatesWritten()));
gateway.close();
try (CoordinationState.PersistedState reloadedPersistedState = newGatewayPersistedState()) {
assertEquals(currentTerm, reloadedPersistedState.getCurrentTerm());
assertClusterStateEqual(GatewayMetaState.AsyncLucenePersistedState.resetVotingConfiguration(state), reloadedPersistedState.getLastAcceptedState());
assertNotNull(reloadedPersistedState.getLastAcceptedState().metadata().index(indexName));
}
ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS);
}
use of org.elasticsearch.cluster.coordination.CoordinationMetadata in project crate by crate.
the class PersistedClusterStateServiceTests method testFailsIfFreshestStateIsInStaleTerm.
public void testFailsIfFreshestStateIsInStaleTerm() throws IOException {
final Path[] dataPaths1 = createDataPaths();
final Path[] dataPaths2 = createDataPaths();
final Path[] combinedPaths = Stream.concat(Arrays.stream(dataPaths1), Arrays.stream(dataPaths2)).toArray(Path[]::new);
final long staleCurrentTerm = randomLongBetween(1L, Long.MAX_VALUE - 1);
final long freshCurrentTerm = randomLongBetween(staleCurrentTerm + 1, Long.MAX_VALUE);
final long freshTerm = randomLongBetween(1L, Long.MAX_VALUE);
final long staleTerm = randomBoolean() ? freshTerm : randomLongBetween(1L, freshTerm);
final long freshVersion = randomLongBetween(2L, Long.MAX_VALUE);
final long staleVersion = staleTerm == freshTerm ? randomLongBetween(1L, freshVersion - 1) : randomLongBetween(1L, Long.MAX_VALUE);
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(combinedPaths)) {
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(newPersistedClusterStateService(nodeEnvironment));
assertFalse(clusterState.metadata().clusterUUIDCommitted());
writeState(writer, staleCurrentTerm, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).version(1).coordinationMetadata(CoordinationMetadata.builder(clusterState.coordinationMetadata()).term(staleTerm).build())).version(staleVersion).build(), clusterState);
}
}
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(dataPaths1)) {
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(newPersistedClusterStateService(nodeEnvironment));
writeState(writer, freshCurrentTerm, clusterState, clusterState);
}
}
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(dataPaths2)) {
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final PersistedClusterStateService.OnDiskState onDiskState = newPersistedClusterStateService(nodeEnvironment).loadBestOnDiskState();
final ClusterState clusterState = clusterStateFromMetadata(onDiskState.lastAcceptedVersion, onDiskState.metadata);
writeState(writer, onDiskState.currentTerm, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).version(2).coordinationMetadata(CoordinationMetadata.builder(clusterState.coordinationMetadata()).term(freshTerm).build())).version(freshVersion).build(), clusterState);
}
}
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(combinedPaths)) {
final String message = expectThrows(IllegalStateException.class, () -> newPersistedClusterStateService(nodeEnvironment).loadBestOnDiskState()).getMessage();
assertThat(message, allOf(containsString("inconsistent terms found"), containsString(Long.toString(staleCurrentTerm)), containsString(Long.toString(freshCurrentTerm))));
assertTrue("[" + message + "] should match " + Arrays.toString(dataPaths1), Arrays.stream(dataPaths1).anyMatch(p -> message.contains(p.toString())));
assertTrue("[" + message + "] should match " + Arrays.toString(dataPaths2), Arrays.stream(dataPaths2).anyMatch(p -> message.contains(p.toString())));
}
}
Aggregations