Search in sources :

Example 1 with DeleteResult

use of org.opensearch.common.blobstore.DeleteResult in project OpenSearch by opensearch-project.

the class FsBlobContainer method delete.

@Override
public DeleteResult delete() throws IOException {
    final AtomicLong filesDeleted = new AtomicLong(0L);
    final AtomicLong bytesDeleted = new AtomicLong(0L);
    Files.walkFileTree(path, new SimpleFileVisitor<Path>() {

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException impossible) throws IOException {
            assert impossible == null;
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Files.delete(file);
            filesDeleted.incrementAndGet();
            bytesDeleted.addAndGet(attrs.size());
            return FileVisitResult.CONTINUE;
        }
    });
    return new DeleteResult(filesDeleted.get(), bytesDeleted.get());
}
Also used : Path(java.nio.file.Path) BlobPath(org.opensearch.common.blobstore.BlobPath) AtomicLong(java.util.concurrent.atomic.AtomicLong) FileVisitResult(java.nio.file.FileVisitResult) IOException(java.io.IOException) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) DeleteResult(org.opensearch.common.blobstore.DeleteResult)

Example 2 with DeleteResult

use of org.opensearch.common.blobstore.DeleteResult in project OpenSearch by opensearch-project.

the class AzureBlobStore method deleteBlobDirectory.

public DeleteResult deleteBlobDirectory(String path, Executor executor) throws URISyntaxException, BlobStorageException, IOException {
    final Tuple<BlobServiceClient, Supplier<Context>> client = client();
    final BlobContainerClient blobContainer = client.v1().getBlobContainerClient(container);
    final Collection<Exception> exceptions = Collections.synchronizedList(new ArrayList<>());
    final AtomicLong outstanding = new AtomicLong(1L);
    final PlainActionFuture<Void> result = PlainActionFuture.newFuture();
    final AtomicLong blobsDeleted = new AtomicLong();
    final AtomicLong bytesDeleted = new AtomicLong();
    final ListBlobsOptions listBlobsOptions = new ListBlobsOptions().setPrefix(path);
    SocketAccess.doPrivilegedVoidException(() -> {
        String continuationToken = null;
        do {
            // Fetch one page at a time, others are going to be fetched by continuation token
            // TODO: reconsider reverting to simplified approach once https://github.com/Azure/azure-sdk-for-java/issues/26064
            // gets addressed.
            final Optional<PagedResponse<BlobItem>> pageOpt = blobContainer.listBlobs(listBlobsOptions, timeout()).streamByPage(continuationToken).findFirst();
            if (!pageOpt.isPresent()) {
                // No more pages, should never happen
                break;
            }
            final PagedResponse<BlobItem> page = pageOpt.get();
            for (final BlobItem blobItem : page.getValue()) {
                // Skipping prefixes as those are not deletable and should not be there
                assert (blobItem.isPrefix() == null || !blobItem.isPrefix()) : "Only blobs (not prefixes) are expected";
                outstanding.incrementAndGet();
                executor.execute(new AbstractRunnable() {

                    @Override
                    protected void doRun() throws Exception {
                        final long len = blobItem.getProperties().getContentLength();
                        final BlobClient azureBlob = blobContainer.getBlobClient(blobItem.getName());
                        logger.trace(() -> new ParameterizedMessage("container [{}]: blob [{}] found. removing.", container, blobItem.getName()));
                        final Response<Void> response = azureBlob.deleteWithResponse(null, null, timeout(), client.v2().get());
                        logger.trace(() -> new ParameterizedMessage("container [{}]: blob [{}] deleted status [{}].", container, blobItem.getName(), response.getStatusCode()));
                        blobsDeleted.incrementAndGet();
                        if (len >= 0) {
                            bytesDeleted.addAndGet(len);
                        }
                    }

                    @Override
                    public void onFailure(Exception e) {
                        exceptions.add(e);
                    }

                    @Override
                    public void onAfter() {
                        if (outstanding.decrementAndGet() == 0) {
                            result.onResponse(null);
                        }
                    }
                });
            }
            // Fetch next continuation token
            continuationToken = page.getContinuationToken();
        } while (StringUtils.isNotBlank(continuationToken));
    });
    if (outstanding.decrementAndGet() == 0) {
        result.onResponse(null);
    }
    result.actionGet();
    if (exceptions.isEmpty() == false) {
        final IOException ex = new IOException("Deleting directory [" + path + "] failed");
        exceptions.forEach(ex::addSuppressed);
        throw ex;
    }
    return new DeleteResult(blobsDeleted.get(), bytesDeleted.get());
}
Also used : AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) ListBlobsOptions(com.azure.storage.blob.models.ListBlobsOptions) BlobClient(com.azure.storage.blob.BlobClient) IOException(java.io.IOException) BlobStorageException(com.azure.storage.blob.models.BlobStorageException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) FileAlreadyExistsException(java.nio.file.FileAlreadyExistsException) BlobItem(com.azure.storage.blob.models.BlobItem) HttpResponse(com.azure.core.http.HttpResponse) PagedResponse(com.azure.core.http.rest.PagedResponse) Response(com.azure.core.http.rest.Response) BlobContainerClient(com.azure.storage.blob.BlobContainerClient) AtomicLong(java.util.concurrent.atomic.AtomicLong) BlobServiceClient(com.azure.storage.blob.BlobServiceClient) Supplier(java.util.function.Supplier) PagedResponse(com.azure.core.http.rest.PagedResponse) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) DeleteResult(org.opensearch.common.blobstore.DeleteResult)

