Skip to content

Commit 03c2e66

Browse files
authored
feat: implement GrpcStorageImpl#listDefaultAcl (#1805)
1 parent f113d15 commit 03c2e66

File tree

4 files changed

+83
-38
lines changed

4 files changed

+83
-38
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,7 @@ public Acl updateDefaultAcl(Acl acl) {
13261326
*
13271327
* @throws StorageException upon failure
13281328
*/
1329-
@TransportCompatibility({Transport.HTTP})
1329+
@TransportCompatibility({Transport.HTTP, Transport.GRPC})
13301330
public List<Acl> listDefaultAcls() {
13311331
return storage.listDefaultAcls(getName());
13321332
}

google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -907,31 +907,12 @@ public List<Acl> listAcls(String bucket) {
907907

908908
@Override
909909
public Acl getDefaultAcl(String bucket, Entity entity) {
910-
// Specify the read-mask to explicitly include defaultObjectAcl
911-
Fields fields =
912-
UnifiedOpts.fields(
913-
ImmutableSet.of(
914-
BucketField.ACL, // workaround for b/261771961
915-
BucketField.DEFAULT_OBJECT_ACL));
916-
GrpcCallContext grpcCallContext = GrpcCallContext.createDefault();
917-
GetBucketRequest req =
918-
fields
919-
.getBucket()
920-
.apply(GetBucketRequest.newBuilder())
921-
.setName(bucketNameCodec.encode(bucket))
922-
.build();
923910
try {
924-
com.google.storage.v2.Bucket resp =
925-
Retrying.run(
926-
getOptions(),
927-
retryAlgorithmManager.getFor(req),
928-
() -> storageClient.getBucketCallable().call(req, grpcCallContext),
929-
Decoder.identity());
911+
com.google.storage.v2.Bucket resp = getBucketDefaultAcls(bucket);
930912

931913
Predicate<ObjectAccessControl> entityPredicate =
932914
objectAclEntityOrAltEq(codecs.entity().encode(entity));
933915

934-
//noinspection DataFlowIssue
935916
Optional<ObjectAccessControl> first =
936917
resp.getDefaultObjectAclList().stream().filter(entityPredicate).findFirst();
937918

@@ -965,7 +946,14 @@ public Acl updateDefaultAcl(String bucket, Acl acl) {
965946

966947
@Override
967948
public List<Acl> listDefaultAcls(String bucket) {
968-
return throwNotYetImplemented(fmtMethodName("listDefaultAcls", String.class));
949+
try {
950+
com.google.storage.v2.Bucket resp = getBucketDefaultAcls(bucket);
951+
return resp.getDefaultObjectAclList().stream()
952+
.map(codecs.objectAcl()::decode)
953+
.collect(ImmutableList.toImmutableList());
954+
} catch (NotFoundException e) {
955+
throw StorageException.coalesce(e);
956+
}
969957
}
970958

971959
@Override
@@ -1430,4 +1418,26 @@ private SourceObject sourceObjectEncode(SourceBlob from) {
14301418
ifNonNull(from.getGeneration(), to::setGeneration);
14311419
return to.build();
14321420
}
1421+
1422+
private com.google.storage.v2.Bucket getBucketDefaultAcls(String bucketName) {
1423+
Fields fields =
1424+
UnifiedOpts.fields(
1425+
ImmutableSet.of(
1426+
BucketField.ACL, // workaround for b/261771961
1427+
BucketField.DEFAULT_OBJECT_ACL,
1428+
BucketField.METAGENERATION));
1429+
GrpcCallContext grpcCallContext = GrpcCallContext.createDefault();
1430+
GetBucketRequest req =
1431+
fields
1432+
.getBucket()
1433+
.apply(GetBucketRequest.newBuilder())
1434+
.setName(bucketNameCodec.encode(bucketName))
1435+
.build();
1436+
1437+
return Retrying.run(
1438+
getOptions(),
1439+
retryAlgorithmManager.getFor(req),
1440+
() -> storageClient.getBucketCallable().call(req, grpcCallContext),
1441+
Decoder.identity());
1442+
}
14331443
}

google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,7 @@ PostPolicyV4 generateSignedPostPolicyV4(
35703570
*
35713571
* @throws StorageException upon failure
35723572
*/
3573-
@TransportCompatibility({Transport.HTTP})
3573+
@TransportCompatibility({Transport.HTTP, Transport.GRPC})
35743574
List<Acl> listDefaultAcls(String bucket);
35753575

35763576
/**

google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITAccessTest.java

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.Assert.assertFalse;
2222
import static org.junit.Assert.assertNotNull;
2323
import static org.junit.Assert.assertNull;
24+
import static org.junit.Assert.assertThrows;
2425
import static org.junit.Assert.assertTrue;
2526
import static org.junit.Assert.fail;
2627

@@ -29,6 +30,7 @@
2930
import com.google.cloud.Identity;
3031
import com.google.cloud.Policy;
3132
import com.google.cloud.RetryHelper;
33+
import com.google.cloud.RetryHelper.RetryHelperException;
3234
import com.google.cloud.http.BaseHttpServiceException;
3335
import com.google.cloud.storage.Acl;
3436
import com.google.cloud.storage.Acl.Role;
@@ -158,15 +160,38 @@ public void bucket_defaultAcl_get_bucket404() {
158160
assertThat(acl).isNull();
159161
}
160162

163+
@Test
164+
public void bucket_defaultAcl_list() {
165+
String bucketName = bucket.getName();
166+
// lookup an entity from the bucket which is known to exist
167+
Bucket bucketWithAcls =
168+
storage.get(
169+
bucketName, BucketGetOption.fields(BucketField.ACL, BucketField.DEFAULT_OBJECT_ACL));
170+
171+
Acl actual = bucketWithAcls.getDefaultAcl().iterator().next();
172+
173+
List<Acl> acls = retry429s(() -> storage.listDefaultAcls(bucketName), storage);
174+
175+
assertThat(acls).contains(actual);
176+
}
177+
178+
@Test
179+
public void bucket_defaultAcl_list_bucket404() {
180+
StorageException storageException =
181+
assertThrows(
182+
StorageException.class,
183+
() -> retry429s(() -> storage.listDefaultAcls(bucket.getName() + "x"), storage));
184+
185+
assertThat(storageException.getCode()).isEqualTo(404);
186+
}
187+
161188
@Test
162189
@CrossRun.Ignore(transports = Transport.GRPC)
163190
public void testBucketDefaultAcl() {
164191
// TODO: break this test up into each of the respective scenarios
165-
// DONE ~1. get default ACL for specific entity~
166192
// 2. Delete a default ACL for a specific entity
167193
// 3. Create a default ACL for specific entity
168194
// 4. Update default ACL to change role of a specific entity
169-
// 5. List default ACLs
170195

171196
// according to https://cloud.google.com/storage/docs/access-control/lists#default
172197
// it can take up to 30 seconds for default acl updates to propagate
@@ -976,19 +1001,29 @@ public void testBlobAcl() {
9761001
}
9771002

9781003
static <T> T retry429s(Callable<T> c, Storage storage) {
979-
return RetryHelper.runWithRetries(
980-
c,
981-
storage.getOptions().getRetrySettings(),
982-
new BasicResultRetryAlgorithm<Object>() {
983-
@Override
984-
public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) {
985-
if (previousThrowable instanceof BaseHttpServiceException) {
986-
BaseHttpServiceException httpException = (BaseHttpServiceException) previousThrowable;
987-
return httpException.getCode() == 429;
1004+
try {
1005+
return RetryHelper.runWithRetries(
1006+
c,
1007+
storage.getOptions().getRetrySettings(),
1008+
new BasicResultRetryAlgorithm<Object>() {
1009+
@Override
1010+
public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) {
1011+
if (previousThrowable instanceof BaseHttpServiceException) {
1012+
BaseHttpServiceException httpException =
1013+
(BaseHttpServiceException) previousThrowable;
1014+
return httpException.getCode() == 429;
1015+
}
1016+
return false;
9881017
}
989-
return false;
990-
}
991-
},
992-
storage.getOptions().getClock());
1018+
},
1019+
storage.getOptions().getClock());
1020+
} catch (RetryHelperException e) {
1021+
Throwable cause = e.getCause();
1022+
if (cause instanceof RuntimeException) {
1023+
throw (RuntimeException) cause;
1024+
} else {
1025+
throw e;
1026+
}
1027+
}
9931028
}
9941029
}

0 commit comments

Comments
 (0)