Search in sources :

Example 31 with StepListener

use of org.opensearch.action.StepListener in project OpenSearch by opensearch-project.

the class RecoverySourceHandler method phase1.

/**
 * Perform phase1 of the recovery operations. Once this {@link IndexCommit}
 * snapshot has been performed no commit operations (files being fsync'd)
 * are effectively allowed on this index until all recovery phases are done
 * <p>
 * Phase1 examines the segment files on the target node and copies over the
 * segments that are missing. Only segments that have the same size and
 * checksum can be reused
 */
void phase1(IndexCommit snapshot, long startingSeqNo, IntSupplier translogOps, ActionListener<SendFileResult> listener) {
    cancellableThreads.checkForCancel();
    final Store store = shard.store();
    try {
        StopWatch stopWatch = new StopWatch().start();
        final Store.MetadataSnapshot recoverySourceMetadata;
        try {
            recoverySourceMetadata = store.getMetadata(snapshot);
        } catch (CorruptIndexException | IndexFormatTooOldException | IndexFormatTooNewException ex) {
            shard.failShard("recovery", ex);
            throw ex;
        }
        for (String name : snapshot.getFileNames()) {
            final StoreFileMetadata md = recoverySourceMetadata.get(name);
            if (md == null) {
                logger.info("Snapshot differs from actual index for file: {} meta: {}", name, recoverySourceMetadata.asMap());
                throw new CorruptIndexException("Snapshot differs from actual index - maybe index was removed metadata has " + recoverySourceMetadata.asMap().size() + " files", name);
            }
        }
        if (canSkipPhase1(recoverySourceMetadata, request.metadataSnapshot()) == false) {
            final List<String> phase1FileNames = new ArrayList<>();
            final List<Long> phase1FileSizes = new ArrayList<>();
            final List<String> phase1ExistingFileNames = new ArrayList<>();
            final List<Long> phase1ExistingFileSizes = new ArrayList<>();
            // Total size of segment files that are recovered
            long totalSizeInBytes = 0;
            // Total size of segment files that were able to be re-used
            long existingTotalSizeInBytes = 0;
            // Generate a "diff" of all the identical, different, and missing
            // segment files on the target node, using the existing files on
            // the source node
            final Store.RecoveryDiff diff = recoverySourceMetadata.recoveryDiff(request.metadataSnapshot());
            for (StoreFileMetadata md : diff.identical) {
                phase1ExistingFileNames.add(md.name());
                phase1ExistingFileSizes.add(md.length());
                existingTotalSizeInBytes += md.length();
                if (logger.isTraceEnabled()) {
                    logger.trace("recovery [phase1]: not recovering [{}], exist in local store and has checksum [{}]," + " size [{}]", md.name(), md.checksum(), md.length());
                }
                totalSizeInBytes += md.length();
            }
            List<StoreFileMetadata> phase1Files = new ArrayList<>(diff.different.size() + diff.missing.size());
            phase1Files.addAll(diff.different);
            phase1Files.addAll(diff.missing);
            for (StoreFileMetadata md : phase1Files) {
                if (request.metadataSnapshot().asMap().containsKey(md.name())) {
                    logger.trace("recovery [phase1]: recovering [{}], exists in local store, but is different: remote [{}], local [{}]", md.name(), request.metadataSnapshot().asMap().get(md.name()), md);
                } else {
                    logger.trace("recovery [phase1]: recovering [{}], does not exist in remote", md.name());
                }
                phase1FileNames.add(md.name());
                phase1FileSizes.add(md.length());
                totalSizeInBytes += md.length();
            }
            logger.trace("recovery [phase1]: recovering_files [{}] with total_size [{}], reusing_files [{}] with total_size [{}]", phase1FileNames.size(), new ByteSizeValue(totalSizeInBytes), phase1ExistingFileNames.size(), new ByteSizeValue(existingTotalSizeInBytes));
            final StepListener<Void> sendFileInfoStep = new StepListener<>();
            final StepListener<Void> sendFilesStep = new StepListener<>();
            final StepListener<RetentionLease> createRetentionLeaseStep = new StepListener<>();
            final StepListener<Void> cleanFilesStep = new StepListener<>();
            cancellableThreads.checkForCancel();
            recoveryTarget.receiveFileInfo(phase1FileNames, phase1FileSizes, phase1ExistingFileNames, phase1ExistingFileSizes, translogOps.getAsInt(), sendFileInfoStep);
            sendFileInfoStep.whenComplete(r -> sendFiles(store, phase1Files.toArray(new StoreFileMetadata[0]), translogOps, sendFilesStep), listener::onFailure);
            sendFilesStep.whenComplete(r -> createRetentionLease(startingSeqNo, createRetentionLeaseStep), listener::onFailure);
            createRetentionLeaseStep.whenComplete(retentionLease -> {
                final long lastKnownGlobalCheckpoint = shard.getLastKnownGlobalCheckpoint();
                assert retentionLease == null || retentionLease.retainingSequenceNumber() - 1 <= lastKnownGlobalCheckpoint : retentionLease + " vs " + lastKnownGlobalCheckpoint;
                // Establishes new empty translog on the replica with global checkpoint set to lastKnownGlobalCheckpoint. We want
                // the commit we just copied to be a safe commit on the replica, so why not set the global checkpoint on the replica
                // to the max seqno of this commit? Because (in rare corner cases) this commit might not be a safe commit here on
                // the primary, and in these cases the max seqno would be too high to be valid as a global checkpoint.
                cleanFiles(store, recoverySourceMetadata, translogOps, lastKnownGlobalCheckpoint, cleanFilesStep);
            }, listener::onFailure);
            final long totalSize = totalSizeInBytes;
            final long existingTotalSize = existingTotalSizeInBytes;
            cleanFilesStep.whenComplete(r -> {
                final TimeValue took = stopWatch.totalTime();
                logger.trace("recovery [phase1]: took [{}]", took);
                listener.onResponse(new SendFileResult(phase1FileNames, phase1FileSizes, totalSize, phase1ExistingFileNames, phase1ExistingFileSizes, existingTotalSize, took));
            }, listener::onFailure);
        } else {
            logger.trace("skipping [phase1] since source and target have identical sync id [{}]", recoverySourceMetadata.getSyncId());
            // but we must still create a retention lease
            final StepListener<RetentionLease> createRetentionLeaseStep = new StepListener<>();
            createRetentionLease(startingSeqNo, createRetentionLeaseStep);
            createRetentionLeaseStep.whenComplete(retentionLease -> {
                final TimeValue took = stopWatch.totalTime();
                logger.trace("recovery [phase1]: took [{}]", took);
                listener.onResponse(new SendFileResult(Collections.emptyList(), Collections.emptyList(), 0L, Collections.emptyList(), Collections.emptyList(), 0L, took));
            }, listener::onFailure);
        }
    } catch (Exception e) {
        throw new RecoverFilesRecoveryException(request.shardId(), 0, new ByteSizeValue(0L), e);
    }
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ByteSizeValue(org.opensearch.common.unit.ByteSizeValue) Store(org.opensearch.index.store.Store) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException) TimeValue(org.opensearch.common.unit.TimeValue) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) RemoteTransportException(org.opensearch.transport.RemoteTransportException) IndexShardClosedException(org.opensearch.index.shard.IndexShardClosedException) IOException(java.io.IOException) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException) IndexShardRelocatedException(org.opensearch.index.shard.IndexShardRelocatedException) RetentionLeaseNotFoundException(org.opensearch.index.seqno.RetentionLeaseNotFoundException) StopWatch(org.opensearch.common.StopWatch) RetentionLease(org.opensearch.index.seqno.RetentionLease) AtomicLong(java.util.concurrent.atomic.AtomicLong) StepListener(org.opensearch.action.StepListener) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException)

