use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.
the class TransportReplicationActionTests method testReplicasCounter.
public void testReplicasCounter() throws Exception {
final ShardId shardId = new ShardId("test", "_na_", 0);
final ClusterState state = state(shardId.getIndexName(), true, ShardRoutingState.STARTED, ShardRoutingState.STARTED);
setState(clusterService, state);
final ShardRouting replicaRouting = state.getRoutingTable().shardRoutingTable(shardId).replicaShards().get(0);
boolean throwException = randomBoolean();
final ReplicationTask task = maybeTask();
TestAction action = new TestAction(Settings.EMPTY, "testActionWithExceptions", transportService, clusterService, shardStateAction, threadPool) {
@Override
protected ReplicaResult shardOperationOnReplica(Request request, IndexShard replica) {
assertIndexShardCounter(1);
assertPhase(task, "replica");
if (throwException) {
throw new ElasticsearchException("simulated");
}
return new ReplicaResult();
}
};
final TestAction.ReplicaOperationTransportHandler replicaOperationTransportHandler = action.new ReplicaOperationTransportHandler();
try {
replicaOperationTransportHandler.messageReceived(new TransportReplicationAction.ConcreteShardRequest<>(new Request().setShardId(shardId), replicaRouting.allocationId().getId()), createTransportChannel(new PlainActionFuture<>()), task);
} catch (ElasticsearchException e) {
assertThat(e.getMessage(), containsString("simulated"));
assertTrue(throwException);
}
assertPhase(task, "finished");
// operation should have finished and counter decreased because no outstanding replica requests
assertIndexShardCounter(0);
}
use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.
the class TransportReplicationActionTests method testClosedIndexOnReroute.
public void testClosedIndexOnReroute() throws InterruptedException {
final String index = "test";
// no replicas in oder to skip the replication part
setState(clusterService, new ClusterStateChanges(xContentRegistry(), threadPool).closeIndices(state(index, true, ShardRoutingState.UNASSIGNED), new CloseIndexRequest(index)));
logger.debug("--> using initial state:\n{}", clusterService.state());
Request request = new Request(new ShardId("test", "_na_", 0)).timeout("1ms");
PlainActionFuture<TestResponse> listener = new PlainActionFuture<>();
ReplicationTask task = maybeTask();
ClusterBlockLevel indexBlockLevel = randomBoolean() ? ClusterBlockLevel.WRITE : null;
TestAction action = new TestAction(Settings.EMPTY, "testActionWithBlocks", transportService, clusterService, shardStateAction, threadPool) {
@Override
protected ClusterBlockLevel indexBlockLevel() {
return indexBlockLevel;
}
};
TestAction.ReroutePhase reroutePhase = action.new ReroutePhase(task, request, listener);
reroutePhase.run();
if (indexBlockLevel == ClusterBlockLevel.WRITE) {
assertListenerThrows("must throw block exception", listener, ClusterBlockException.class);
} else {
assertListenerThrows("must throw index closed exception", listener, IndexClosedException.class);
}
assertPhase(task, "failed");
assertFalse(request.isRetrySet.get());
}
use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.
the class ClusterStateHealthTests method testClusterHealthWaitsForClusterStateApplication.
public void testClusterHealthWaitsForClusterStateApplication() throws InterruptedException, ExecutionException {
final CountDownLatch applyLatch = new CountDownLatch(1);
final CountDownLatch listenerCalled = new CountDownLatch(1);
setState(clusterService, ClusterState.builder(clusterService.state()).nodes(DiscoveryNodes.builder(clusterService.state().nodes()).masterNodeId(null)).build());
clusterService.addStateApplier(event -> {
listenerCalled.countDown();
try {
applyLatch.await();
} catch (InterruptedException e) {
logger.debug("interrupted", e);
}
});
logger.info("--> submit task to restore master");
clusterService.submitStateUpdateTask("restore master", new LocalClusterUpdateTask() {
@Override
public ClusterTasksResult<LocalClusterUpdateTask> execute(ClusterState currentState) throws Exception {
return newState(ClusterState.builder(currentState).nodes(DiscoveryNodes.builder(currentState.nodes()).masterNodeId(currentState.nodes().getLocalNodeId())).build());
}
@Override
public void onFailure(String source, Exception e) {
logger.warn("unexpected failure", e);
}
});
logger.info("--> waiting for listener to be called and cluster state being blocked");
listenerCalled.await();
TransportClusterHealthAction action = new TransportClusterHealthAction(Settings.EMPTY, transportService, clusterService, threadPool, new ActionFilters(new HashSet<>()), indexNameExpressionResolver, new TestGatewayAllocator());
PlainActionFuture<ClusterHealthResponse> listener = new PlainActionFuture<>();
action.execute(new ClusterHealthRequest().waitForGreenStatus(), listener);
assertFalse(listener.isDone());
logger.info("--> realising task to restore master");
applyLatch.countDown();
listener.get();
}
use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.
the class Gateway method performStateRecovery.
public void performStateRecovery(final GatewayStateRecoveredListener listener) throws GatewayException {
final DiscoveryNode[] nodes = clusterService.state().nodes().getMasterNodes().values().toArray(DiscoveryNode.class);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("performing state recovery from {}", Arrays.toString(nodes));
}
var request = new TransportNodesListGatewayMetaState.Request(nodes);
PlainActionFuture<TransportNodesListGatewayMetaState.NodesGatewayMetaState> future = PlainActionFuture.newFuture();
client.executeLocally(TransportNodesListGatewayMetaState.TYPE, request, future);
final TransportNodesListGatewayMetaState.NodesGatewayMetaState nodesState = future.actionGet();
final int requiredAllocation = 1;
if (nodesState.hasFailures()) {
for (final FailedNodeException failedNodeException : nodesState.failures()) {
LOGGER.warn("failed to fetch state from node", failedNodeException);
}
}
final ObjectFloatHashMap<Index> indices = new ObjectFloatHashMap<>();
Metadata electedGlobalState = null;
int found = 0;
for (final TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) {
if (nodeState.metadata() == null) {
continue;
}
found++;
if (electedGlobalState == null) {
electedGlobalState = nodeState.metadata();
} else if (nodeState.metadata().version() > electedGlobalState.version()) {
electedGlobalState = nodeState.metadata();
}
for (final ObjectCursor<IndexMetadata> cursor : nodeState.metadata().indices().values()) {
indices.addTo(cursor.value.getIndex(), 1);
}
}
if (found < requiredAllocation) {
listener.onFailure("found [" + found + "] metadata states, required [" + requiredAllocation + "]");
return;
}
// update the global state, and clean the indices, we elect them in the next phase
final Metadata.Builder metadataBuilder = Metadata.builder(electedGlobalState).removeAllIndices();
assert !indices.containsKey(null);
final Object[] keys = indices.keys;
for (int i = 0; i < keys.length; i++) {
if (keys[i] != null) {
final Index index = (Index) keys[i];
IndexMetadata electedIndexMetadata = null;
int indexMetadataCount = 0;
for (final TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) {
if (nodeState.metadata() == null) {
continue;
}
final IndexMetadata indexMetadata = nodeState.metadata().index(index);
if (indexMetadata == null) {
continue;
}
if (electedIndexMetadata == null) {
electedIndexMetadata = indexMetadata;
} else if (indexMetadata.getVersion() > electedIndexMetadata.getVersion()) {
electedIndexMetadata = indexMetadata;
}
indexMetadataCount++;
}
if (electedIndexMetadata != null) {
if (indexMetadataCount < requiredAllocation) {
LOGGER.debug("[{}] found [{}], required [{}], not adding", index, indexMetadataCount, requiredAllocation);
}
// TODO if this logging statement is correct then we are missing an else here
metadataBuilder.put(electedIndexMetadata, false);
}
}
}
ClusterState recoveredState = Function.<ClusterState>identity().andThen(state -> ClusterStateUpdaters.upgradeAndArchiveUnknownOrInvalidSettings(state, clusterService.getClusterSettings())).apply(ClusterState.builder(clusterService.getClusterName()).metadata(metadataBuilder).build());
listener.onSuccess(recoveredState);
}
use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.
the class PutHeadChunkRunnable method run.
@Override
public void run() {
FileInputStream fileInputStream = null;
try {
int bufSize = 4096;
int bytesRead;
int size;
int maxFileGrowthWait = 5;
int fileGrowthWaited = 0;
byte[] buffer = new byte[bufSize];
long remainingBytes = bytesToSend;
File pendingFile;
try {
pendingFile = digestBlob.file();
if (pendingFile == null) {
pendingFile = digestBlob.getContainerFile();
}
fileInputStream = new FileInputStream(pendingFile);
} catch (FileNotFoundException e) {
// this happens if the file has already been moved from tmpDirectory to containerDirectory
pendingFile = digestBlob.getContainerFile();
fileInputStream = new FileInputStream(pendingFile);
}
while (remainingBytes > 0) {
size = (int) Math.min(bufSize, remainingBytes);
bytesRead = fileInputStream.read(buffer, 0, size);
if (bytesRead < size) {
waitUntilFileHasGrown(pendingFile);
fileGrowthWaited++;
if (fileGrowthWaited == maxFileGrowthWait) {
throw new HeadChunkFileTooSmallException(pendingFile.getAbsolutePath());
}
if (bytesRead < 1) {
continue;
}
}
remainingBytes -= bytesRead;
var listener = new PlainActionFuture<TransportResponse>();
transportService.sendRequest(recipientNode, BlobHeadRequestHandler.Actions.PUT_BLOB_HEAD_CHUNK, new PutBlobHeadChunkRequest(transferId, new BytesArray(buffer, 0, bytesRead)), TransportRequestOptions.EMPTY, new ActionListenerResponseHandler<>(listener, in -> TransportResponse.Empty.INSTANCE));
listener.actionGet();
}
} catch (IOException ex) {
LOGGER.error("IOException in PutHeadChunkRunnable", ex);
} finally {
blobTransferTarget.putHeadChunkTransferFinished(transferId);
if (watcher != null) {
try {
watcher.close();
} catch (IOException e) {
LOGGER.error("Error closing WatchService in {}", e, getClass().getSimpleName());
}
}
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
LOGGER.error("Error closing HeadChunk", e);
}
}
}
}
Aggregations