Skip to content

Commit

Permalink
Merge pull request #539 from ajkannan/forcedelete-without-executor
Browse files Browse the repository at this point in the history
Create simple forceDelete that can be used on App Engine
  • Loading branch information
aozarov committed Jan 12, 2016
2 parents 560faa9 + 33f6ad8 commit b5dd44a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ public StorageOptions options() {

/**
* Deletes a bucket, even if non-empty. Objects in the bucket are listed and deleted until bucket
* deletion succeeds or {@code timeout} expires.
* deletion succeeds or {@code timeout} expires. To allow for the timeout, this method uses a
* separate thread to send the delete requests. Use
* {@link #forceDelete(Storage storage, String bucket)} if spawning an additional thread is
* undesirable, such as in the App Engine production runtime.
*
* @param storage the storage service to be used to issue requests
* @param bucket the bucket to be deleted
Expand All @@ -88,6 +91,17 @@ public static Boolean forceDelete(Storage storage, String bucket, long timeout,
}
}

/**
* Deletes a bucket, even if non-empty. This method blocks until the deletion completes or fails.
*
* @param storage the storage service to be used to issue requests
* @param bucket the bucket to be deleted
* @throws StorageException if an exception is encountered during bucket deletion
*/
public static void forceDelete(Storage storage, String bucket) {
new DeleteBucketTask(storage, bucket).call();
}

/**
* Returns a bucket name generated using a random UUID.
*/
Expand Down Expand Up @@ -157,7 +171,7 @@ public DeleteBucketTask(Storage storage, String bucket) {
}

@Override
public Boolean call() throws Exception {
public Boolean call() {
while (true) {
for (BlobInfo info : storage.list(bucket).values()) {
storage.delete(bucket, info.name());
Expand All @@ -167,7 +181,12 @@ public Boolean call() throws Exception {
return true;
} catch (StorageException e) {
if (e.code() == 409) {
Thread.sleep(500);
try {
Thread.sleep(500);
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw e;
}
} else {
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,36 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio
}
}

@Test
public void testForceDeleteNoTimeout() {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE);
for (BlobInfo info : BLOB_LIST) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true);
EasyMock.replay(storageMock);
RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME);
EasyMock.verify(storageMock);
}

@Test
public void testForceDeleteNoTimeoutFail() {
Storage storageMock = EasyMock.createMock(Storage.class);
EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(BLOB_PAGE);
for (BlobInfo info : BLOB_LIST) {
EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true);
}
EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION);
EasyMock.replay(storageMock);
thrown.expect(StorageException.class);
try {
RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME);
} finally {
EasyMock.verify(storageMock);
}
}

@Test
public void testCreateFromStream() {
RemoteGcsHelper helper = RemoteGcsHelper.create(PROJECT_ID, JSON_KEY_STREAM);
Expand Down

0 comments on commit b5dd44a

Please sign in to comment.