Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add hierarchical namespace and folders features #2445

Merged
merged 11 commits into from
Mar 14, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ final class GrpcConversions {
Codec.of(this::conditionEncode, this::conditionDecode);

private final Codec<BucketInfo.HierarchicalNamespace, Bucket.HierarchicalNamespace>
hierarchicalNamespaceCodec =
hierarchicalNamespaceCodec =
Codec.of(this::hierarchicalNamespaceEncode, this::hierarchicalNamespaceDecode);

@VisibleForTesting
Expand Down Expand Up @@ -303,7 +303,7 @@ private BucketInfo bucketInfoDecode(Bucket from) {
}
if (from.hasHierarchicalNamespace()) {
to.setHierarchicalNamespace(
hierarchicalNamespaceCodec.decode(from.getHierarchicalNamespace()));
hierarchicalNamespaceCodec.decode(from.getHierarchicalNamespace()));
}
// TODO(frankyn): Add SelfLink when the field is available
if (!from.getEtag().isEmpty()) {
Expand Down Expand Up @@ -391,9 +391,9 @@ private Bucket bucketInfoEncode(BucketInfo from) {
.build());
}
ifNonNull(
from.getHierarchicalNamespace(),
hierarchicalNamespaceCodec::encode,
to::setHierarchicalNamespace);
from.getHierarchicalNamespace(),
hierarchicalNamespaceCodec::encode,
to::setHierarchicalNamespace);
// TODO(frankyn): Add SelfLink when the field is available
ifNonNull(from.getEtag(), to::setEtag);
return to.build();
Expand Down Expand Up @@ -602,14 +602,14 @@ private Bucket.Autoclass autoclassEncode(BucketInfo.Autoclass from) {
}

private Bucket.HierarchicalNamespace hierarchicalNamespaceEncode(
BucketInfo.HierarchicalNamespace from) {
BucketInfo.HierarchicalNamespace from) {
Bucket.HierarchicalNamespace.Builder to = Bucket.HierarchicalNamespace.newBuilder();
ifNonNull(from.getEnabled(), to::setEnabled);
return to.build();
}

private BucketInfo.HierarchicalNamespace hierarchicalNamespaceDecode(
Bucket.HierarchicalNamespace from) {
Bucket.HierarchicalNamespace from) {
BucketInfo.HierarchicalNamespace.Builder to = BucketInfo.HierarchicalNamespace.newBuilder();
to.setEnabled(from.getEnabled());
return to.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ final class JsonConversions {
Codec.of(this::blobInfoEncode, this::blobInfoDecode);

private final Codec<BucketInfo.HierarchicalNamespace, Bucket.HierarchicalNamespace>
hierarchicalNamespaceCodec =
hierarchicalNamespaceCodec =
Codec.of(this::hierarchicalNamespaceEncode, this::hierarchicalNamespaceDecode);

private final Codec<NotificationInfo, com.google.api.services.storage.model.Notification>
Expand Down Expand Up @@ -442,9 +442,9 @@ private Bucket bucketInfoEncode(BucketInfo from) {
to::setCustomPlacementConfig);
ifNonNull(from.getObjectRetention(), this::objectRetentionEncode, to::setObjectRetention);
ifNonNull(
from.getHierarchicalNamespace(),
this::hierarchicalNamespaceEncode,
to::setHierarchicalNamespace);
from.getHierarchicalNamespace(),
this::hierarchicalNamespaceEncode,
to::setHierarchicalNamespace);
return to;
}

Expand Down Expand Up @@ -496,9 +496,9 @@ private BucketInfo bucketInfoDecode(com.google.api.services.storage.model.Bucket
this::customPlacementConfigDecode,
to::setCustomPlacementConfig);
ifNonNull(
from.getHierarchicalNamespace(),
this::hierarchicalNamespaceDecode,
to::setHierarchicalNamespace);
from.getHierarchicalNamespace(),
this::hierarchicalNamespaceDecode,
to::setHierarchicalNamespace);
ifNonNull(from.getObjectRetention(), this::objectRetentionDecode, to::setObjectRetention);
return to.build();
}
Expand Down Expand Up @@ -873,19 +873,20 @@ private com.google.api.services.storage.model.Notification notificationEncode(
return to;
}

