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) { if (options.getBlobAccess() == BlobAccess.PUBLIC_READ) {
atmosOptions.publicRead(); atmosOptions.publicRead();
} }
atmosOptions.overwrite();
return AtmosUtils.putBlob(sync, crypto, blob2Object, container, blob, atmosOptions); return AtmosUtils.putBlob(sync, crypto, blob2Object, container, blob, atmosOptions);
} }

View File

@ -53,6 +53,12 @@ public class PutOptions extends BaseHttpRequestOptions {
return this; 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 { public static class Builder {
/** /**
@ -67,5 +73,10 @@ public class PutOptions extends BaseHttpRequestOptions {
PutOptions options = new PutOptions(); PutOptions options = new PutOptions();
return options.publicNone(); 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.reference.AtmosErrorCode;
import org.jclouds.atmos.xml.ErrorHandler; import org.jclouds.atmos.xml.ErrorHandler;
import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyAlreadyExistsException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.crypto.Crypto; import org.jclouds.crypto.Crypto;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
@ -72,14 +71,7 @@ public class AtmosUtils {
Blob blob, PutOptions options) { Blob blob, PutOptions options) {
final String path = container + "/" + blob.getMetadata().getName(); final String path = container + "/" + blob.getMetadata().getName();
final AtmosObject object = blob2Object.apply(blob); final AtmosObject object = blob2Object.apply(blob);
sync.createFile(container, object, options);
try {
sync.createFile(container, object, options);
} catch (KeyAlreadyExistsException e) {
deletePathAndEnsureGone(sync, path);
sync.createFile(container, object, options);
}
return path; 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" }) @Test(groups = { "integration", "live" })
public void testCreateBlobWithExpiry() throws InterruptedException { public void testCreateBlobWithExpiry() throws InterruptedException {
String container = getContainerName(); String container = getContainerName();