繁体   English   中英

如何使用 aws-java-sdk 2.0 删除非空 S3 存储桶

[英]How to delete non empty S3 bucket using aws-java-sdk 2.0

我可以使用aws-java-sdk 1.0删除非空存储桶,但不能使用 aws-java-sdk 2.0。 这是代码:

无法使用 aws-java-sdk 2.0 删除非空 s3 存储桶的代码:

{
            boolean isTruncated = true;
            while(isTruncated) {
                ListObjectsV2Iterable objectListing = s3Client.listObjectsV2Paginator(ListObjectsV2Request.builder()
                        .bucket(bucketName)
                        .build());
                for (ListObjectsV2Response response : objectListing) {
                    /*
                     * There could be many pages in object list response is just one page
                     * */
                    for (S3Object s3Object : response.contents()) {
                        s3Client.deleteObject(DeleteObjectRequest.builder()
                                .bucket(bucketName)
                                .key(s3Object.key())
                                .build());
                    }
                    isTruncated = response.isTruncated();
                }
            }


            // Delete all object versions (required for versioned buckets).
            ListObjectVersionsIterable versionList = s3Client.listObjectVersionsPaginator(ListObjectVersionsRequest.builder()
                    .bucket(bucketName)
                    .build());
            isTruncated = true;

            while (isTruncated) {
                for (ListObjectVersionsResponse response : versionList) {
                    for (ObjectVersion version : response.versions()) {
                        s3Client.deleteObject(DeleteObjectRequest.builder()
                                .bucket(bucketName)
                                .key(version.key())
                                .versionId(version.versionId())
                                .build());
                    }
                    isTruncated = response.isTruncated();
                }
            }

        s3Client.deleteBucket(DeleteBucketRequest.builder().bucket(bucketName).build());
    }

上面的代码无法删除桶,它抛出异常:

software.amazon.awssdk.services.s3.model.S3Exception:您尝试删除的存储桶不为空。 您必须删除存储桶中的所有版本。 (服务:S3,状态代码:409,请求 ID:F5D76141223DC5EA)

使用 aws-java-sdk 1.0 删除非空存储桶的工作代码:

ObjectListing objectListing = s3Client.listObjects(bucketName);
            while (true) {
                Iterator<S3ObjectSummary> objIter = objectListing.getObjectSummaries().iterator();
                while (objIter.hasNext()) {
                    s3Client.deleteObject(bucketName, objIter.next().getKey());
                }

                // If the bucket contains many objects, the listObjects() call
                // might not return all of the objects in the first listing. Check to
                // see whether the listing was truncated. If so, retrieve the next page of objects
                // and delete them.
                if (objectListing.isTruncated()) {
                    objectListing = s3Client.listNextBatchOfObjects(objectListing);
                } else {
                    break;
                }
            }

            // Delete all object versions (required for versioned buckets).
            VersionListing versionList = s3Client.listVersions(new ListVersionsRequest().withBucketName(bucketName));
            while (true) {
                Iterator<S3VersionSummary> versionIter = versionList.getVersionSummaries().iterator();
                while (versionIter.hasNext()) {
                    S3VersionSummary vs = versionIter.next();
                    s3Client.deleteVersion(bucketName, vs.getKey(), vs.getVersionId());
                }

                if (versionList.isTruncated()) {
                    versionList = s3Client.listNextBatchOfVersions(versionList);
                } else {
                    break;
                }
            }

            // After all objects and object versions are deleted, delete the bucket.
            s3Client.deleteBucket(bucketName);

我检查了每个 DeleteObjectResponse 是否有任何失败。 如果所有响应都显示成功,则删除存储桶。 这是对象的工作代码,它也应该适用于版本。

public void delete(String bucketName)
{
    amazonS3Client.listObjectsV2(bucketName).stream().map(this::toDeleteObjectRequests).forEach(this::deleteBucket);
}

private List<DeleteObjectRequest> toDeleteObjectRequests(ListObjectsV2Response res)
{
    List<DeleteObjectRequest> deleteObjectRequests = res.contents().stream()
    .map(object -> DeleteObjectRequest.builder().bucket(res.name()).key(object.key()).build())
    .collect(Collectors.toList());
    if(deleteObjectRequests.isEmpty())
    {
        log.info("Bucket :{}: is empty deleting", res.name());
        amazonS3Client.deleteBucket(DeleteBucketRequest.builder().bucket(res.name()).build());
    }
    return deleteObjectRequests;
}

private void deleteBucket(List<DeleteObjectRequest> deleteObjects)
{
    deleteObjects.stream().findFirst().ifPresent(object -> deleteObjectsAndBucket(deleteObjects, object));
}

private void deleteObjectsAndBucket(List<DeleteObjectRequest> deleteObjects, DeleteObjectRequest object)
{
    Optional<DeleteObjectResponse> notDeletedObject = deleteAllObjects(deleteObjects);
    if (!notDeletedObject.isPresent())
    {
        log.info("Deleting bucket {} after emptying", object.bucket());
        amazonS3Client.deleteBucket(DeleteBucketRequest.builder().bucket(object.bucket()).build());
    }
    else
    {
        log.info("{} could not be deleted", notDeletedObject.get());
    }
}

private Optional<DeleteObjectResponse> deleteAllObjects(List<DeleteObjectRequest> deleteObjects)
{
    Optional<DeleteObjectResponse> notDeletedObject = deleteObjects.stream().map(amazonS3Client::deleteObject)
            .filter(res -> !res.sdkHttpResponse().isSuccessful()).findFirst();
    return notDeletedObject;
}

您需要根据@lu_ko 的建议修改上述代码以处理分页。 这是aws-sdk的 github 源代码的链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM