Only create multipart stub blob when required

pull/210/head
Andrew Gaul 2017-04-13 14:07:36 -07:00
rodzic 5cca563871
commit fc204c0d49
2 zmienionych plików z 44 dodań i 15 usunięć

Wyświetl plik

@ -86,6 +86,19 @@ final class Quirks {
"azureblob" "azureblob"
); );
/**
* S3 stores object metadata during initiate multipart while others
* require it during complete multipart. Emulate the former in the latter
* by storing and retrieving a stub object.
*/
static final Set<String> MULTIPART_REQUIRES_STUB = ImmutableSet.of(
"azureblob",
"filesystem",
"google-cloud-storage",
"openstack-swift",
"transient"
);
/** Blobstores with opaque ETags. */ /** Blobstores with opaque ETags. */
static final Set<String> OPAQUE_ETAG = ImmutableSet.of( static final Set<String> OPAQUE_ETAG = ImmutableSet.of(
"azureblob", "azureblob",

Wyświetl plik

@ -91,6 +91,7 @@ import org.jclouds.blobstore.domain.MultipartPart;
import org.jclouds.blobstore.domain.MultipartUpload; import org.jclouds.blobstore.domain.MultipartUpload;
import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
import org.jclouds.blobstore.options.CopyOptions; import org.jclouds.blobstore.options.CopyOptions;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
@ -1862,11 +1863,11 @@ public class S3ProxyHandler {
MultipartUpload mpu = blobStore.initiateMultipartUpload(containerName, MultipartUpload mpu = blobStore.initiateMultipartUpload(containerName,
builder.build().getMetadata(), options); builder.build().getMetadata(), options);
// S3 requires blob metadata during the initiate call while Azure and if (Quirks.MULTIPART_REQUIRES_STUB.contains(getBlobStoreType(
// Swift require it in the complete call. Store a stub blob which blobStore))) {
// allows reproducing this metadata later.
blobStore.putBlob(containerName, builder.name(mpu.id()).build(), blobStore.putBlob(containerName, builder.name(mpu.id()).build(),
options); options);
}
try (Writer writer = response.getWriter()) { try (Writer writer = response.getWriter()) {
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter( XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
@ -1889,11 +1890,20 @@ public class S3ProxyHandler {
private void handleCompleteMultipartUpload(HttpServletResponse response, private void handleCompleteMultipartUpload(HttpServletResponse response,
InputStream is, BlobStore blobStore, String containerName, InputStream is, BlobStore blobStore, String containerName,
String blobName, String uploadId) throws IOException, S3Exception { String blobName, String uploadId) throws IOException, S3Exception {
MultipartUpload mpu;
if (Quirks.MULTIPART_REQUIRES_STUB.contains(getBlobStoreType(
blobStore))) {
Blob stubBlob = blobStore.getBlob(containerName, uploadId); Blob stubBlob = blobStore.getBlob(containerName, uploadId);
BlobAccess access = blobStore.getBlobAccess(containerName, uploadId); BlobAccess access = blobStore.getBlobAccess(containerName,
MultipartUpload mpu = MultipartUpload.create(containerName, uploadId);
mpu = MultipartUpload.create(containerName,
blobName, uploadId, stubBlob.getMetadata(), blobName, uploadId, stubBlob.getMetadata(),
new PutOptions().setBlobAccess(access)); new PutOptions().setBlobAccess(access));
} else {
mpu = MultipartUpload.create(containerName,
blobName, uploadId, new MutableBlobMetadataImpl(),
new PutOptions());
}
// List parts to get part sizes and to map multiple Azure parts // List parts to get part sizes and to map multiple Azure parts
// into single parts. // into single parts.
@ -1950,7 +1960,10 @@ public class S3ProxyHandler {
String eTag = blobStore.completeMultipartUpload(mpu, parts); String eTag = blobStore.completeMultipartUpload(mpu, parts);
blobStore.removeBlob(containerName, stubBlob.getMetadata().getName()); if (Quirks.MULTIPART_REQUIRES_STUB.contains(getBlobStoreType(
blobStore))) {
blobStore.removeBlob(containerName, uploadId);
}
try (Writer writer = response.getWriter()) { try (Writer writer = response.getWriter()) {
XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter( XMLStreamWriter xml = xmlOutputFactory.createXMLStreamWriter(
@ -1980,11 +1993,14 @@ public class S3ProxyHandler {
private static void handleAbortMultipartUpload(HttpServletResponse response, private static void handleAbortMultipartUpload(HttpServletResponse response,
BlobStore blobStore, String containerName, String blobName, BlobStore blobStore, String containerName, String blobName,
String uploadId) throws IOException, S3Exception { String uploadId) throws IOException, S3Exception {
if (Quirks.MULTIPART_REQUIRES_STUB.contains(getBlobStoreType(
blobStore))) {
if (!blobStore.blobExists(containerName, uploadId)) { if (!blobStore.blobExists(containerName, uploadId)) {
throw new S3Exception(S3ErrorCode.NO_SUCH_UPLOAD); throw new S3Exception(S3ErrorCode.NO_SUCH_UPLOAD);
} }
blobStore.removeBlob(containerName, uploadId); blobStore.removeBlob(containerName, uploadId);
}
// TODO: how to reconstruct original mpu? // TODO: how to reconstruct original mpu?
MultipartUpload mpu = MultipartUpload.create(containerName, MultipartUpload mpu = MultipartUpload.create(containerName,