kopia lustrzana https://github.com/gaul/s3proxy
Only create multipart stub blob when required
rodzic
5cca563871
commit
fc204c0d49
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Ładowanie…
Reference in New Issue