private Bucket.HierarchicalNamespace hierarchicalNamespaceEncode(BucketInfo.HierarchicalNamespace from) {
private Bucket.HierarchicalNamespace hierarchicalNamespaceEncode(
BucketInfo.HierarchicalNamespace from) {
Bucket.HierarchicalNamespace to = new Bucket.HierarchicalNamespace();
ifNonNull(from.getEnabled(), to::setEnabled);
return to;
}

private BucketInfo.HierarchicalNamespace hierarchicalNamespaceDecode(Bucket.HierarchicalNamespace from) {
private BucketInfo.HierarchicalNamespace hierarchicalNamespaceDecode(
Bucket.HierarchicalNamespace from) {
BucketInfo.HierarchicalNamespace.Builder to = BucketInfo.HierarchicalNamespace.newBuilder();
to.setEnabled(from.getEnabled());
return to.build();
}


private NotificationInfo notificationDecode(
com.google.api.services.storage.model.Notification from) {
NotificationInfo.Builder builder = new NotificationInfo.BuilderImpl(from.getTopic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ static IncludeFoldersAsPrefixes includeFoldersAsPrefixes(boolean includeFoldersA
return new IncludeFoldersAsPrefixes(includeFoldersAsPrefixes);
}


@Deprecated
static DetectContentType detectContentType() {
return DetectContentType.INSTANCE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ enum Option {
ENABLE_OBJECT_RETENTION("enableObjectRetention"),
RETURN_RAW_INPUT_STREAM("returnRawInputStream"),
OVERRIDE_UNLOCKED_RETENTION("overrideUnlockedRetention"),
INCLUDE_FOLDERS_AS_PREFIXES("includeFoldersAsPrefixes");;
INCLUDE_FOLDERS_AS_PREFIXES("includeFoldersAsPrefixes");
;

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,17 +553,19 @@ public void testUpdateBucket_noModification() throws Exception {
assertThat(gen2).isEqualTo(gen1);
}
}

@Test
public void createBucketWithHierarchicalNamespace() {
String bucketName = generator.randomBucketName();
storage.create(
BucketInfo.newBuilder(bucketName)
.setHierarchicalNamespace(BucketInfo.HierarchicalNamespace.newBuilder().setEnabled(true).build())
.setIamConfiguration(
BucketInfo.IamConfiguration.newBuilder()
.setIsUniformBucketLevelAccessEnabled(true)
.build())
.build());
BucketInfo.newBuilder(bucketName)
.setHierarchicalNamespace(
BucketInfo.HierarchicalNamespace.newBuilder().setEnabled(true).build())
.setIamConfiguration(
BucketInfo.IamConfiguration.newBuilder()
.setIsUniformBucketLevelAccessEnabled(true)
.build())
.build());
try {
Bucket remoteBucket = storage.get(bucketName);
assertNotNull(remoteBucket.getHierarchicalNamespace());
Expand All @@ -572,30 +574,32 @@ public void createBucketWithHierarchicalNamespace() {
BucketCleaner.doCleanup(bucketName, storage);
}
}

@Test
public void testListObjectsWithFolders() throws Exception {
String bucketName = generator.randomBucketName();
storage.create(
BucketInfo.newBuilder(bucketName)
.setHierarchicalNamespace(BucketInfo.HierarchicalNamespace.newBuilder().setEnabled(true).build())
.setIamConfiguration(
BucketInfo.IamConfiguration.newBuilder()
.setIsUniformBucketLevelAccessEnabled(true)
.build())
.build());
BucketInfo.newBuilder(bucketName)
.setHierarchicalNamespace(
BucketInfo.HierarchicalNamespace.newBuilder().setEnabled(true).build())
.setIamConfiguration(
BucketInfo.IamConfiguration.newBuilder()
.setIsUniformBucketLevelAccessEnabled(true)
.build())
.build());
try {
com.google.api.services.storage.Storage apiaryStorage =
new HttpStorageRpc(StorageOptions.getDefaultInstance()).getStorage();
new HttpStorageRpc(StorageOptions.getDefaultInstance()).getStorage();
apiaryStorage
.folders()
.insert(bucketName, new Folder().setName("F").setBucket(bucketName))
.execute();
.folders()
.insert(bucketName, new Folder().setName("F").setBucket(bucketName))
.execute();

Page<Blob> blobs =
storage.list(
bucketName,
Storage.BlobListOption.delimiter("/"),
Storage.BlobListOption.includeFolders(false));
storage.list(
bucketName,
Storage.BlobListOption.delimiter("/"),
Storage.BlobListOption.includeFolders(false));

boolean found = false;
for (Blob blob : blobs.iterateAll()) {
Expand All @@ -606,10 +610,10 @@ public void testListObjectsWithFolders() throws Exception {
assert (!found);

blobs =
storage.list(
bucketName,
Storage.BlobListOption.delimiter("/"),
Storage.BlobListOption.includeFolders(true));
storage.list(
bucketName,
Storage.BlobListOption.delimiter("/"),
Storage.BlobListOption.includeFolders(true));

for (Blob blob : blobs.iterateAll()) {
if (blob.getName().equals("F/")) {
Expand Down