Search in sources :

Example 31 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.

the class BlobRecoveryHandler method deleteFilesRequest.

private void deleteFilesRequest(BytesArray[] digests) {
    var listener = new PlainActionFuture<TransportResponse>();
    transportService.sendRequest(request.targetNode(), BlobRecoveryTarget.Actions.DELETE_FILE, new BlobRecoveryDeleteRequest(request.recoveryId(), digests), TransportRequestOptions.EMPTY, new ActionListenerResponseHandler<>(listener, in -> TransportResponse.Empty.INSTANCE));
    listener.actionGet();
}
Also used : ElasticsearchException(org.elasticsearch.ElasticsearchException) CancellableThreads(org.elasticsearch.common.util.CancellableThreads) StartRecoveryRequest(org.elasticsearch.indices.recovery.StartRecoveryRequest) BlobIndex(io.crate.blob.v2.BlobIndex) BlobRecoveryTarget(org.elasticsearch.indices.recovery.BlobRecoveryTarget) IndexShardClosedException(org.elasticsearch.index.shard.IndexShardClosedException) BlobShard(io.crate.blob.v2.BlobShard) BlobRecoveryDeleteRequest(org.elasticsearch.indices.recovery.BlobRecoveryDeleteRequest) AtomicReference(java.util.concurrent.atomic.AtomicReference) RecoveryTargetHandler(org.elasticsearch.indices.recovery.RecoveryTargetHandler) BytesArray(org.elasticsearch.common.bytes.BytesArray) RecoverySourceHandler(org.elasticsearch.indices.recovery.RecoverySourceHandler) HashSet(java.util.HashSet) BlobRecoveryStartTransferRequest(org.elasticsearch.indices.recovery.BlobRecoveryStartTransferRequest) ActionListenerResponseHandler(org.elasticsearch.action.ActionListenerResponseHandler) BlobStartPrefixResponse(org.elasticsearch.indices.recovery.BlobStartPrefixResponse) BlobStartPrefixSyncRequest(org.elasticsearch.indices.recovery.BlobStartPrefixSyncRequest) TransportResponse(org.elasticsearch.transport.TransportResponse) TransportService(org.elasticsearch.transport.TransportService) BlobContainer(io.crate.blob.BlobContainer) IndexShardState(org.elasticsearch.index.shard.IndexShardState) BlobRecoveryChunkRequest(org.elasticsearch.indices.recovery.BlobRecoveryChunkRequest) BlobStartRecoveryRequest(org.elasticsearch.indices.recovery.BlobStartRecoveryRequest) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) IndexShard(org.elasticsearch.index.shard.IndexShard) Set(java.util.Set) IOException(java.io.IOException) BlobIndicesService(io.crate.blob.v2.BlobIndicesService) StopWatch(org.elasticsearch.common.StopWatch) FileInputStream(java.io.FileInputStream) BytesReference(org.elasticsearch.common.bytes.BytesReference) Hex(io.crate.common.Hex) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) BlobTransferTarget(io.crate.blob.BlobTransferTarget) CountDownLatch(java.util.concurrent.CountDownLatch) Logger(org.apache.logging.log4j.Logger) BlobFinalizeRecoveryRequest(org.elasticsearch.indices.recovery.BlobFinalizeRecoveryRequest) TransportRequestOptions(org.elasticsearch.transport.TransportRequestOptions) LogManager(org.apache.logging.log4j.LogManager) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) BlobRecoveryDeleteRequest(org.elasticsearch.indices.recovery.BlobRecoveryDeleteRequest)

Example 32 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.

the class IndexRecoveryIT method testUsesFileBasedRecoveryIfRetentionLeaseMissing.

