Skip to content

Commit

Permalink
Merge pull request #64 from EMCECS/feature-SDK-569-support-if-match-i…
Browse files Browse the repository at this point in the history
…f-unmodified-since-with-delete

SDK-569: add DeleteObjectRequest to support if-Match/ If-Unmodified-S…
  • Loading branch information
xiaoxin-ren authored Sep 22, 2021
2 parents aa83551 + 26dc425 commit 2343653
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/main/java/com/emc/object/s3/S3Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,11 @@ public interface S3Client {
*/
void deleteObject(String bucketName, String key);

/**
* Deletes object using the parameters specified in <code>request</code>
*/
void deleteObject(DeleteObjectRequest request);

/**
* Delets version <code>versionId</code> of object <code>key</code> in bucket <code>bucketName</code>.
* <p><b>Note:</b> versioning must be enabled in the bucket.</p>
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/emc/object/s3/jersey/S3JerseyClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -602,12 +602,17 @@ public URL getPresignedUrl(PresignedUrlRequest request) {

@Override
public void deleteObject(String bucketName, final String key) {
executeAndClose(client, new S3ObjectRequest(Method.DELETE, bucketName, key, null));
deleteObject(new DeleteObjectRequest(bucketName, key));
}

@Override
public void deleteObject(DeleteObjectRequest request) {
executeAndClose(client, request);
}

@Override
public void deleteVersion(String bucketName, String key, String versionId) {
executeAndClose(client, new S3ObjectRequest(Method.DELETE, bucketName, key, "versionId=" + versionId));
deleteObject(new DeleteObjectRequest(bucketName, key).withVersionId(versionId));
}

@Override
Expand Down
89 changes: 89 additions & 0 deletions src/main/java/com/emc/object/s3/request/DeleteObjectRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.emc.object.s3.request;

import com.emc.object.Method;
import com.emc.object.s3.S3Constants;
import com.emc.object.util.RestUtil;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class DeleteObjectRequest extends S3ObjectRequest {
private String versionId;
private Date ifUnmodifiedSince;
private String ifMatch;
private Boolean bypassGovernanceRetention;

public DeleteObjectRequest(String bucketName, String key) {
super(Method.DELETE, bucketName, key, null);
}

@Override
public Map<String, String> getQueryParams() {
Map<String, String> queryParams = super.getQueryParams();
if (versionId != null) queryParams.put("versionId", versionId);
return queryParams;
}

@Override
public Map<String, List<Object>> getHeaders() {
Map<String, List<Object>> headers = super.getHeaders();
if (ifUnmodifiedSince != null)
RestUtil.putSingle(headers, RestUtil.HEADER_IF_UNMODIFIED_SINCE, RestUtil.headerFormat(ifUnmodifiedSince));
if (ifMatch != null) RestUtil.putSingle(headers, RestUtil.HEADER_IF_MATCH, ifMatch);
if (bypassGovernanceRetention != null) RestUtil.putSingle(headers, S3Constants.AMZ_OBJECT_LOCK_BYPASS_GOVERNANCE_RETENTION, bypassGovernanceRetention.toString());
return headers;
}

public String getVersionId() {
return versionId;
}

public void setVersionId(String versionId) {
this.versionId = versionId;
}

public Date getIfUnmodifiedSince() {
return ifUnmodifiedSince;
}

public void setIfUnmodifiedSince(Date ifUnmodifiedSince) {
this.ifUnmodifiedSince = ifUnmodifiedSince;
}

public String getIfMatch() {
return ifMatch;
}

public void setIfMatch(String ifMatch) {
this.ifMatch = ifMatch;
}

public boolean getBypassGovernanceRetention() {
return bypassGovernanceRetention;
}

public void setBypassGovernanceRetention(Boolean bypassGovernanceRetention) {
this.bypassGovernanceRetention = bypassGovernanceRetention;
}

public DeleteObjectRequest withVersionId(String versionId) {
setVersionId(versionId);
return this;
}

public DeleteObjectRequest withIfUnmodifiedSince(Date ifUnmodifiedSince) {
setIfUnmodifiedSince(ifUnmodifiedSince);
return this;
}

public DeleteObjectRequest withIfMatch(String ifMatch) {
setIfMatch(ifMatch);
return this;
}

public DeleteObjectRequest withBypassGovernanceRetention(Boolean bypassGovernanceRetention) {
setBypassGovernanceRetention(bypassGovernanceRetention);
return this;
}
}
101 changes: 100 additions & 1 deletion src/test/java/com/emc/object/s3/S3JerseyClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,19 @@ public void testDeleteObjectWithBypassGovernance() throws Exception {
ObjectKey objectKey = new ObjectKey(key, versionId);
DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(objectKey);

//Expect failure without bypassGovernanceRetention
//Expect failure without bypassGovernanceRetention (DeleteObjectsRequest)
DeleteObjectsResult deleteObjectsResult = client.deleteObjects(deleteObjectsRequest);
Assert.assertTrue(deleteObjectsResult.getResults().get(0) instanceof DeleteError);

//Expect failure without bypassGovernanceRetention (DeleteObjectRequest)
DeleteObjectRequest request = new DeleteObjectRequest(bucketName, key).withVersionId(versionId);
try {
client.deleteObject(request);
Assert.fail("expected 403");
}catch (S3Exception e) {
Assert.assertEquals(403, e.getHttpCode());
}

//Expect success with bypassGovernanceRetention
deleteObjectsRequest.setBypassGovernanceRetention(true);
deleteObjectsResult = client.deleteObjects(deleteObjectsRequest);
Expand Down Expand Up @@ -1107,6 +1116,79 @@ public void testPutObjectPreconditions() {
client.putObject(request);
}

@Test
public void testDeleteObjectPreconditions() {
Assume.assumeTrue("ECS version must be at least 3.7", ecsVersion != null && ecsVersion.compareTo("3.7") >= 0);
String key = "testDeletePreconditions";
String content = "hello Delete preconditions!";

Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -5); // 5 minutes ago

client.putObject(getTestBucket(), key, content, "text/plain");
String etag = client.getObjectMetadata(getTestBucket(), key).getETag();
String etag2 = "d41d8cd98f00b204e9800998ecf8427e"; //non-matching Etag

DeleteObjectRequest request = new DeleteObjectRequest(getTestBucket(), key);

// test if-unmodified fail
request.withIfUnmodifiedSince(cal.getTime());
try {
client.deleteObject(request);
Assert.fail("expected 412");
} catch (S3Exception e) {
Assert.assertEquals(412, e.getHttpCode());
}

// test if-unmodified and if-match(correct etag) fail
request.withIfUnmodifiedSince(cal.getTime()).withIfMatch(etag);
try {
client.deleteObject(request);
Assert.fail("expected 412");
} catch (S3Exception e) {
Assert.assertEquals(412, e.getHttpCode());
}

// test if-unmodified pass
cal.add(Calendar.MINUTE, 10); // 5 minutes from now
request.withIfUnmodifiedSince(cal.getTime()).withIfMatch(null);
client.deleteObject(request);

client.putObject(getTestBucket(), key, content, "text/plain");
// test if-unmodified and if-match(non-matching etag) fail
request.withIfUnmodifiedSince(cal.getTime()).withIfMatch(etag2);
try {
client.deleteObject(request);
Assert.fail("expected 412");
} catch (S3Exception e) {
Assert.assertEquals(412, e.getHttpCode());
}

// test if-match(non-matching etag) fail
request.withIfUnmodifiedSince(null).withIfMatch(etag2);
try {
client.deleteObject(request);
Assert.fail("expected 412");
} catch (S3Exception e) {
Assert.assertEquals(412, e.getHttpCode());
}

//test if-match(correct etag) pass
request.withIfUnmodifiedSince(null).withIfMatch(etag);
client.deleteObject(request);

client.putObject(getTestBucket(), key, content, "text/plain");
// test if-match * pass
request.withIfUnmodifiedSince(null).withIfMatch("*");
client.deleteObject(request);

// test pre-condition should not fail on non-existing key
request.setKey("bogus-key");
cal.add(Calendar.MINUTE, -10); // 5 minutes ago
request.withIfUnmodifiedSince(cal.getTime()).withIfMatch(etag2);
client.deleteObject(request);
}

@Test
public void testCreateObjectByteArray() {
byte[] data;
Expand Down Expand Up @@ -2324,6 +2406,23 @@ protected void inspectDeleteSuccess(DeleteSuccess deleteResult) {
Assert.assertNotNull(deleteResult);
}

@Test
public void testDeleteObjectRequest() {
String key = "string-test-DeleteObjectRequest";
String content = "Hello Strings!";
client.putObject(getTestBucket(), key, content, "text/plain");
Assert.assertEquals(1, client.listObjects(getTestBucket()).getObjects().size());

DeleteObjectRequest request = new DeleteObjectRequest(getTestBucket(), key);
client.deleteObject(request);
try {
client.getObjectMetadata(getTestBucket(), key);
Assert.fail("expected 404 Not Found");
} catch(S3Exception e) {
Assert.assertEquals(404, e.getHttpCode());
}
}

@Test
public void testGetObjectMetadata() {
String testObject = "/objectPrefix/testObject1";
Expand Down

0 comments on commit 2343653

Please sign in to comment.