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() { 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; return this;
} }
public static class Builder { public static class Builder {
public static PutOptions fromPutOptions(PutOptions putOptions) {
return multipart(putOptions.multipart);
}
/** /**
* @see PutOptions#multipart() * @see PutOptions#multipart()
*/ */
public static PutOptions multipart() { public static PutOptions multipart() {
PutOptions options = new PutOptions(); return multipart(true);
return options.multipart();
} }
public static PutOptions multipart(boolean val) {
PutOptions options = new PutOptions();
return options.multipart(val);
}
} }
@Override @Override

View File

@ -241,7 +241,11 @@ public class ParallelMultipartUploadStrategy implements AsyncMultipartUploadStra
throw rtex; throw rtex;
} }
} else { } 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 ? return maxTime != null ?
futureETag.get(maxTime,TimeUnit.SECONDS) : futureETag.get(); futureETag.get(maxTime,TimeUnit.SECONDS) : futureETag.get();
} }

View File

@ -34,6 +34,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.KeyNotFoundException; import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
@ -44,9 +45,9 @@ import org.jclouds.s3.S3Client;
import org.jclouds.s3.S3ClientLiveTest; import org.jclouds.s3.S3ClientLiveTest;
import org.jclouds.s3.domain.ListBucketResponse; import org.jclouds.s3.domain.ListBucketResponse;
import org.jclouds.s3.domain.ObjectMetadata; import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.ObjectMetadata.StorageClass;
import org.jclouds.s3.domain.ObjectMetadataBuilder; import org.jclouds.s3.domain.ObjectMetadataBuilder;
import org.jclouds.s3.domain.S3Object; import org.jclouds.s3.domain.S3Object;
import org.jclouds.s3.domain.ObjectMetadata.StorageClass;
import org.testng.ITestContext; import org.testng.ITestContext;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; 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 { public void testPutWithReducedRedundancyStorage() throws InterruptedException {
String containerName = getContainerName(); String containerName = getContainerName();
try { try {