JCLOUDS-1111: Force overwriting Atmos objects

This avoids a racy delete then write in the portable abstraction.
This commit is contained in:
Andrew Gaul 2017-07-08 15:17:37 -07:00
parent 8344ddcc2c
commit e446b5b8b4
4 changed files with 29 additions and 9 deletions

View File

@ -258,6 +258,7 @@ public class AtmosBlobStore extends BaseBlobStore {
if (options.getBlobAccess() == BlobAccess.PUBLIC_READ) {
atmosOptions.publicRead();
}
atmosOptions.overwrite();
return AtmosUtils.putBlob(sync, crypto, blob2Object, container, blob, atmosOptions);
}

View File

@ -53,6 +53,12 @@ public class PutOptions extends BaseHttpRequestOptions {
return this;
}
/** By default Atmos does not allow overwriting objects. */
public PutOptions overwrite() {
this.replaceHeader("x-emc-force-overwrite", "true");
return this;
}
public static class Builder {
/**
@ -67,5 +73,10 @@ public class PutOptions extends BaseHttpRequestOptions {
PutOptions options = new PutOptions();
return options.publicNone();
}
public static PutOptions overwrite() {
PutOptions options = new PutOptions();
return options.overwrite();
}
}
}

View File

@ -33,7 +33,6 @@ import org.jclouds.atmos.options.PutOptions;
import org.jclouds.atmos.reference.AtmosErrorCode;
import org.jclouds.atmos.xml.ErrorHandler;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyAlreadyExistsException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.crypto.Crypto;
import org.jclouds.http.HttpCommand;
@ -72,14 +71,7 @@ public class AtmosUtils {
Blob blob, PutOptions options) {
final String path = container + "/" + blob.getMetadata().getName();
final AtmosObject object = blob2Object.apply(blob);
try {
sync.createFile(container, object, options);
} catch (KeyAlreadyExistsException e) {
deletePathAndEnsureGone(sync, path);
sync.createFile(container, object, options);
}
sync.createFile(container, object, options);
return path;
}

View File

@ -229,6 +229,22 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
}
@Test(groups = { "integration", "live" })
public void testOverwriteBlob() throws InterruptedException {
String container = getContainerName();
BlobStore blobStore = view.getBlobStore();
try {
String blobName = "hello";
Blob blob = blobStore.blobBuilder(blobName)
.payload(TEST_STRING)
.build();
blobStore.putBlob(container, blob);
blobStore.putBlob(container, blob);
} finally {
returnContainer(container);
}
}
@Test(groups = { "integration", "live" })
public void testCreateBlobWithExpiry() throws InterruptedException {
String container = getContainerName();