diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java index 26d39627f50..f5111ef6f0a 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileStatus.java @@ -207,6 +207,15 @@ public FsPermission getPermission() { return permission; } + /** + * Tell whether the underlying file or directory has ACLs set. + * + * @return true if the underlying file or directory has ACLs set. + */ + public boolean hasAcl() { + return permission.getAclBit(); + } + /** * Tell whether the underlying file or directory is encrypted or not. * @@ -399,6 +408,9 @@ public String toString() { if(isSymlink()) { sb.append("; symlink=" + symlink); } + sb.append("; hasAcl=" + hasAcl()); + sb.append("; isEncrypted=" + isEncrypted()); + sb.append("; isErasureCoded=" + isErasureCoded()); sb.append("}"); return sb.toString(); } diff --git a/hadoop-common-project/hadoop-common/src/site/markdown/filesystem/filesystem.md b/hadoop-common-project/hadoop-common/src/site/markdown/filesystem/filesystem.md index 97bc7d19dfd..b464941537b 100644 --- a/hadoop-common-project/hadoop-common/src/site/markdown/filesystem/filesystem.md +++ b/hadoop-common-project/hadoop-common/src/site/markdown/filesystem/filesystem.md @@ -86,20 +86,15 @@ Get the status of a path stat.length = 0 stat.isdir = False stat.symlink = FS.Symlinks[p] - if inEncryptionZone(FS, p) : - stat.isEncrypted = True - else - stat.isEncrypted = False - if isErasureCoded(FS, p) : - stat.isErasureCoded = True - else - stat.isErasureCoded = False + stat.hasAcl = hasACL(FS, p) + stat.isEncrypted = inEncryptionZone(FS, p) + stat.isErasureCoded = isErasureCoded(FS, p) The returned `FileStatus` status of the path additionally carries details on -Encryption and Erasure Coding information. `getFileStatus(Path p).isEncrypted()` -can be queried to find if the path is Encrypted. -Likewise, `getFileStatus(Path p).isErasureCoded()` will tell if the path is -Erasure Coded or not. +ACL, encryption and erasure coding information. `getFileStatus(Path p).hasAcl()` +can be queried to find if the path has an ACL. `getFileStatus(Path p).isEncrypted()` +can be queried to find if the path is encrypted. `getFileStatus(Path p).isErasureCoded()` +will tell if the path is erasure coded or not. ### `Path getHomeDirectory()` diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java index 35f2bad5657..d29b1a40711 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFileStatus.java @@ -295,11 +295,15 @@ private void validateToString(FileStatus fileStatus) throws IOException { expected.append("permission=").append(fileStatus.getPermission()).append("; "); if(fileStatus.isSymlink()) { expected.append("isSymlink=").append(true).append("; "); - expected.append("symlink=").append(fileStatus.getSymlink()).append("}"); + expected.append("symlink=").append(fileStatus.getSymlink()).append("; "); } else { - expected.append("isSymlink=").append(false).append("}"); + expected.append("isSymlink=").append(false).append("; "); } - + expected.append("hasAcl=").append(fileStatus.hasAcl()).append("; "); + expected.append("isEncrypted=").append( + fileStatus.isEncrypted()).append("; "); + expected.append("isErasureCoded=").append( + fileStatus.isErasureCoded()).append("}"); assertEquals(expected.toString(), fileStatus.toString()); } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewfsFileStatus.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewfsFileStatus.java index 449e2e33621..0c31c8ed6a9 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewfsFileStatus.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewfsFileStatus.java @@ -75,6 +75,9 @@ public void testFileStatusSerialziation() FileStatus stat = vfs.getFileStatus(path); assertEquals(content.length, stat.getLen()); ContractTestUtils.assertNotErasureCoded(vfs, path); + assertTrue(path + " should have erasure coding unset in " + + "FileStatus#toString(): " + stat, + stat.toString().contains("isErasureCoded=false")); // check serialization/deserialization DataOutputBuffer dob = new DataOutputBuffer(); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatus.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatus.java index 7631e7d70cc..c74bb632a74 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatus.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatus.java @@ -139,6 +139,9 @@ public void testGetFileStatusOnFile() throws Exception { assertEquals(file1.makeQualified(fs.getUri(), fs.getWorkingDirectory()).toString(), status.getPath().toString()); + assertTrue(file1 + " should have erasure coding unset in " + + "FileStatus#toString(): " + status, + status.toString().contains("isErasureCoded=false")); } /** Test the FileStatus obtained calling listStatus on a file */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatusWithECPolicy.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatusWithECPolicy.java index 0e270ff75c7..e04f9573256 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatusWithECPolicy.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestFileStatusWithECPolicy.java @@ -23,6 +23,7 @@ import java.io.IOException; +import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.contract.ContractTestUtils; import org.apache.hadoop.fs.permission.FsPermission; @@ -85,7 +86,7 @@ public void testFileStatusWithECPolicy() throws Exception { assertNotNull(ecPolicy2); assertTrue(ecPolicy1.equals(ecPolicy2)); - // test file doesn't have an EC policy + // test file with EC policy fs.create(file).close(); final ErasureCodingPolicy ecPolicy3 = fs.getClient().getFileInfo(file.toUri().getPath()) @@ -93,5 +94,9 @@ public void testFileStatusWithECPolicy() throws Exception { assertNotNull(ecPolicy3); assertTrue(ecPolicy1.equals(ecPolicy3)); ContractTestUtils.assertErasureCoded(fs, file); + FileStatus status = fs.getFileStatus(file); + assertTrue(file + " should have erasure coding set in " + + "FileStatus#toString(): " + status, + status.toString().contains("isErasureCoded=true")); } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/FSAclBaseTest.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/FSAclBaseTest.java index 81270e6f2bd..60b0ab168d2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/FSAclBaseTest.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/FSAclBaseTest.java @@ -50,6 +50,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -120,10 +121,16 @@ public void testModifyAclEntries() throws IOException { aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); + Assert.assertTrue(path + " should have ACLs in FileStatus!", + fs.getFileStatus(path).hasAcl()); + aclSpec = Lists.newArrayList( aclEntry(ACCESS, USER, "foo", READ_EXECUTE), aclEntry(DEFAULT, USER, "foo", READ_EXECUTE)); fs.modifyAclEntries(path, aclSpec); + Assert.assertTrue(path + " should have ACLs in FileStatus!", + fs.getFileStatus(path).hasAcl()); + AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { @@ -561,8 +568,18 @@ public void testRemoveAcl() throws IOException { aclEntry(ACCESS, GROUP, READ_EXECUTE), aclEntry(ACCESS, OTHER, NONE), aclEntry(DEFAULT, USER, "foo", ALL)); + fs.setAcl(path, aclSpec); + Assert.assertTrue(path + " should have ACLs in FileStatus!", + fs.getFileStatus(path).hasAcl()); + Assert.assertTrue(path + " should have ACLs in FileStatus#toString()!", + fs.getFileStatus(path).toString().contains("hasAcl=true")); fs.removeAcl(path); + Assert.assertFalse(path + " should not have ACLs in FileStatus!", + fs.getFileStatus(path).hasAcl()); + Assert.assertTrue(path + " should not have ACLs in FileStatus#toString()!", + fs.getFileStatus(path).toString().contains("hasAcl=false")); + AclStatus s = fs.getAclStatus(path); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { }, returned); @@ -968,8 +985,14 @@ public void testDefaultAclNewDir() throws Exception { List aclSpec = Lists.newArrayList( aclEntry(DEFAULT, USER, "foo", ALL)); fs.setAcl(path, aclSpec); + Assert.assertTrue(path + " should have ACLs in FileStatus!", + fs.getFileStatus(path).hasAcl()); + Path dirPath = new Path(path, "dir1"); fs.mkdirs(dirPath); + Assert.assertTrue(dirPath + " should have ACLs in FileStatus!", + fs.getFileStatus(dirPath).hasAcl()); + AclStatus s = fs.getAclStatus(dirPath); AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]); assertArrayEquals(new AclEntry[] { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFS.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFS.java index 3c366c39dad..46a8a56f1c1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFS.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFS.java @@ -547,24 +547,36 @@ public void testWebHdfsErasureCodingFiles() throws Exception { Assert.assertEquals(expectedECDirStatus.isErasureCoded(), actualECDirStatus.isErasureCoded()); ContractTestUtils.assertErasureCoded(dfs, ecDir); + assertTrue(ecDir+ " should have erasure coding set in " + + "FileStatus#toString(): " + actualECDirStatus, + actualECDirStatus.toString().contains("isErasureCoded=true")); FileStatus expectedECFileStatus = dfs.getFileStatus(ecFile); FileStatus actualECFileStatus = webHdfs.getFileStatus(ecFile); Assert.assertEquals(expectedECFileStatus.isErasureCoded(), actualECFileStatus.isErasureCoded()); ContractTestUtils.assertErasureCoded(dfs, ecFile); + assertTrue(ecFile+ " should have erasure coding set in " + + "FileStatus#toString(): " + actualECFileStatus, + actualECFileStatus.toString().contains("isErasureCoded=true")); FileStatus expectedNormalDirStatus = dfs.getFileStatus(normalDir); FileStatus actualNormalDirStatus = webHdfs.getFileStatus(normalDir); Assert.assertEquals(expectedNormalDirStatus.isErasureCoded(), actualNormalDirStatus.isErasureCoded()); ContractTestUtils.assertNotErasureCoded(dfs, normalDir); + assertTrue(normalDir + " should have erasure coding unset in " + + "FileStatus#toString(): " + actualNormalDirStatus, + actualNormalDirStatus.toString().contains("isErasureCoded=false")); FileStatus expectedNormalFileStatus = dfs.getFileStatus(normalFile); FileStatus actualNormalFileStatus = webHdfs.getFileStatus(normalDir); Assert.assertEquals(expectedNormalFileStatus.isErasureCoded(), actualNormalFileStatus.isErasureCoded()); ContractTestUtils.assertNotErasureCoded(dfs, normalFile); + assertTrue(normalFile + " should have erasure coding unset in " + + "FileStatus#toString(): " + actualNormalFileStatus, + actualNormalFileStatus.toString().contains("isErasureCoded=false")); } finally { if (cluster != null) { diff --git a/hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/TestS3AGetFileStatus.java b/hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/TestS3AGetFileStatus.java index deb3963b2d2..58e4d3074bc 100644 --- a/hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/TestS3AGetFileStatus.java +++ b/hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/TestS3AGetFileStatus.java @@ -62,6 +62,9 @@ public void testFile() throws Exception { assertEquals(meta.getContentLength(), stat.getLen()); assertEquals(meta.getLastModified().getTime(), stat.getModificationTime()); ContractTestUtils.assertNotErasureCoded(fs, path); + assertTrue(path + " should have erasure coding unset in " + + "FileStatus#toString(): " + stat, + stat.toString().contains("isErasureCoded=false")); } @Test @@ -101,6 +104,9 @@ public void testImplicitDirectory() throws Exception { assertEquals(fs.makeQualified(path), stat.getPath()); assertTrue(stat.isDirectory()); ContractTestUtils.assertNotErasureCoded(fs, path); + assertTrue(path + " should have erasure coding unset in " + + "FileStatus#toString(): " + stat, + stat.toString().contains("isErasureCoded=false")); } @Test diff --git a/hadoop-tools/hadoop-azure-datalake/src/test/java/org/apache/hadoop/fs/adl/TestGetFileStatus.java b/hadoop-tools/hadoop-azure-datalake/src/test/java/org/apache/hadoop/fs/adl/TestGetFileStatus.java index df39a40cebd..0ea4b868c1d 100644 --- a/hadoop-tools/hadoop-azure-datalake/src/test/java/org/apache/hadoop/fs/adl/TestGetFileStatus.java +++ b/hadoop-tools/hadoop-azure-datalake/src/test/java/org/apache/hadoop/fs/adl/TestGetFileStatus.java @@ -65,6 +65,9 @@ public void getFileStatusReturnsAsExpected() Assert.assertEquals(new FsPermission("777"), fileStatus.getPermission()); Assert.assertEquals("NotSupportYet", fileStatus.getOwner()); Assert.assertEquals("NotSupportYet", fileStatus.getGroup()); + Assert.assertTrue(path + " should have Acl!", fileStatus.hasAcl()); + Assert.assertFalse(path + " should not be encrypted!", + fileStatus.isEncrypted()); Assert.assertFalse(path + " should not be erasure coded!", fileStatus.isErasureCoded()); } @@ -82,6 +85,8 @@ public void getFileStatusAclBit() LOG.debug("Time : " + (endTime - startTime)); Assert.assertTrue(fileStatus.isFile()); Assert.assertEquals(true, fileStatus.getPermission().getAclBit()); + Assert.assertEquals(fileStatus.hasAcl(), + fileStatus.getPermission().getAclBit()); // With ACLBIT set to false getMockServer().enqueue(new MockResponse().setResponseCode(200) @@ -93,5 +98,7 @@ public void getFileStatusAclBit() LOG.debug("Time : " + (endTime - startTime)); Assert.assertTrue(fileStatus.isFile()); Assert.assertEquals(false, fileStatus.getPermission().getAclBit()); + Assert.assertEquals(fileStatus.hasAcl(), + fileStatus.getPermission().getAclBit()); } }