From 2e8ea780a45c0eccb8f106b2bf072b59446a1cc4 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Thu, 16 Apr 2015 07:14:44 -0700 Subject: [PATCH] HDFS-8142. DistributedFileSystem encryption zone commands should resolve relative paths. Contributed by Rakesh R. --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 ++ .../hadoop/hdfs/DistributedFileSystem.java | 51 +++++++++++++++++-- .../hadoop/hdfs/TestEncryptionZones.java | 18 +++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 65234236f5..cc9d901aa8 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -502,6 +502,9 @@ Release 2.8.0 - UNRELEASED HDFS-8055. NullPointerException when topology script is missing. (Anu Engineer via cnauroth) + HDFS-8142. DistributedFileSystem encryption zone commands should resolve + relative paths. (Rakesh R via wang) + Release 2.7.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java index 21f5107e75..8e7daf3a97 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java @@ -2046,16 +2046,59 @@ public AclStatus next(final FileSystem fs, final Path p) } /* HDFS only */ - public void createEncryptionZone(Path path, String keyName) + public void createEncryptionZone(final Path path, final String keyName) throws IOException { - dfs.createEncryptionZone(getPathName(path), keyName); + Path absF = fixRelativePart(path); + new FileSystemLinkResolver() { + @Override + public Void doCall(final Path p) throws IOException, + UnresolvedLinkException { + dfs.createEncryptionZone(getPathName(p), keyName); + return null; + } + + @Override + public Void next(final FileSystem fs, final Path p) throws IOException { + if (fs instanceof DistributedFileSystem) { + DistributedFileSystem myDfs = (DistributedFileSystem) fs; + myDfs.createEncryptionZone(p, keyName); + return null; + } else { + throw new UnsupportedOperationException( + "Cannot call createEncryptionZone" + + " on a symlink to a non-DistributedFileSystem: " + path + + " -> " + p); + } + } + }.resolve(this, absF); } /* HDFS only */ - public EncryptionZone getEZForPath(Path path) + public EncryptionZone getEZForPath(final Path path) throws IOException { Preconditions.checkNotNull(path); - return dfs.getEZForPath(getPathName(path)); + Path absF = fixRelativePart(path); + return new FileSystemLinkResolver() { + @Override + public EncryptionZone doCall(final Path p) throws IOException, + UnresolvedLinkException { + return dfs.getEZForPath(getPathName(p)); + } + + @Override + public EncryptionZone next(final FileSystem fs, final Path p) + throws IOException { + if (fs instanceof DistributedFileSystem) { + DistributedFileSystem myDfs = (DistributedFileSystem) fs; + return myDfs.getEZForPath(p); + } else { + throw new UnsupportedOperationException( + "Cannot call getEZForPath" + + " on a symlink to a non-DistributedFileSystem: " + path + + " -> " + p); + } + } + }.resolve(this, absF); } /* HDFS only */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java index dbb7ea59c3..e43593df2e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java @@ -1310,4 +1310,22 @@ public void testEncryptionZonesOnRootPath() throws Exception { true, fs.getFileStatus(zoneFile).isEncrypted()); DFSTestUtil.verifyFilesNotEqual(fs, zoneFile, rawFile, len); } + + @Test(timeout = 60000) + public void testEncryptionZonesOnRelativePath() throws Exception { + final int len = 8196; + final Path baseDir = new Path("/somewhere/base"); + final Path zoneDir = new Path("zone"); + final Path zoneFile = new Path("file"); + fs.setWorkingDirectory(baseDir); + fs.mkdirs(zoneDir); + dfsAdmin.createEncryptionZone(zoneDir, TEST_KEY); + DFSTestUtil.createFile(fs, zoneFile, len, (short) 1, 0xFEED); + + assertNumZones(1); + assertZonePresent(TEST_KEY, "/somewhere/base/zone"); + + assertEquals("Got unexpected ez path", "/somewhere/base/zone", dfsAdmin + .getEncryptionZoneForPath(zoneDir).getPath().toString()); + } }