@Test
public void testUsesFileBasedRecoveryIfRetentionLeaseMissing() throws Exception {
    internalCluster().ensureAtLeastNumDataNodes(2);
    String indexName = "test";
    execute("CREATE TABLE doc.test (num INT)" + " CLUSTERED INTO 1 SHARDS" + " WITH (" + "  number_of_replicas = 1," + "  \"unassigned.node_left.delayed_timeout\"='12h'," + "  \"soft_deletes.enabled\"=true" + " )");
    int numDocs = randomIntBetween(1, 100);
    var args = new Object[numDocs][];
    for (int i = 0; i < numDocs; i++) {
        args[i] = new Object[] { i };
    }
    execute("INSERT INTO doc.test (num) VALUES (?)", args);
    ensureGreen(indexName);
    final ShardId shardId = new ShardId(resolveIndex(indexName), 0);
    final DiscoveryNodes discoveryNodes = clusterService().state().nodes();
    final IndexShardRoutingTable indexShardRoutingTable = clusterService().state().routingTable().shardRoutingTable(shardId);
    final IndexShard primary = internalCluster().getInstance(IndicesService.class, discoveryNodes.get(indexShardRoutingTable.primaryShard().currentNodeId()).getName()).getShardOrNull(shardId);
    final ShardRouting replicaShardRouting = indexShardRoutingTable.replicaShards().get(0);
    internalCluster().restartNode(discoveryNodes.get(replicaShardRouting.currentNodeId()).getName(), new InternalTestCluster.RestartCallback() {

        @Override
        public Settings onNodeStopped(String nodeName) throws Exception {
            assertFalse(client().admin().cluster().prepareHealth().setWaitForNodes(Integer.toString(discoveryNodes.getSize() - 1)).setWaitForEvents(Priority.LANGUID).get().isTimedOut());
            final PlainActionFuture<ReplicationResponse> future = new PlainActionFuture<>();
            primary.removeRetentionLease(ReplicationTracker.getPeerRecoveryRetentionLeaseId(replicaShardRouting), future);
            future.get();
            return super.onNodeStopped(nodeName);
        }
    });
    ensureGreen(indexName);
    // noinspection OptionalGetWithoutIsPresent because it fails the test if absent
    final var recoveryState = client().execute(RecoveryAction.INSTANCE, new RecoveryRequest()).get().shardRecoveryStates().get(indexName).stream().filter(rs -> rs.getPrimary() == false).findFirst().get();
    assertThat(recoveryState.getIndex().totalFileCount(), greaterThan(0));
}
Also used : IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) IndexShard(org.elasticsearch.index.shard.IndexShard) IndicesService(org.elasticsearch.indices.IndicesService) InternalTestCluster(org.elasticsearch.test.InternalTestCluster) ConnectTransportException(org.elasticsearch.transport.ConnectTransportException) IOException(java.io.IOException) EsRejectedExecutionException(org.elasticsearch.common.util.concurrent.EsRejectedExecutionException) MapperParsingException(org.elasticsearch.index.mapper.MapperParsingException) CircuitBreakingException(org.elasticsearch.common.breaker.CircuitBreakingException) ShardId(org.elasticsearch.index.shard.ShardId) RecoveryRequest(org.elasticsearch.action.admin.indices.recovery.RecoveryRequest) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes) Settings(org.elasticsearch.common.settings.Settings) IndexSettings(org.elasticsearch.index.IndexSettings) Test(org.junit.Test)

Example 33 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.

the class RecoverySourceHandlerTests method testSendOperationsConcurrently.

public void testSendOperationsConcurrently() throws Throwable {
    final IndexShard shard = mock(IndexShard.class);
    when(shard.state()).thenReturn(IndexShardState.STARTED);
    Set<Long> receivedSeqNos = ConcurrentCollections.newConcurrentSet();
    long maxSeenAutoIdTimestamp = randomBoolean() ? -1 : randomNonNegativeLong();
    long maxSeqNoOfUpdatesOrDeletes = randomBoolean() ? -1 : randomNonNegativeLong();
    RetentionLeases retentionLeases = new RetentionLeases(randomNonNegativeLong(), randomNonNegativeLong(), Collections.emptySet());
    long mappingVersion = randomNonNegativeLong();
    AtomicLong localCheckpoint = new AtomicLong(SequenceNumbers.NO_OPS_PERFORMED);
    int numOps = randomIntBetween(0, 1000);
    AtomicBoolean received = new AtomicBoolean();
    RecoveryTargetHandler target = new TestRecoveryTargetHandler() {

        @Override
        public void indexTranslogOperations(List<Translog.Operation> operations, int receivedTotalOps, long receivedMaxSeenAutoIdTimestamp, long receivedMaxSeqNoOfUpdatesOrDeletes, RetentionLeases receivedRetentionLease, long receivedMappingVersion, ActionListener<Long> listener) {
            received.set(true);
            assertThat(receivedMaxSeenAutoIdTimestamp, equalTo(maxSeenAutoIdTimestamp));
            assertThat(receivedMaxSeqNoOfUpdatesOrDeletes, equalTo(maxSeqNoOfUpdatesOrDeletes));
            assertThat(receivedRetentionLease, equalTo(retentionLeases));
            assertThat(receivedMappingVersion, equalTo(mappingVersion));
            assertThat(receivedTotalOps, equalTo(numOps));
            for (Translog.Operation operation : operations) {
                receivedSeqNos.add(operation.seqNo());
            }
            if (randomBoolean()) {
                localCheckpoint.addAndGet(randomIntBetween(1, 100));
            }
            listener.onResponse(localCheckpoint.get());
        }
    };
    PlainActionFuture<RecoverySourceHandler.SendSnapshotResult> sendFuture = new PlainActionFuture<>();
    long startingSeqNo = randomIntBetween(0, 1000);
    long endingSeqNo = startingSeqNo + randomIntBetween(0, 10000);
    List<Translog.Operation> operations = generateOperations(numOps);
    Randomness.shuffle(operations);
    List<Translog.Operation> skipOperations = randomSubsetOf(operations);
    Translog.Snapshot snapshot = newTranslogSnapshot(operations, skipOperations);
    RecoverySourceHandler handler = new RecoverySourceHandler(shard, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool, getStartRecoveryRequest(), between(1, 10 * 1024), between(1, 5), between(1, 5));
    handler.phase2(startingSeqNo, endingSeqNo, snapshot, maxSeenAutoIdTimestamp, maxSeqNoOfUpdatesOrDeletes, retentionLeases, mappingVersion, sendFuture);
    RecoverySourceHandler.SendSnapshotResult sendSnapshotResult = sendFuture.actionGet();
    assertTrue(received.get());
    assertThat(sendSnapshotResult.targetLocalCheckpoint, equalTo(localCheckpoint.get()));
    assertThat(sendSnapshotResult.sentOperations, equalTo(receivedSeqNos.size()));
    Set<Long> sentSeqNos = new HashSet<>();
    for (Translog.Operation op : operations) {
        if (startingSeqNo <= op.seqNo() && op.seqNo() <= endingSeqNo && skipOperations.contains(op) == false) {
            sentSeqNos.add(op.seqNo());
        }
    }
    assertThat(receivedSeqNos, equalTo(sentSeqNos));
}
Also used : IndexShard(org.elasticsearch.index.shard.IndexShard) RetentionLeases(org.elasticsearch.index.seqno.RetentionLeases) Translog(org.elasticsearch.index.translog.Translog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) ActionListener(org.elasticsearch.action.ActionListener) LatchedActionListener(org.elasticsearch.action.LatchedActionListener) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) AtomicLong(java.util.concurrent.atomic.AtomicLong) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 34 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.