Example 3 with DeleteResult

use of org.opensearch.common.blobstore.DeleteResult in project OpenSearch by opensearch-project.

the class GoogleCloudStorageBlobStore method deleteDirectory.

/**
 * Deletes the given path and all its children.
 *
 * @param pathStr Name of path to delete
 */
DeleteResult deleteDirectory(String pathStr) throws IOException {
    return SocketAccess.doPrivilegedIOException(() -> {
        DeleteResult deleteResult = DeleteResult.ZERO;
        Page<Blob> page = client().list(bucketName, BlobListOption.prefix(pathStr));
        do {
            final Collection<String> blobsToDelete = new ArrayList<>();
            final AtomicLong blobsDeleted = new AtomicLong(0L);
            final AtomicLong bytesDeleted = new AtomicLong(0L);
            page.getValues().forEach(b -> {
                blobsToDelete.add(b.getName());
                blobsDeleted.incrementAndGet();
                bytesDeleted.addAndGet(b.getSize());
            });
            deleteBlobsIgnoringIfNotExists(blobsToDelete);
            deleteResult = deleteResult.add(blobsDeleted.get(), bytesDeleted.get());
            page = page.getNextPage();
        } while (page != null);
        return deleteResult;
    });
}
Also used : Blob(com.google.cloud.storage.Blob) AtomicLong(java.util.concurrent.atomic.AtomicLong) ArrayList(java.util.ArrayList) DeleteResult(org.opensearch.common.blobstore.DeleteResult)

Example 4 with DeleteResult

use of org.opensearch.common.blobstore.DeleteResult in project OpenSearch by opensearch-project.

the class BlobStoreRepository method executeOneStaleIndexDelete.

