Merge pull request #644 from aledsage/Issue-936-SmallBlobAsyncMultiPart-Strike2

Issue 936: fixes async multi-part upload of small blob
This commit is contained in:
Adrian Cole 2012-05-21 08:13:43 -07:00
commit 997479f27a
3 changed files with 41 additions and 6 deletions

View File

@ -77,23 +77,39 @@ public class PutOptions implements Cloneable {
}
/**
* split large blobs into pieces, if supported by the provider
* split large blobs into pieces, if supported by the provider.
*
* Equivalent to <code>multipart(true)</code>
*/
public PutOptions multipart() {
this.multipart = true;
return multipart(true);
}
/**
* whether to split large blobs into pieces, if supported by the provider
*/
public PutOptions multipart(boolean val) {
this.multipart = val;
return this;
}
public static class Builder {
public static PutOptions fromPutOptions(PutOptions putOptions) {
return multipart(putOptions.multipart);
}
/**
* @see PutOptions#multipart()
*/
public static PutOptions multipart() {
PutOptions options = new PutOptions();
return options.multipart();
return multipart(true);
}
public static PutOptions multipart(boolean val) {
PutOptions options = new PutOptions();
return options.multipart(val);
}
}
@Override

View File

@ -241,7 +241,11 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
throw rtex;
}
} else {
ListenableFuture<String> futureETag = ablobstore.putBlob(container, blob, options);
// Issue 936: don't just call putBlob, as that will see options=multiPart and
// recursively call this execute method again; instead mark as not multipart
// because it can all fit in one go.
PutOptions nonMultipartOptions = PutOptions.Builder.multipart(false);
ListenableFuture<String> futureETag = ablobstore.putBlob(container, blob, nonMultipartOptions);
return maxTime != null ?
futureETag.get(maxTime,TimeUnit.SECONDS) : futureETag.get();
}

View File

@ -34,6 +34,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob;
@ -44,9 +45,9 @@ import org.jclouds.s3.S3Client;
import org.jclouds.s3.S3ClientLiveTest;
import org.jclouds.s3.domain.ListBucketResponse;
import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.ObjectMetadata.StorageClass;
import org.jclouds.s3.domain.ObjectMetadataBuilder;
import org.jclouds.s3.domain.S3Object;
import org.jclouds.s3.domain.ObjectMetadata.StorageClass;
import org.testng.ITestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -161,6 +162,20 @@ public class AWSS3ClientLiveTest extends S3ClientLiveTest {
}
}
public void testMultipartAsynchronouslySmallBlob() throws IOException, InterruptedException, Exception {
String containerName = getContainerName();
try {
AsyncBlobStore asyncBlobStore = view.getAsyncBlobStore();
asyncBlobStore.createContainerInLocation(null, containerName).get();
Blob blob = asyncBlobStore.blobBuilder("small").payload("small").build();
asyncBlobStore.putBlob(containerName, blob, PutOptions.Builder.multipart()).get();
} finally {
returnContainer(containerName);
}
}
public void testPutWithReducedRedundancyStorage() throws InterruptedException {
String containerName = getContainerName();
try {