Example 32 with StepListener

use of org.opensearch.action.StepListener in project OpenSearch by opensearch-project.

the class SnapshotResiliencyTests method testConcurrentSnapshotDeleteAndDeleteIndex.

public void testConcurrentSnapshotDeleteAndDeleteIndex() throws IOException {
    setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10));
    String repoName = "repo";
    String snapshotName = "snapshot";
    final String index = "test";
    TestClusterNodes.TestClusterNode masterNode = testClusterNodes.currentMaster(testClusterNodes.nodes.values().iterator().next().clusterService.state());
    final StepListener<Collection<CreateIndexResponse>> createIndicesListener = new StepListener<>();
    final int indices = randomIntBetween(5, 20);
    final SetOnce<Index> firstIndex = new SetOnce<>();
    continueOrDie(createRepoAndIndex(repoName, index, 1), createIndexResponse -> {
        firstIndex.set(masterNode.clusterService.state().metadata().index(index).getIndex());
        // create a few more indices to make it more likely that the subsequent index delete operation happens before snapshot
        // finalization
        final GroupedActionListener<CreateIndexResponse> listener = new GroupedActionListener<>(createIndicesListener, indices);
        for (int i = 0; i < indices; ++i) {
            client().admin().indices().create(new CreateIndexRequest("index-" + i), listener);
        }
    });
    final StepListener<CreateSnapshotResponse> createSnapshotResponseStepListener = new StepListener<>();
    final boolean partialSnapshot = randomBoolean();
    continueOrDie(createIndicesListener, createIndexResponses -> client().admin().cluster().prepareCreateSnapshot(repoName, snapshotName).setWaitForCompletion(false).setPartial(partialSnapshot).setIncludeGlobalState(randomBoolean()).execute(createSnapshotResponseStepListener));
    continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> client().admin().indices().delete(new DeleteIndexRequest(index), new ActionListener<AcknowledgedResponse>() {

        @Override
        public void onResponse(AcknowledgedResponse acknowledgedResponse) {
            if (partialSnapshot) {
                // Recreate index by the same name to test that we don't snapshot conflicting metadata in this scenario
                client().admin().indices().create(new CreateIndexRequest(index), noopListener());
            }
        }

        @Override
        public void onFailure(Exception e) {
            if (partialSnapshot) {
                throw new AssertionError("Delete index should always work during partial snapshots", e);
            }
        }
    }));
    deterministicTaskQueue.runAllRunnableTasks();
    SnapshotsInProgress finalSnapshotsInProgress = masterNode.clusterService.state().custom(SnapshotsInProgress.TYPE);
    assertFalse(finalSnapshotsInProgress.entries().stream().anyMatch(entry -> entry.state().completed() == false));
    final Repository repository = masterNode.repositoriesService.repository(repoName);
    final RepositoryData repositoryData = getRepositoryData(repository);
    Collection<SnapshotId> snapshotIds = repositoryData.getSnapshotIds();
    assertThat(snapshotIds, hasSize(1));
    final SnapshotInfo snapshotInfo = repository.getSnapshotInfo(snapshotIds.iterator().next());
    if (partialSnapshot) {
        assertThat(snapshotInfo.state(), either(is(SnapshotState.SUCCESS)).or(is(SnapshotState.PARTIAL)));
        // Single shard for each index so we either get all indices or all except for the deleted index
        assertThat(snapshotInfo.successfulShards(), either(is(indices + 1)).or(is(indices)));
        if (snapshotInfo.successfulShards() == indices + 1) {
            final IndexMetadata indexMetadata = repository.getSnapshotIndexMetaData(repositoryData, snapshotInfo.snapshotId(), repositoryData.resolveIndexId(index));
            // Make sure we snapshotted the metadata of this index and not the recreated version
            assertEquals(indexMetadata.getIndex(), firstIndex.get());
        }
    } else {
        assertEquals(snapshotInfo.state(), SnapshotState.SUCCESS);
        // Index delete must be blocked for non-partial snapshots and we get a snapshot for every index
        assertEquals(snapshotInfo.successfulShards(), indices + 1);
    }
    assertEquals(0, snapshotInfo.failedShards());
}
Also used : PrioritizedOpenSearchThreadPoolExecutor(org.opensearch.common.util.concurrent.PrioritizedOpenSearchThreadPoolExecutor) Version(org.opensearch.Version) TransportPutMappingAction(org.opensearch.action.admin.indices.mapping.put.TransportPutMappingAction) BulkAction(org.opensearch.action.bulk.BulkAction) TransportPutRepositoryAction(org.opensearch.action.admin.cluster.repositories.put.TransportPutRepositoryAction) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) WriteRequest(org.opensearch.action.support.WriteRequest) RestoreSnapshotRequest(org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest) OpenSearchAllocationTestCase(org.opensearch.cluster.OpenSearchAllocationTestCase) Map(java.util.Map) PutMappingAction(org.opensearch.action.admin.indices.mapping.put.PutMappingAction) Path(java.nio.file.Path) ShardStateAction(org.opensearch.cluster.action.shard.ShardStateAction) NodeEnvironment(org.opensearch.env.NodeEnvironment) NodeClient(org.opensearch.client.node.NodeClient) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) MasterService(org.opensearch.cluster.service.MasterService) IndexingPressureService(org.opensearch.index.IndexingPressureService) TransportResyncReplicationAction(org.opensearch.action.resync.TransportResyncReplicationAction) ExceptionsHelper(org.opensearch.ExceptionsHelper) HEALTHY(org.opensearch.monitor.StatusInfo.Status.HEALTHY) TransportService(org.opensearch.transport.TransportService) TransportClusterRerouteAction(org.opensearch.action.admin.cluster.reroute.TransportClusterRerouteAction) Logger(org.apache.logging.log4j.Logger) Stream(java.util.stream.Stream) ActionTestUtils(org.opensearch.action.support.ActionTestUtils) IndexNameExpressionResolver(org.opensearch.cluster.metadata.IndexNameExpressionResolver) Mockito.mock(org.mockito.Mockito.mock) SearchAction(org.opensearch.action.search.SearchAction) TransportRequestHandler(org.opensearch.transport.TransportRequestHandler) ThreadPool(org.opensearch.threadpool.ThreadPool) Supplier(java.util.function.Supplier) LinkedHashMap(java.util.LinkedHashMap) RestoreSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse) ResponseCollectorService(org.opensearch.node.ResponseCollectorService) MapperRegistry(org.opensearch.indices.mapper.MapperRegistry) RestoreSnapshotAction(org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotAction) Matchers.hasSize(org.hamcrest.Matchers.hasSize) ElectionStrategy(org.opensearch.cluster.coordination.ElectionStrategy) Before(org.junit.Before) DisruptableMockTransport(org.opensearch.test.disruption.DisruptableMockTransport) IOException(java.io.IOException) AnalysisModule(org.opensearch.indices.analysis.AnalysisModule) RetentionLeaseSyncer(org.opensearch.index.seqno.RetentionLeaseSyncer) PageCacheRecycler(org.opensearch.common.util.PageCacheRecycler) DestructiveOperations(org.opensearch.action.support.DestructiveOperations) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) FetchPhase(org.opensearch.search.fetch.FetchPhase) BulkRequest(org.opensearch.action.bulk.BulkRequest) DeleteSnapshotAction(org.opensearch.action.admin.cluster.snapshots.delete.DeleteSnapshotAction) IndicesShardStoresAction(org.opensearch.action.admin.indices.shards.IndicesShardStoresAction) SearchTransportService(org.opensearch.action.search.SearchTransportService) MetadataIndexUpgradeService(org.opensearch.cluster.metadata.MetadataIndexUpgradeService) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Coordinator(org.opensearch.cluster.coordination.Coordinator) UnassignedInfo(org.opensearch.cluster.routing.UnassignedInfo) RecoverySettings(org.opensearch.indices.recovery.RecoverySettings) SearchPhaseController(org.opensearch.action.search.SearchPhaseController) PATH_HOME_SETTING(org.opensearch.env.Environment.PATH_HOME_SETTING) TransportAutoPutMappingAction(org.opensearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction) MockEventuallyConsistentRepository(org.opensearch.snapshots.mockstore.MockEventuallyConsistentRepository) ClusterStateAction(org.opensearch.action.admin.cluster.state.ClusterStateAction) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) OpenSearchTestCase(org.opensearch.test.OpenSearchTestCase) Collection(java.util.Collection) CreateSnapshotAction(org.opensearch.action.admin.cluster.snapshots.create.CreateSnapshotAction) AutoPutMappingAction(org.opensearch.action.admin.indices.mapping.put.AutoPutMappingAction) Collectors(java.util.stream.Collectors) AliasValidator(org.opensearch.cluster.metadata.AliasValidator) Objects(java.util.Objects) FakeThreadPoolMasterService(org.opensearch.cluster.service.FakeThreadPoolMasterService) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) StatusInfo(org.opensearch.monitor.StatusInfo) BigArrays(org.opensearch.common.util.BigArrays) IntStream(java.util.stream.IntStream) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) CheckedConsumer(org.opensearch.common.CheckedConsumer) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DeleteIndexAction(org.opensearch.action.admin.indices.delete.DeleteIndexAction) CoordinatorTests(org.opensearch.cluster.coordination.CoordinatorTests) SnapshotDeletionsInProgress(org.opensearch.cluster.SnapshotDeletionsInProgress) NamedWriteableRegistry(org.opensearch.common.io.stream.NamedWriteableRegistry) MappingUpdatedAction(org.opensearch.cluster.action.index.MappingUpdatedAction) HashSet(java.util.HashSet) TransportShardBulkAction(org.opensearch.action.bulk.TransportShardBulkAction) PeerRecoveryTargetService(org.opensearch.indices.recovery.PeerRecoveryTargetService) TransportCreateIndexAction(org.opensearch.action.admin.indices.create.TransportCreateIndexAction) Matchers.iterableWithSize(org.hamcrest.Matchers.iterableWithSize) SearchResponse(org.opensearch.action.search.SearchResponse) PutRepositoryAction(org.opensearch.action.admin.cluster.repositories.put.PutRepositoryAction) RepositoryData(org.opensearch.repositories.RepositoryData) Collections.emptyMap(java.util.Collections.emptyMap) Matchers.empty(org.hamcrest.Matchers.empty) ShardLimitValidator(org.opensearch.indices.ShardLimitValidator) IngestService(org.opensearch.ingest.IngestService) BlobStoreTestUtil(org.opensearch.repositories.blobstore.BlobStoreTestUtil) TransportRequest(org.opensearch.transport.TransportRequest) ActionTestUtils.assertNoFailureListener(org.opensearch.action.support.ActionTestUtils.assertNoFailureListener) CreateIndexResponse(org.opensearch.action.admin.indices.create.CreateIndexResponse) FsRepository(org.opensearch.repositories.fs.FsRepository) ShardRouting(org.opensearch.cluster.routing.ShardRouting) ClusterStateRequest(org.opensearch.action.admin.cluster.state.ClusterStateRequest) ClusterName(org.opensearch.cluster.ClusterName) Comparator(java.util.Comparator) LogManager(org.apache.logging.log4j.LogManager) IndicesModule(org.opensearch.indices.IndicesModule) Arrays(java.util.Arrays) ClusterBootstrapService(org.opensearch.cluster.coordination.ClusterBootstrapService) IndexScopedSettings(org.opensearch.common.settings.IndexScopedSettings) ClusterStateResponse(org.opensearch.action.admin.cluster.state.ClusterStateResponse) TransportInterceptor(org.opensearch.transport.TransportInterceptor) ClusterRerouteAction(org.opensearch.action.admin.cluster.reroute.ClusterRerouteAction) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) CleanupRepositoryAction(org.opensearch.action.admin.cluster.repositories.cleanup.CleanupRepositoryAction) RequestValidators(org.opensearch.action.RequestValidators) TransportNodesListGatewayStartedShards(org.opensearch.gateway.TransportNodesListGatewayStartedShards) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) TransportCreateSnapshotAction(org.opensearch.action.admin.cluster.snapshots.create.TransportCreateSnapshotAction) SearchExecutionStatsCollector(org.opensearch.action.search.SearchExecutionStatsCollector) ActionListener(org.opensearch.action.ActionListener) ActionType(org.opensearch.action.ActionType) AbstractCoordinatorTestCase(org.opensearch.cluster.coordination.AbstractCoordinatorTestCase) CreateIndexRequest(org.opensearch.action.admin.indices.create.CreateIndexRequest) Repository(org.opensearch.repositories.Repository) MockSinglePrioritizingExecutor(org.opensearch.cluster.coordination.MockSinglePrioritizingExecutor) ScriptService(org.opensearch.script.ScriptService) Index(org.opensearch.index.Index) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) DiscoveryNodeRole(org.opensearch.cluster.node.DiscoveryNodeRole) ActionFilters(org.opensearch.action.support.ActionFilters) Matchers.contains(org.hamcrest.Matchers.contains) StepListener(org.opensearch.action.StepListener) Matchers.is(org.hamcrest.Matchers.is) Matchers.endsWith(org.hamcrest.Matchers.endsWith) TransportException(org.opensearch.transport.TransportException) RepositoriesService(org.opensearch.repositories.RepositoriesService) TransportDeleteSnapshotAction(org.opensearch.action.admin.cluster.snapshots.delete.TransportDeleteSnapshotAction) ClusterState(org.opensearch.cluster.ClusterState) TransportClusterStateAction(org.opensearch.action.admin.cluster.state.TransportClusterStateAction) SearchRequest(org.opensearch.action.search.SearchRequest) Environment(org.opensearch.env.Environment) SetOnce(org.apache.lucene.util.SetOnce) TransportIndicesShardStoresAction(org.opensearch.action.admin.indices.shards.TransportIndicesShardStoresAction) UpdateHelper(org.opensearch.action.update.UpdateHelper) VotingConfiguration(org.opensearch.cluster.coordination.CoordinationMetadata.VotingConfiguration) DeleteSnapshotRequest(org.opensearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest) SystemIndices(org.opensearch.indices.SystemIndices) PluginsService(org.opensearch.plugins.PluginsService) InMemoryPersistedState(org.opensearch.cluster.coordination.InMemoryPersistedState) NamedXContentRegistry(org.opensearch.common.xcontent.NamedXContentRegistry) ClusterService(org.opensearch.cluster.service.ClusterService) ClusterChangedEvent(org.opensearch.cluster.ClusterChangedEvent) BlobStoreRepository(org.opensearch.repositories.blobstore.BlobStoreRepository) Matchers.either(org.hamcrest.Matchers.either) MetadataDeleteIndexService(org.opensearch.cluster.metadata.MetadataDeleteIndexService) NoneCircuitBreakerService(org.opensearch.indices.breaker.NoneCircuitBreakerService) ClusterRerouteRequest(org.opensearch.action.admin.cluster.reroute.ClusterRerouteRequest) ThreadContext(org.opensearch.common.util.concurrent.ThreadContext) PrimaryReplicaSyncer(org.opensearch.index.shard.PrimaryReplicaSyncer) ClusterApplierService(org.opensearch.cluster.service.ClusterApplierService) TransportRestoreSnapshotAction(org.opensearch.action.admin.cluster.snapshots.restore.TransportRestoreSnapshotAction) TransportSearchAction(org.opensearch.action.search.TransportSearchAction) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) AnalysisRegistry(org.opensearch.index.analysis.AnalysisRegistry) After(org.junit.After) TransportCleanupRepositoryAction(org.opensearch.action.admin.cluster.repositories.cleanup.TransportCleanupRepositoryAction) IndicesClusterStateService(org.opensearch.indices.cluster.IndicesClusterStateService) DeterministicTaskQueue(org.opensearch.cluster.coordination.DeterministicTaskQueue) AdminClient(org.opensearch.client.AdminClient) IndicesService(org.opensearch.indices.IndicesService) PeerRecoverySourceService(org.opensearch.indices.recovery.PeerRecoverySourceService) CreateIndexAction(org.opensearch.action.admin.indices.create.CreateIndexAction) BatchedRerouteService(org.opensearch.cluster.routing.BatchedRerouteService) Nullable(org.opensearch.common.Nullable) ClusterModule(org.opensearch.cluster.ClusterModule) TransportAddress(org.opensearch.common.transport.TransportAddress) TransportAction(org.opensearch.action.support.TransportAction) List(java.util.List) GlobalCheckpointSyncAction(org.opensearch.index.seqno.GlobalCheckpointSyncAction) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) CoordinationState(org.opensearch.cluster.coordination.CoordinationState) Optional(java.util.Optional) TransportBulkAction(org.opensearch.action.bulk.TransportBulkAction) AllocateEmptyPrimaryAllocationCommand(org.opensearch.cluster.routing.allocation.command.AllocateEmptyPrimaryAllocationCommand) TestEnvironment(org.opensearch.env.TestEnvironment) DiscoveryNodes(org.opensearch.cluster.node.DiscoveryNodes) MetaStateService(org.opensearch.gateway.MetaStateService) SnapshotsInProgress(org.opensearch.cluster.SnapshotsInProgress) HashMap(java.util.HashMap) ClusterStateListener(org.opensearch.cluster.ClusterStateListener) AutoCreateIndex(org.opensearch.action.support.AutoCreateIndex) NodeConnectionsService(org.opensearch.cluster.NodeConnectionsService) MetadataCreateIndexService(org.opensearch.cluster.metadata.MetadataCreateIndexService) DeleteIndexRequest(org.opensearch.action.admin.indices.delete.DeleteIndexRequest) NetworkModule(org.opensearch.common.network.NetworkModule) MetadataMappingService(org.opensearch.cluster.metadata.MetadataMappingService) RerouteService(org.opensearch.cluster.routing.RerouteService) NodeMappingRefreshAction(org.opensearch.cluster.action.index.NodeMappingRefreshAction) ClusterSettings(org.opensearch.common.settings.ClusterSettings) SearchService(org.opensearch.search.SearchService) CleanupRepositoryRequest(org.opensearch.action.admin.cluster.repositories.cleanup.CleanupRepositoryRequest) TransportDeleteIndexAction(org.opensearch.action.admin.indices.delete.TransportDeleteIndexAction) CreateSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse) Collections.emptySet(java.util.Collections.emptySet) CleanupRepositoryResponse(org.opensearch.action.admin.cluster.repositories.cleanup.CleanupRepositoryResponse) ActiveShardCount(org.opensearch.action.support.ActiveShardCount) AcknowledgedResponse(org.opensearch.action.support.master.AcknowledgedResponse) TimeUnit(java.util.concurrent.TimeUnit) NODE_NAME_SETTING(org.opensearch.node.Node.NODE_NAME_SETTING) BulkResponse(org.opensearch.action.bulk.BulkResponse) IndexRequest(org.opensearch.action.index.IndexRequest) Collections(java.util.Collections) DeleteIndexRequest(org.opensearch.action.admin.indices.delete.DeleteIndexRequest) Index(org.opensearch.index.Index) AutoCreateIndex(org.opensearch.action.support.AutoCreateIndex) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) CreateSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse) CreateIndexResponse(org.opensearch.action.admin.indices.create.CreateIndexResponse) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) SetOnce(org.apache.lucene.util.SetOnce) AcknowledgedResponse(org.opensearch.action.support.master.AcknowledgedResponse) IOException(java.io.IOException) TransportException(org.opensearch.transport.TransportException) RepositoryData(org.opensearch.repositories.RepositoryData) MockEventuallyConsistentRepository(org.opensearch.snapshots.mockstore.MockEventuallyConsistentRepository) FsRepository(org.opensearch.repositories.fs.FsRepository) Repository(org.opensearch.repositories.Repository) BlobStoreRepository(org.opensearch.repositories.blobstore.BlobStoreRepository) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) ActionListener(org.opensearch.action.ActionListener) Collection(java.util.Collection) SnapshotsInProgress(org.opensearch.cluster.SnapshotsInProgress) StepListener(org.opensearch.action.StepListener) CreateIndexRequest(org.opensearch.action.admin.indices.create.CreateIndexRequest)