private void executeOneStaleIndexDelete(BlockingQueue<Map.Entry<String, BlobContainer>> staleIndicesToDelete, GroupedActionListener<DeleteResult> listener) throws InterruptedException {
    Map.Entry<String, BlobContainer> indexEntry = staleIndicesToDelete.poll(0L, TimeUnit.MILLISECONDS);
    if (indexEntry != null) {
        final String indexSnId = indexEntry.getKey();
        threadPool.executor(ThreadPool.Names.SNAPSHOT).execute(ActionRunnable.supply(listener, () -> {
            DeleteResult deleteResult = DeleteResult.ZERO;
            try {
                logger.debug("[{}] Found stale index [{}]. Cleaning it up", metadata.name(), indexSnId);
                deleteResult = indexEntry.getValue().delete();
                logger.debug("[{}] Cleaned up stale index [{}]", metadata.name(), indexSnId);
            } catch (IOException e) {
                logger.warn(() -> new ParameterizedMessage("[{}] index {} is no longer part of any snapshots in the repository, " + "but failed to clean up their index folders", metadata.name(), indexSnId), e);
            } catch (Exception e) {
                assert false : e;
                logger.warn(new ParameterizedMessage("[{}] Exception during single stale index delete", metadata.name()), e);
            }
            executeOneStaleIndexDelete(staleIndicesToDelete, listener);
            return deleteResult;
        }));
    }
}
Also used : FsBlobContainer(org.opensearch.common.blobstore.fs.FsBlobContainer) BlobContainer(org.opensearch.common.blobstore.BlobContainer) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) IOException(java.io.IOException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DeleteResult(org.opensearch.common.blobstore.DeleteResult) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) AbortedSnapshotException(org.opensearch.snapshots.AbortedSnapshotException) SnapshotMissingException(org.opensearch.snapshots.SnapshotMissingException) SnapshotException(org.opensearch.snapshots.SnapshotException) RepositoryVerificationException(org.opensearch.repositories.RepositoryVerificationException) IOException(java.io.IOException) IndexShardSnapshotFailedException(org.opensearch.index.snapshots.IndexShardSnapshotFailedException) NotXContentException(org.opensearch.common.compress.NotXContentException) NoSuchFileException(java.nio.file.NoSuchFileException) SnapshotCreationException(org.opensearch.snapshots.SnapshotCreationException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) RepositoryException(org.opensearch.repositories.RepositoryException) IndexShardRestoreFailedException(org.opensearch.index.snapshots.IndexShardRestoreFailedException) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException)

Example 5 with DeleteResult

use of org.opensearch.common.blobstore.DeleteResult in project OpenSearch by opensearch-project.

the class BlobStoreRepository method cleanupStaleBlobs.

/**
 * Cleans up stale blobs directly under the repository root as well as all indices paths that aren't referenced by any existing
 * snapshots. This method is only to be called directly after a new {@link RepositoryData} was written to the repository and with
 * parameters {@code foundIndices}, {@code rootBlobs}
 *
 * @param deletedSnapshots if this method is called as part of a delete operation, the snapshot ids just deleted or empty if called as
 *                         part of a repository cleanup
 * @param foundIndices     all indices blob containers found in the repository before {@code newRepoData} was written
 * @param rootBlobs        all blobs found directly under the repository root
 * @param newRepoData      new repository data that was just written
 * @param listener         listener to invoke with the combined {@link DeleteResult} of all blobs removed in this operation
 */
