This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 77680bda7d5 HDDS-12094. OzoneKey isFile returns true for directories
(#8838)
77680bda7d5 is described below
commit 77680bda7d59c526be823a7f8127abfc091a020e
Author: Anastasia Kostryukova <[email protected]>
AuthorDate: Mon Nov 17 15:16:24 2025 +0300
HDDS-12094. OzoneKey isFile returns true for directories (#8838)
Co-authored-by: Rishabh Patel <[email protected]>
---
.../hadoop/ozone/om/helpers/BasicOmKeyInfo.java | 15 ++++++--
.../src/main/smoketest/compatibility/read.robot | 13 +++++++
.../ozone/client/rpc/OzoneRpcClientTests.java | 40 ++++++++++++++++++++++
.../src/main/proto/OmClientProtocol.proto | 1 +
4 files changed, 67 insertions(+), 2 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BasicOmKeyInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BasicOmKeyInfo.java
index 371e4f38c7b..420bac76664 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BasicOmKeyInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/BasicOmKeyInfo.java
@@ -202,6 +202,7 @@ public BasicKeyInfo getProtobuf() {
.setDataSize(dataSize)
.setCreationTime(creationTime)
.setModificationTime(modificationTime)
+ .setIsFile(isFile)
.setType(replicationConfig.getReplicationType())
.setIsEncrypted(isEncrypted);
if (ownerName != null) {
@@ -241,10 +242,15 @@ public static BasicOmKeyInfo getFromProtobuf(BasicKeyInfo
basicKeyInfo,
basicKeyInfo.getFactor(),
basicKeyInfo.getEcReplicationConfig()))
.setETag(basicKeyInfo.getETag())
- .setIsFile(!keyName.endsWith("/"))
.setOwnerName(basicKeyInfo.getOwnerName())
.setIsEncrypted(basicKeyInfo.getIsEncrypted());
+ if (basicKeyInfo.hasIsFile()) {
+ builder.setIsFile(basicKeyInfo.getIsFile());
+ } else {
+ builder.setIsFile(!keyName.endsWith("/"));
+ }
+
return builder.build();
}
@@ -268,10 +274,15 @@ public static BasicOmKeyInfo getFromProtobuf(String
volumeName,
basicKeyInfo.getFactor(),
basicKeyInfo.getEcReplicationConfig()))
.setETag(basicKeyInfo.getETag())
- .setIsFile(!keyName.endsWith("/"))
.setOwnerName(basicKeyInfo.getOwnerName())
.setIsEncrypted(basicKeyInfo.getIsEncrypted());
+ if (basicKeyInfo.hasIsFile()) {
+ builder.setIsFile(basicKeyInfo.getIsFile());
+ } else {
+ builder.setIsFile(!keyName.endsWith("/"));
+ }
+
return builder.build();
}
diff --git a/hadoop-ozone/dist/src/main/smoketest/compatibility/read.robot
b/hadoop-ozone/dist/src/main/smoketest/compatibility/read.robot
index b5dfbb9739e..406b19fbe4c 100644
--- a/hadoop-ozone/dist/src/main/smoketest/compatibility/read.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/compatibility/read.robot
@@ -155,3 +155,16 @@ HSync Lease Recover Can Be Used
Pass Execution If '${CLIENT_VERSION}' < '${HSYNC_VERSION}' Client
does not support HSYNC
Pass Execution If '${CLUSTER_VERSION}' < '${HSYNC_VERSION}' Cluster
does not support HSYNC
Execute ozone admin om lease recover
--path=ofs://om/vol1/fso-bucket-${DATA_VERSION}/dir/subdir/file
+
+Key Info File Flag Should Be Set Correctly
+ Pass Execution If '${CLUSTER_VERSION}' <= '${EC_VERSION}' Cluster
does not support 'file' flag
+ Pass Execution If '${CLIENT_VERSION}' <= '${EC_VERSION}' Client does
not support 'file' flag
+
+ ${dirpath} = Set Variable
/vol1/fso-bucket-${DATA_VERSION}/dir/subdir/
+ ${filepath} = Set Variable ${dirpath}file
+
+ ${key_info} = Execute ozone sh key info ${filepath}
+ Should Contain ${key_info} \"file\" : true
+
+ ${dir_info} = Execute ozone sh key info ${dirpath}
+ Should Contain ${dir_info} \"file\" : false
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
index 5cc2e8ec435..554b125ddbe 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
@@ -2927,6 +2927,46 @@ public void testListKey()
assertFalse(volABucketBIter.hasNext());
}
+ @Test
+ public void testListKeyDirectoriesAreNotFiles()
+ throws IOException {
+ // Test that directories in multilevel keys are not marked as files
+
+ String volumeA = "volume-a-" + RandomStringUtils.randomNumeric(5);
+ String bucketA = "bucket-a-" + RandomStringUtils.randomNumeric(5);
+ store.createVolume(volumeA);
+ OzoneVolume volA = store.getVolume(volumeA);
+ volA.createBucket(bucketA);
+ OzoneBucket volAbucketA = volA.getBucket(bucketA);
+
+ String keyBaseA = "key-a/";
+ for (int i = 0; i < 10; i++) {
+ byte[] value = RandomStringUtils.randomAscii(10240).getBytes(UTF_8);
+ OzoneOutputStream one = volAbucketA.createKey(
+ keyBaseA + i + "-" + RandomStringUtils.randomNumeric(5),
+ value.length, RATIS, ONE,
+ new HashMap<>());
+ one.write(value);
+ one.close();
+ }
+
+ Iterator<? extends OzoneKey> volABucketAIter1 = volAbucketA.listKeys(null);
+ while (volABucketAIter1.hasNext()) {
+ OzoneKey key = volABucketAIter1.next();
+ if (key.getName().endsWith("/")) {
+ assertFalse(key.isFile(), "Key '" + key.getName() + "' is not a file");
+ }
+ }
+
+ Iterator<? extends OzoneKey> volABucketAIter2 =
volAbucketA.listKeys("key-");
+ while (volABucketAIter2.hasNext()) {
+ OzoneKey key = volABucketAIter2.next();
+ if (key.getName().endsWith("/")) {
+ assertFalse(key.isFile(), "Key '" + key.getName() + "' is not a file");
+ }
+ }
+ }
+
@Test
public void testListKeyOnEmptyBucket()
throws IOException {
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 1e5675f612e..9d417700537 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -1205,6 +1205,7 @@ message BasicKeyInfo {
optional string eTag = 8;
optional string ownerName = 9;
optional bool isEncrypted = 10;
+ optional bool isFile = 11;
}
message DirectoryInfo {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]