Example 33 with StepListener

use of org.opensearch.action.StepListener in project OpenSearch by opensearch-project.

the class SnapshotResiliencyTests method indexNDocuments.

private void indexNDocuments(int documents, String index, Runnable afterIndexing) {
    if (documents == 0) {
        afterIndexing.run();
        return;
    }
    final BulkRequest bulkRequest = new BulkRequest().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
    for (int i = 0; i < documents; ++i) {
        bulkRequest.add(new IndexRequest(index).source(Collections.singletonMap("foo", "bar" + i)));
    }
    final StepListener<BulkResponse> bulkResponseStepListener = new StepListener<>();
    client().bulk(bulkRequest, bulkResponseStepListener);
    continueOrDie(bulkResponseStepListener, bulkResponse -> {
        assertFalse("Failures in bulk response: " + bulkResponse.buildFailureMessage(), bulkResponse.hasFailures());
        assertEquals(documents, bulkResponse.getItems().length);
        afterIndexing.run();
    });
}
Also used : BulkRequest(org.opensearch.action.bulk.BulkRequest) BulkResponse(org.opensearch.action.bulk.BulkResponse) StepListener(org.opensearch.action.StepListener) CreateIndexRequest(org.opensearch.action.admin.indices.create.CreateIndexRequest) DeleteIndexRequest(org.opensearch.action.admin.indices.delete.DeleteIndexRequest) IndexRequest(org.opensearch.action.index.IndexRequest)

Example 34 with StepListener

use of org.opensearch.action.StepListener in project OpenSearch by opensearch-project.

the class SnapshotResiliencyTests method testConcurrentSnapshotRestoreAndDeleteOther.

public void testConcurrentSnapshotRestoreAndDeleteOther() {
    setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10));
    String repoName = "repo";
    String snapshotName = "snapshot";
    final String index = "test";
    final int shards = randomIntBetween(1, 10);
    TestClusterNodes.TestClusterNode masterNode = testClusterNodes.currentMaster(testClusterNodes.nodes.values().iterator().next().clusterService.state());
    final StepListener<CreateSnapshotResponse> createSnapshotResponseStepListener = new StepListener<>();
    final int documentsFirstSnapshot = randomIntBetween(0, 100);
    continueOrDie(createRepoAndIndex(repoName, index, shards), createIndexResponse -> indexNDocuments(documentsFirstSnapshot, index, () -> client().admin().cluster().prepareCreateSnapshot(repoName, snapshotName).setWaitForCompletion(true).execute(createSnapshotResponseStepListener)));
    final int documentsSecondSnapshot = randomIntBetween(0, 100);
    final StepListener<CreateSnapshotResponse> createOtherSnapshotResponseStepListener = new StepListener<>();
    final String secondSnapshotName = "snapshot-2";
    continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> indexNDocuments(documentsSecondSnapshot, index, () -> client().admin().cluster().prepareCreateSnapshot(repoName, secondSnapshotName).setWaitForCompletion(true).execute(createOtherSnapshotResponseStepListener)));
    final StepListener<AcknowledgedResponse> deleteSnapshotStepListener = new StepListener<>();
    final StepListener<RestoreSnapshotResponse> restoreSnapshotResponseListener = new StepListener<>();
    continueOrDie(createOtherSnapshotResponseStepListener, createSnapshotResponse -> {
        scheduleNow(() -> client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).execute(deleteSnapshotStepListener));
        scheduleNow(() -> client().admin().cluster().restoreSnapshot(new RestoreSnapshotRequest(repoName, secondSnapshotName).waitForCompletion(true).renamePattern("(.+)").renameReplacement("restored_$1"), restoreSnapshotResponseListener));
    });
    final StepListener<SearchResponse> searchResponseListener = new StepListener<>();
    continueOrDie(restoreSnapshotResponseListener, restoreSnapshotResponse -> {
        assertEquals(shards, restoreSnapshotResponse.getRestoreInfo().totalShards());
        client().search(new SearchRequest("restored_" + index).source(new SearchSourceBuilder().size(0).trackTotalHits(true)), searchResponseListener);
    });
    deterministicTaskQueue.runAllRunnableTasks();
    assertEquals(documentsFirstSnapshot + documentsSecondSnapshot, Objects.requireNonNull(searchResponseListener.result().getHits().getTotalHits()).value);
    assertThat(deleteSnapshotStepListener.result().isAcknowledged(), is(true));
    assertThat(restoreSnapshotResponseListener.result().getRestoreInfo().failedShards(), is(0));
    final Repository repository = masterNode.repositoriesService.repository(repoName);
    Collection<SnapshotId> snapshotIds = getRepositoryData(repository).getSnapshotIds();
    assertThat(snapshotIds, contains(createOtherSnapshotResponseStepListener.result().getSnapshotInfo().snapshotId()));
    for (SnapshotId snapshotId : snapshotIds) {
        final SnapshotInfo snapshotInfo = repository.getSnapshotInfo(snapshotId);
        assertEquals(SnapshotState.SUCCESS, snapshotInfo.state());
        assertThat(snapshotInfo.indices(), containsInAnyOrder(index));
        assertEquals(shards, snapshotInfo.successfulShards());
        assertEquals(0, snapshotInfo.failedShards());
    }
}
Also used : SearchRequest(org.opensearch.action.search.SearchRequest) AcknowledgedResponse(org.opensearch.action.support.master.AcknowledgedResponse) RestoreSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse) SearchResponse(org.opensearch.action.search.SearchResponse) SearchSourceBuilder(org.opensearch.search.builder.SearchSourceBuilder) MockEventuallyConsistentRepository(org.opensearch.snapshots.mockstore.MockEventuallyConsistentRepository) FsRepository(org.opensearch.repositories.fs.FsRepository) Repository(org.opensearch.repositories.Repository) BlobStoreRepository(org.opensearch.repositories.blobstore.BlobStoreRepository) CreateSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse) RestoreSnapshotRequest(org.opensearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest) StepListener(org.opensearch.action.StepListener)