the class RecoverySourceHandlerTests method testHandleExceptionOnSendFiles.

@Test
public void testHandleExceptionOnSendFiles() throws Throwable {
    final RecoverySettings recoverySettings = new RecoverySettings(Settings.EMPTY, service);
    final StartRecoveryRequest request = getStartRecoveryRequest();
    Path tempDir = createTempDir();
    Store store = newStore(tempDir, false);
    AtomicBoolean failedEngine = new AtomicBoolean(false);
    Directory dir = store.directory();
    RandomIndexWriter writer = new RandomIndexWriter(random(), dir, newIndexWriterConfig());
    int numDocs = randomIntBetween(10, 100);
    for (int i = 0; i < numDocs; i++) {
        Document document = new Document();
        document.add(new StringField("id", Integer.toString(i), Field.Store.YES));
        document.add(newField("field", randomUnicodeOfCodepointLengthBetween(1, 10), TextField.TYPE_STORED));
        writer.addDocument(document);
    }
    writer.commit();
    writer.close();
    Store.MetadataSnapshot metadata = store.getMetadata(null);
    List<StoreFileMetadata> metas = new ArrayList<>();
    for (StoreFileMetadata md : metadata) {
        metas.add(md);
    }
    final boolean throwCorruptedIndexException = randomBoolean();
    RecoveryTargetHandler target = new TestRecoveryTargetHandler() {

        @Override
        public void writeFileChunk(StoreFileMetadata md, long position, BytesReference content, boolean lastChunk, int totalTranslogOps, ActionListener<Void> listener) {
            if (throwCorruptedIndexException) {
                listener.onFailure(new RuntimeException(new CorruptIndexException("foo", "bar")));
            } else {
                listener.onFailure(new RuntimeException("boom"));
            }
        }
    };
    RecoverySourceHandler handler = new RecoverySourceHandler(null, new AsyncRecoveryTarget(target, recoveryExecutor), threadPool, request, Math.toIntExact(recoverySettings.getChunkSize().getBytes()), between(1, 10), between(1, 4)) {

        @Override
        protected void failEngine(IOException cause) {
            assertFalse(failedEngine.get());
            failedEngine.set(true);
        }
    };
    PlainActionFuture<Void> sendFilesFuture = new PlainActionFuture<>();
    handler.sendFiles(store, metas.toArray(new StoreFileMetadata[0]), () -> 0, sendFilesFuture);
    Exception ex = expectThrows(Exception.class, sendFilesFuture::actionGet);
    final IOException unwrappedCorruption = ExceptionsHelper.unwrapCorruption(ex);
    if (throwCorruptedIndexException) {
        assertNotNull(unwrappedCorruption);
        assertEquals(ex.getMessage(), "[File corruption occurred on recovery but checksums are ok]");
    } else {
        assertNull(unwrappedCorruption);
        assertEquals(ex.getMessage(), "boom");
    }
    assertFalse(failedEngine.get());
    IOUtils.close(store);
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Store(org.elasticsearch.index.store.Store) StoreFileMetadata(org.elasticsearch.index.store.StoreFileMetadata) Document(org.apache.lucene.document.Document) ParsedDocument(org.elasticsearch.index.mapper.ParsedDocument) Directory(org.apache.lucene.store.Directory) Path(java.nio.file.Path) BytesReference(org.elasticsearch.common.bytes.BytesReference) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) IOException(java.io.IOException) IndexShardRelocatedException(org.elasticsearch.index.shard.IndexShardRelocatedException) IOException(java.io.IOException) RecoveryEngineException(org.elasticsearch.index.engine.RecoveryEngineException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ActionListener(org.elasticsearch.action.ActionListener) LatchedActionListener(org.elasticsearch.action.LatchedActionListener) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) StringField(org.apache.lucene.document.StringField) RandomIndexWriter(org.apache.lucene.index.RandomIndexWriter) Test(org.junit.Test)