private void cleanupStaleBlobs(Collection<SnapshotId> deletedSnapshots, Map<String, BlobContainer> foundIndices, Map<String, BlobMetadata> rootBlobs, RepositoryData newRepoData, ActionListener<DeleteResult> listener) {
    final GroupedActionListener<DeleteResult> groupedListener = new GroupedActionListener<>(ActionListener.wrap(deleteResults -> {
        DeleteResult deleteResult = DeleteResult.ZERO;
        for (DeleteResult result : deleteResults) {
            deleteResult = deleteResult.add(result);
        }
        listener.onResponse(deleteResult);
    }, listener::onFailure), 2);
    final Executor executor = threadPool.executor(ThreadPool.Names.SNAPSHOT);
    final List<String> staleRootBlobs = staleRootBlobs(newRepoData, rootBlobs.keySet());
    if (staleRootBlobs.isEmpty()) {
        groupedListener.onResponse(DeleteResult.ZERO);
    } else {
        executor.execute(ActionRunnable.supply(groupedListener, () -> {
            List<String> deletedBlobs = cleanupStaleRootFiles(newRepoData.getGenId() - 1, deletedSnapshots, staleRootBlobs);
            return new DeleteResult(deletedBlobs.size(), deletedBlobs.stream().mapToLong(name -> rootBlobs.get(name).length()).sum());
        }));
    }
    final Set<String> survivingIndexIds = newRepoData.getIndices().values().stream().map(IndexId::getId).collect(Collectors.toSet());
    if (foundIndices.keySet().equals(survivingIndexIds)) {
        groupedListener.onResponse(DeleteResult.ZERO);
    } else {
        cleanupStaleIndices(foundIndices, survivingIndexIds, groupedListener);
    }
}
Also used : Metadata(org.opensearch.cluster.metadata.Metadata) IndexFormatTooNewException(org.apache.lucene.index.IndexFormatTooNewException) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) Version(org.opensearch.Version) Strings(org.opensearch.common.Strings) AbortedSnapshotException(org.opensearch.snapshots.AbortedSnapshotException) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) RecoveryState(org.opensearch.indices.recovery.RecoveryState) Map(java.util.Map) Lucene(org.opensearch.common.lucene.Lucene) ActionListener(org.opensearch.action.ActionListener) IOContext(org.apache.lucene.store.IOContext) Repository(org.opensearch.repositories.Repository) TimeValue(org.opensearch.common.unit.TimeValue) ExceptionsHelper(org.opensearch.ExceptionsHelper) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) BlobStoreIndexShardSnapshot(org.opensearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot) BlockingQueue(java.util.concurrent.BlockingQueue) AbstractLifecycleComponent(org.opensearch.common.component.AbstractLifecycleComponent) Logger(org.apache.logging.log4j.Logger) RepositoryOperation(org.opensearch.repositories.RepositoryOperation) Stream(java.util.stream.Stream) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) BytesArray(org.opensearch.common.bytes.BytesArray) BlobStoreIndexShardSnapshots(org.opensearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshots) FsBlobContainer(org.opensearch.common.blobstore.fs.FsBlobContainer) StepListener(org.opensearch.action.StepListener) XContentType(org.opensearch.common.xcontent.XContentType) IndexCommit(org.apache.lucene.index.IndexCommit) ThreadPool(org.opensearch.threadpool.ThreadPool) BlobContainer(org.opensearch.common.blobstore.BlobContainer) Releasable(org.opensearch.common.lease.Releasable) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ClusterState(org.opensearch.cluster.ClusterState) SnapshotMissingException(org.opensearch.snapshots.SnapshotMissingException) Numbers(org.opensearch.common.Numbers) SlicedInputStream(org.opensearch.index.snapshots.blobstore.SlicedInputStream) SnapshotException(org.opensearch.snapshots.SnapshotException) Streams(org.opensearch.common.io.Streams) CompressorFactory(org.opensearch.common.compress.CompressorFactory) RepositoryVerificationException(org.opensearch.repositories.RepositoryVerificationException) RepositoryCleanupInProgress(org.opensearch.cluster.RepositoryCleanupInProgress) InputStreamIndexInput(org.opensearch.common.lucene.store.InputStreamIndexInput) LongStream(java.util.stream.LongStream) IndexInput(org.apache.lucene.store.IndexInput) SetOnce(org.apache.lucene.util.SetOnce) RepositoriesMetadata(org.opensearch.cluster.metadata.RepositoriesMetadata) Executor(java.util.concurrent.Executor) SnapshotInfo(org.opensearch.snapshots.SnapshotInfo) RepositoryMetadata(org.opensearch.cluster.metadata.RepositoryMetadata) IOException(java.io.IOException) IndexShardSnapshotFailedException(org.opensearch.index.snapshots.IndexShardSnapshotFailedException) NotXContentException(org.opensearch.common.compress.NotXContentException) AtomicLong(java.util.concurrent.atomic.AtomicLong) RepositoryCleanupResult(org.opensearch.repositories.RepositoryCleanupResult) BlobPath(org.opensearch.common.blobstore.BlobPath) NamedXContentRegistry(org.opensearch.common.xcontent.NamedXContentRegistry) ClusterService(org.opensearch.cluster.service.ClusterService) CounterMetric(org.opensearch.common.metrics.CounterMetric) ShardGenerations(org.opensearch.repositories.ShardGenerations) NoSuchFileException(java.nio.file.NoSuchFileException) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) SnapshotCreationException(org.opensearch.snapshots.SnapshotCreationException) ByteSizeUnit(org.opensearch.common.unit.ByteSizeUnit) SnapshotFiles(org.opensearch.index.snapshots.blobstore.SnapshotFiles) SnapshotsService(org.opensearch.snapshots.SnapshotsService) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) XContentParser(org.opensearch.common.xcontent.XContentParser) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) MapperService(org.opensearch.index.mapper.MapperService) IndexId(org.opensearch.repositories.IndexId) XContentFactory(org.opensearch.common.xcontent.XContentFactory) RepositoryStats(org.opensearch.repositories.RepositoryStats) BlobMetadata(org.opensearch.common.blobstore.BlobMetadata) RecoverySettings(org.opensearch.indices.recovery.RecoverySettings) RepositoryException(org.opensearch.repositories.RepositoryException) FileInfo.canonicalName(org.opensearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot.FileInfo.canonicalName) BytesRef(org.apache.lucene.util.BytesRef) SnapshotId(org.opensearch.snapshots.SnapshotId) Collection(java.util.Collection) LoggingDeprecationHandler(org.opensearch.common.xcontent.LoggingDeprecationHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Store(org.opensearch.index.store.Store) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) Nullable(org.opensearch.common.Nullable) Tuple(org.opensearch.common.collect.Tuple) BlobStore(org.opensearch.common.blobstore.BlobStore) List(java.util.List) Optional(java.util.Optional) BytesReference(org.opensearch.common.bytes.BytesReference) RateLimitingInputStream(org.opensearch.index.snapshots.blobstore.RateLimitingInputStream) IndexMetadata(org.opensearch.cluster.metadata.IndexMetadata) ActionRunnable(org.opensearch.action.ActionRunnable) SnapshotsInProgress(org.opensearch.cluster.SnapshotsInProgress) ByteSizeValue(org.opensearch.common.unit.ByteSizeValue) SnapshotDeletionsInProgress(org.opensearch.cluster.SnapshotDeletionsInProgress) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) FilterInputStream(java.io.FilterInputStream) IndexShardSnapshotStatus(org.opensearch.index.snapshots.IndexShardSnapshotStatus) IndexMetaDataGenerations(org.opensearch.repositories.IndexMetaDataGenerations) UUIDs(org.opensearch.common.UUIDs) StoreFileMetadata(org.opensearch.index.store.StoreFileMetadata) IndexOutput(org.apache.lucene.store.IndexOutput) IndexShardRestoreFailedException(org.opensearch.index.snapshots.IndexShardRestoreFailedException) RepositoryData(org.opensearch.repositories.RepositoryData) Setting(org.opensearch.common.settings.Setting) RepositoryShardId(org.opensearch.repositories.RepositoryShardId) IndexFormatTooOldException(org.apache.lucene.index.IndexFormatTooOldException) ShardId(org.opensearch.index.shard.ShardId) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) DeleteResult(org.opensearch.common.blobstore.DeleteResult) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) RateLimiter(org.apache.lucene.store.RateLimiter) InputStream(java.io.InputStream) Executor(java.util.concurrent.Executor) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) ArrayList(java.util.ArrayList) List(java.util.List) DeleteResult(org.opensearch.common.blobstore.DeleteResult)