Example 35 with StepListener

use of org.opensearch.action.StepListener in project OpenSearch by opensearch-project.

the class SnapshotResiliencyTests method testSnapshotDeleteWithMasterFailover.

public void testSnapshotDeleteWithMasterFailover() {
    final int dataNodes = randomIntBetween(2, 10);
    final int masterNodes = randomFrom(3, 5);
    setupTestCluster(masterNodes, dataNodes);
    String repoName = "repo";
    String snapshotName = "snapshot";
    final String index = "test";
    final int shards = randomIntBetween(1, 10);
    final boolean waitForSnapshot = randomBoolean();
    final StepListener<CreateSnapshotResponse> createSnapshotResponseStepListener = new StepListener<>();
    continueOrDie(createRepoAndIndex(repoName, index, shards), createIndexResponse -> testClusterNodes.randomMasterNodeSafe().client.admin().cluster().prepareCreateSnapshot(repoName, snapshotName).setWaitForCompletion(waitForSnapshot).execute(createSnapshotResponseStepListener));
    final AtomicBoolean snapshotDeleteResponded = new AtomicBoolean(false);
    continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> {
        scheduleNow(this::disconnectOrRestartMasterNode);
        testClusterNodes.randomDataNodeSafe().client.admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).execute(ActionListener.wrap(() -> snapshotDeleteResponded.set(true)));
    });
    runUntil(() -> testClusterNodes.randomMasterNode().map(master -> snapshotDeleteResponded.get() && master.clusterService.state().custom(SnapshotDeletionsInProgress.TYPE, SnapshotDeletionsInProgress.EMPTY).getEntries().isEmpty()).orElse(false), TimeUnit.MINUTES.toMillis(1L));
    clearDisruptionsAndAwaitSync();
    final TestClusterNodes.TestClusterNode randomMaster = testClusterNodes.randomMasterNode().orElseThrow(() -> new AssertionError("expected to find at least one active master node"));
    SnapshotsInProgress finalSnapshotsInProgress = randomMaster.clusterService.state().custom(SnapshotsInProgress.TYPE);
    assertThat(finalSnapshotsInProgress.entries(), empty());
    final Repository repository = randomMaster.repositoriesService.repository(repoName);
    Collection<SnapshotId> snapshotIds = getRepositoryData(repository).getSnapshotIds();
    assertThat(snapshotIds, hasSize(0));
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MockEventuallyConsistentRepository(org.opensearch.snapshots.mockstore.MockEventuallyConsistentRepository) FsRepository(org.opensearch.repositories.fs.FsRepository) Repository(org.opensearch.repositories.Repository) BlobStoreRepository(org.opensearch.repositories.blobstore.BlobStoreRepository) CreateSnapshotResponse(org.opensearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse) SnapshotsInProgress(org.opensearch.cluster.SnapshotsInProgress) StepListener(org.opensearch.action.StepListener)

Aggregations

StepListener (org.opensearch.action.StepListener)40 IOException (java.io.IOException)28 ActionListener (org.opensearch.action.ActionListener)28 Logger (org.apache.logging.log4j.Logger)26 List (java.util.List)25 Repository (org.opensearch.repositories.Repository)24 Collections (java.util.Collections)23 Set (java.util.Set)22 Collectors (java.util.stream.Collectors)22 LogManager (org.apache.logging.log4j.LogManager)22 SnapshotsInProgress (org.opensearch.cluster.SnapshotsInProgress)21 RepositoryData (org.opensearch.repositories.RepositoryData)21 ThreadPool (org.opensearch.threadpool.ThreadPool)21 Map (java.util.Map)20 ExceptionsHelper (org.opensearch.ExceptionsHelper)20 ClusterState (org.opensearch.cluster.ClusterState)20 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)20 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)20 Collection (java.util.Collection)19 Version (org.opensearch.Version)19