Example 35 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project crate by crate.

the class RecoverySourceHandlerTests method testSendSnapshotStopOnError.

@Test
public void testSendSnapshotStopOnError() throws Exception {
    final int fileChunkSizeInBytes = between(1, 10 * 1024);
    final StartRecoveryRequest request = getStartRecoveryRequest();
    final IndexShard shard = mock(IndexShard.class);
    when(shard.state()).thenReturn(IndexShardState.STARTED);
    final List<Translog.Operation> ops = new ArrayList<>();
    for (int numOps = between(1, 256), i = 0; i < numOps; i++) {
        final Engine.Index index = getIndex(Integer.toString(i));
        ops.add(new Translog.Index(index, new Engine.IndexResult(1, 1, i, true)));
    }
    final AtomicBoolean wasFailed = new AtomicBoolean();
    RecoveryTargetHandler recoveryTarget = new TestRecoveryTargetHandler() {

        @Override
        public void indexTranslogOperations(List<Translog.Operation> operations, int totalTranslogOps, long timestamp, long msu, RetentionLeases retentionLeases, long mappingVersion, ActionListener<Long> listener) {
            if (randomBoolean()) {
                listener.onResponse(SequenceNumbers.NO_OPS_PERFORMED);
            } else {
                listener.onFailure(new RuntimeException("test - failed to index"));
                wasFailed.set(true);
            }
        }
    };
    RecoverySourceHandler handler = new RecoverySourceHandler(shard, new AsyncRecoveryTarget(recoveryTarget, threadPool.generic()), threadPool, request, fileChunkSizeInBytes, between(1, 10), between(1, 10));
    PlainActionFuture<RecoverySourceHandler.SendSnapshotResult> future = new PlainActionFuture<>();
    final long startingSeqNo = randomLongBetween(0, ops.size() - 1L);
    final long endingSeqNo = randomLongBetween(startingSeqNo, ops.size() - 1L);
    handler.phase2(startingSeqNo, endingSeqNo, newTranslogSnapshot(ops, Collections.emptyList()), randomNonNegativeLong(), randomNonNegativeLong(), RetentionLeases.EMPTY, randomNonNegativeLong(), future);
    if (wasFailed.get()) {
        final RecoveryEngineException error = expectThrows(RecoveryEngineException.class, future::actionGet);
        assertThat(error.getMessage(), equalTo("Phase[2] failed to send/replay operations"));
        assertThat(error.getCause().getMessage(), equalTo("test - failed to index"));
    }
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) Translog(org.elasticsearch.index.translog.Translog) RecoveryEngineException(org.elasticsearch.index.engine.RecoveryEngineException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Engine(org.elasticsearch.index.engine.Engine) IndexShard(org.elasticsearch.index.shard.IndexShard) RetentionLeases(org.elasticsearch.index.seqno.RetentionLeases) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ActionListener(org.elasticsearch.action.ActionListener) LatchedActionListener(org.elasticsearch.action.LatchedActionListener) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) Test(org.junit.Test)

Aggregations

PlainActionFuture (org.elasticsearch.action.support.PlainActionFuture)82 ShardId (org.elasticsearch.index.shard.ShardId)37 ClusterState (org.elasticsearch.cluster.ClusterState)28 ExecutionException (java.util.concurrent.ExecutionException)27 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)25 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)21 IOException (java.io.IOException)20 ArrayList (java.util.ArrayList)20 Test (org.junit.Test)20 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)18 ElasticsearchException (org.elasticsearch.ElasticsearchException)17 TransportRequest (org.elasticsearch.transport.TransportRequest)17 Matchers.anyString (org.mockito.Matchers.anyString)17 HashSet (java.util.HashSet)16 List (java.util.List)16 CloseIndexRequest (org.elasticsearch.action.admin.indices.close.CloseIndexRequest)16 IndexShard (org.elasticsearch.index.shard.IndexShard)16 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)16 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)15 ClusterBlockException (org.elasticsearch.cluster.block.ClusterBlockException)13