/** * Empties the contents of the given bucket and optionally deletes the bucket * * @param s3 The S3 client object to use * @param bucketName The bucket to empty * @param deleteBucket Flag to determine whether to delete the bucket after emptying * @param context Lambda context object */ public static void emptyBucket(AmazonS3 s3, String bucketName, boolean deleteBucket, Context context) { if (s3.doesBucketExistV2(bucketName)) { logDebug("Emptying bucket '" + bucketName + "'...", context); VersionListing versionListing = s3.listVersions(new ListVersionsRequest().withBucketName(bucketName)); while (true) { for (S3VersionSummary vs : versionListing.getVersionSummaries()) { s3.deleteVersion(bucketName, vs.getKey(), vs.getVersionId()); } if (versionListing.isTruncated()) { logDebug("Fetching next batch of versions for bucket '" + bucketName + "'", context); versionListing = s3.listNextBatchOfVersions(versionListing); } else { break; } } logInfo("Successfully emptied bucket '" + bucketName + "'", context); if (deleteBucket) { logDebug("Deleting bucket '" + bucketName + "'...", context); s3.deleteBucket(bucketName); logInfo("Successfully deleted bucket '" + bucketName + "'", context); } } else { logWarn("Bucket '" + bucketName + "' does not exist", context); } }
@Override public S3VersionSummary next() { prepareCurrentListing(); S3VersionSummary returnValue = nextMatchingSummary(); nextSummary = null; return returnValue; }
private S3VersionSummary nextMatchingSummary() { if (getKey() == null || (nextSummary != null && nextSummary.getKey().equals( getKey()))) { return nextSummary; } else { return null; } }
@Test public void testDeleteDirectoryAssertHandleAmazonClientException() { S3Operations originalS3Operations = (S3Operations) ReflectionTestUtils.getField(s3Dao, "s3Operations"); S3Operations mockS3Operations = mock(S3Operations.class); ReflectionTestUtils.setField(s3Dao, "s3Operations", mockS3Operations); try { S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = new S3FileTransferRequestParamsDto(); s3FileTransferRequestParamsDto.setS3BucketName("s3BucketName"); s3FileTransferRequestParamsDto.setS3KeyPrefix("s3KeyPrefix"); VersionListing versionListing = new VersionListing(); versionListing.getVersionSummaries().add(new S3VersionSummary()); when(mockS3Operations.listVersions(any(), any())).thenReturn(versionListing); when(mockS3Operations.deleteObjects(any(), any())).thenThrow(new AmazonClientException("message")); try { s3Dao.deleteDirectory(s3FileTransferRequestParamsDto); fail(); } catch (Exception e) { assertEquals(IllegalStateException.class, e.getClass()); assertEquals("Failed to delete keys/key versions with prefix \"s3KeyPrefix\" from bucket \"s3BucketName\". Reason: message", e.getMessage()); } } finally { ReflectionTestUtils.setField(s3Dao, "s3Operations", originalS3Operations); } }
@Override public Iterator<S3VersionSummary> iterator() { return new VersionIterator(); }
public static void main(String[] args) { final String USAGE = "\n" + "To run this example, supply the name of an S3 bucket\n" + "\n" + "Ex: DeleteBucket <bucketname>\n"; if (args.length < 1) { System.out.println(USAGE); System.exit(1); } String bucket_name = args[0]; System.out.println("Deleting S3 bucket: " + bucket_name); final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient(); try { System.out.println(" - removing objects from bucket"); ObjectListing object_listing = s3.listObjects(bucket_name); while (true) { for (Iterator<?> iterator = object_listing.getObjectSummaries().iterator(); iterator.hasNext();) { S3ObjectSummary summary = (S3ObjectSummary)iterator.next(); s3.deleteObject(bucket_name, summary.getKey()); } // more object_listing to retrieve? if (object_listing.isTruncated()) { object_listing = s3.listNextBatchOfObjects(object_listing); } else { break; } }; System.out.println(" - removing versions from bucket"); VersionListing version_listing = s3.listVersions( new ListVersionsRequest().withBucketName(bucket_name)); while (true) { for (Iterator<?> iterator = version_listing.getVersionSummaries().iterator(); iterator.hasNext();) { S3VersionSummary vs = (S3VersionSummary)iterator.next(); s3.deleteVersion( bucket_name, vs.getKey(), vs.getVersionId()); } if (version_listing.isTruncated()) { version_listing = s3.listNextBatchOfVersions( version_listing); } else { break; } } System.out.println(" OK, bucket ready to delete!"); s3.deleteBucket(bucket_name); } catch (AmazonServiceException e) { System.err.println(e.getErrorMessage()); System.exit(1); } System.out.println("Done!"); }
@Override public List<DeleteObjectsRequest.KeyVersion> listVersions(final S3FileTransferRequestParamsDto params) { Assert.isTrue(!isRootKeyPrefix(params.getS3KeyPrefix()), "Listing of S3 key versions from root directory is not allowed."); AmazonS3Client s3Client = getAmazonS3(params); List<DeleteObjectsRequest.KeyVersion> keyVersions = new ArrayList<>(); try { ListVersionsRequest listVersionsRequest = new ListVersionsRequest().withBucketName(params.getS3BucketName()).withPrefix(params.getS3KeyPrefix()); VersionListing versionListing; do { versionListing = s3Operations.listVersions(listVersionsRequest, s3Client); for (S3VersionSummary versionSummary : versionListing.getVersionSummaries()) { keyVersions.add(new DeleteObjectsRequest.KeyVersion(versionSummary.getKey(), versionSummary.getVersionId())); } listVersionsRequest.setKeyMarker(versionListing.getNextKeyMarker()); listVersionsRequest.setVersionIdMarker(versionListing.getNextVersionIdMarker()); } while (versionListing.isTruncated()); } catch (AmazonS3Exception amazonS3Exception) { if (S3Operations.ERROR_CODE_NO_SUCH_BUCKET.equals(amazonS3Exception.getErrorCode())) { throw new IllegalArgumentException("The specified bucket '" + params.getS3BucketName() + "' does not exist.", amazonS3Exception); } throw new IllegalStateException("Error accessing S3", amazonS3Exception); } catch (AmazonClientException e) { throw new IllegalStateException(String .format("Failed to list keys/key versions with prefix \"%s\" from bucket \"%s\". Reason: %s", params.getS3KeyPrefix(), params.getS3BucketName(), e.getMessage()), e); } finally { // Shutdown the AmazonS3Client instance to release resources. s3Client.shutdown(); } return keyVersions; }
/** * {@inheritDoc} * <p/> * If the bucket does not exist, returns a listing with an empty list. If a prefix is specified in listVersionsRequest, only versions starting with the * prefix will be returned. */ @Override public VersionListing listVersions(ListVersionsRequest listVersionsRequest, AmazonS3 s3Client) { LOGGER.debug("listVersions(): listVersionsRequest.getBucketName() = " + listVersionsRequest.getBucketName()); String bucketName = listVersionsRequest.getBucketName(); if (MOCK_S3_BUCKET_NAME_NO_SUCH_BUCKET_EXCEPTION.equals(bucketName)) { AmazonS3Exception amazonS3Exception = new AmazonS3Exception(MOCK_S3_BUCKET_NAME_NO_SUCH_BUCKET_EXCEPTION); amazonS3Exception.setErrorCode("NoSuchBucket"); throw amazonS3Exception; } else if (MOCK_S3_BUCKET_NAME_INTERNAL_ERROR.equals(bucketName)) { throw new AmazonServiceException(S3Operations.ERROR_CODE_INTERNAL_ERROR); } VersionListing versionListing = new VersionListing(); versionListing.setBucketName(bucketName); MockS3Bucket mockS3Bucket = mockS3Buckets.get(bucketName); if (mockS3Bucket != null) { for (MockS3Object mockS3Object : mockS3Bucket.getVersions().values()) { String s3ObjectKey = mockS3Object.getKey(); if (listVersionsRequest.getPrefix() == null || s3ObjectKey.startsWith(listVersionsRequest.getPrefix())) { S3VersionSummary s3VersionSummary = new S3VersionSummary(); s3VersionSummary.setBucketName(bucketName); s3VersionSummary.setKey(s3ObjectKey); s3VersionSummary.setVersionId(mockS3Object.getVersion()); s3VersionSummary.setSize(mockS3Object.getData().length); s3VersionSummary.setStorageClass(mockS3Object.getObjectMetadata() != null ? mockS3Object.getObjectMetadata().getStorageClass() : null); versionListing.getVersionSummaries().add(s3VersionSummary); } } } return versionListing; }
@Test public void testDeleteDirectoryMultiObjectDeleteException() { // Create an S3 file transfer request parameters DTO to access S3 objects. S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = new S3FileTransferRequestParamsDto(); s3FileTransferRequestParamsDto.setS3BucketName(S3_BUCKET_NAME); s3FileTransferRequestParamsDto.setS3KeyPrefix(S3_KEY_PREFIX); // Create a retry policy. RetryPolicy retryPolicy = new RetryPolicy(PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION, PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY, INTEGER_VALUE, true); // Create an S3 version summary. S3VersionSummary s3VersionSummary = new S3VersionSummary(); s3VersionSummary.setKey(S3_KEY); s3VersionSummary.setVersionId(S3_VERSION_ID); // Create a version listing. VersionListing versionListing = new VersionListing(); versionListing.setVersionSummaries(Arrays.asList(s3VersionSummary)); // Create a delete error. MultiObjectDeleteException.DeleteError deleteError = new MultiObjectDeleteException.DeleteError(); deleteError.setKey(S3_KEY); deleteError.setVersionId(S3_VERSION_ID); deleteError.setCode(ERROR_CODE); deleteError.setMessage(ERROR_MESSAGE); // Create a multi object delete exception. MultiObjectDeleteException multiObjectDeleteException = new MultiObjectDeleteException(Arrays.asList(deleteError), new ArrayList<>()); // Mock the external calls. when(retryPolicyFactory.getRetryPolicy()).thenReturn(retryPolicy); when(s3Operations.listVersions(any(ListVersionsRequest.class), any(AmazonS3Client.class))).thenReturn(versionListing); when(s3Operations.deleteObjects(any(DeleteObjectsRequest.class), any(AmazonS3Client.class))).thenThrow(multiObjectDeleteException); // Try to call the method under test. try { s3DaoImpl.deleteDirectory(s3FileTransferRequestParamsDto); } catch (IllegalStateException e) { assertEquals(String.format("Failed to delete keys/key versions with prefix \"%s\" from bucket \"%s\". " + "Reason: One or more objects could not be deleted (Service: null; Status Code: 0; Error Code: null; Request ID: null; S3 Extended Request ID: null)", S3_KEY_PREFIX, S3_BUCKET_NAME), e.getMessage()); } // Verify the external calls. verify(retryPolicyFactory, times(2)).getRetryPolicy(); verify(s3Operations).listVersions(any(ListVersionsRequest.class), any(AmazonS3Client.class)); verify(s3Operations).deleteObjects(any(DeleteObjectsRequest.class), any(AmazonS3Client.class)); verifyNoMoreInteractionsHelper(); }
private void delete(VersionListing versionListing) { for (S3VersionSummary versionSummary : versionListing.getVersionSummaries()) { s3.deleteVersion(versionSummary.getBucketName(), versionSummary.getKey(), versionSummary.getVersionId()); } }