Aggregations

DeleteResult (org.opensearch.common.blobstore.DeleteResult)6 IOException (java.io.IOException)5 AtomicLong (java.util.concurrent.atomic.AtomicLong)5 ArrayList (java.util.ArrayList)3 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)3 NoSuchFileException (java.nio.file.NoSuchFileException)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Supplier (java.util.function.Supplier)2 CorruptIndexException (org.apache.lucene.index.CorruptIndexException)2 IndexFormatTooNewException (org.apache.lucene.index.IndexFormatTooNewException)2 IndexFormatTooOldException (org.apache.lucene.index.IndexFormatTooOldException)2 AlreadyClosedException (org.apache.lucene.store.AlreadyClosedException)2 BlobContainer (org.opensearch.common.blobstore.BlobContainer)2 BlobPath (org.opensearch.common.blobstore.BlobPath)2 FsBlobContainer (org.opensearch.common.blobstore.fs.FsBlobContainer)2 NotXContentException (org.opensearch.common.compress.NotXContentException)2 AbstractRunnable (org.opensearch.common.util.concurrent.AbstractRunnable)2 IndexShardRestoreFailedException (org.opensearch.index.snapshots.IndexShardRestoreFailedException)2 IndexShardSnapshotFailedException (org.opensearch.index.snapshots.IndexShardSnapshotFailedException)2