Author: clamb Date: Thu Aug 14 19:11:06 2014 New Revision: 1618022 URL: http://svn.apache.org/r1618022 Log: HDFS-6546. Add non-superuser capability to get the encryption zone for a specific path. (clamb)
Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/CHANGES-fs-encryption.txt hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/client/HdfsAdmin.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolServerSideTranslatorPB.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolTranslatorPB.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/encryption.proto hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/CHANGES-fs-encryption.txt URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/CHANGES-fs-encryption.txt?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/CHANGES-fs-encryption.txt (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/CHANGES-fs-encryption.txt Thu Aug 14 19:11:06 2014 @@ -79,6 +79,9 @@ fs-encryption (Unreleased) HDFS-6834. Improve the configuration guidance in DFSClient when there are no Codec classes found in configs. (umamahesh) + HDFS-6546. Add non-superuser capability to get the encryption zone + for a specific path. (clamb) + OPTIMIZATIONS BUG FIXES Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java Thu Aug 14 19:11:06 2014 @@ -154,6 +154,7 @@ import org.apache.hadoop.hdfs.protocol.D import org.apache.hadoop.hdfs.protocol.DirectoryListing; import org.apache.hadoop.hdfs.protocol.EncryptionZone; import org.apache.hadoop.hdfs.protocol.EncryptionZoneIterator; +import org.apache.hadoop.hdfs.protocol.EncryptionZoneWithId; import org.apache.hadoop.hdfs.protocol.ExtendedBlock; import org.apache.hadoop.hdfs.protocol.HdfsBlocksMetadata; import org.apache.hadoop.hdfs.protocol.HdfsConstants; @@ -2880,6 +2881,18 @@ public class DFSClient implements java.i } } + public EncryptionZone getEZForPath(String src) + throws IOException { + checkOpen(); + try { + final EncryptionZoneWithId ezi = namenode.getEZForPath(src); + return (ezi.getId() < 0) ? null : ezi; + } catch (RemoteException re) { + throw re.unwrapRemoteException(AccessControlException.class, + UnresolvedPathException.class); + } + } + public RemoteIterator<EncryptionZone> listEncryptionZones() throws IOException { checkOpen(); Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DistributedFileSystem.java Thu Aug 14 19:11:06 2014 @@ -1806,6 +1806,13 @@ public class DistributedFileSystem exten } /* HDFS only */ + public EncryptionZone getEZForPath(Path path) + throws IOException { + Preconditions.checkNotNull(path); + return dfs.getEZForPath(getPathName(path)); + } + + /* HDFS only */ public RemoteIterator<EncryptionZone> listEncryptionZones() throws IOException { return dfs.listEncryptionZones(); Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/client/HdfsAdmin.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/client/HdfsAdmin.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/client/HdfsAdmin.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/client/HdfsAdmin.java Thu Aug 14 19:11:06 2014 @@ -21,7 +21,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import java.util.EnumSet; -import java.util.List; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceStability; @@ -248,6 +247,21 @@ public class HdfsAdmin { } /** + * Get the path of the encryption zone for a given file or directory. + * + * @param path The path to get the ez for. + * + * @return The EncryptionZone of the ez, or null if path is not in an ez. + * @throws IOException if there was a general IO exception + * @throws AccessControlException if the caller does not have access to path + * @throws FileNotFoundException if the path does not exist + */ + public EncryptionZone getEncryptionZoneForPath(Path path) + throws IOException, AccessControlException, FileNotFoundException { + return dfs.getEZForPath(path); + } + + /** * Returns a RemoteIterator which can be used to list the encryption zones * in HDFS. For large numbers of encryption zones, the iterator will fetch * the list of zones in a number of small batches. Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocol/ClientProtocol.java Thu Aug 14 19:11:06 2014 @@ -1276,6 +1276,13 @@ public interface ClientProtocol { throws IOException; /** + * Get the encryption zone for a path. + */ + @Idempotent + public EncryptionZoneWithId getEZForPath(String src) + throws IOException; + + /** * Used to implement cursor-based batched listing of {@EncryptionZone}s. * * @param prevId ID of the last item in the previous batch. If there is no Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolServerSideTranslatorPB.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolServerSideTranslatorPB.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolServerSideTranslatorPB.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolServerSideTranslatorPB.java Thu Aug 14 19:11:06 2014 @@ -179,6 +179,8 @@ import org.apache.hadoop.hdfs.protocol.p import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CheckAccessResponseProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.CreateEncryptionZoneResponseProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.CreateEncryptionZoneRequestProto; +import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.GetEZForPathResponseProto; +import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.GetEZForPathRequestProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.ListEncryptionZonesResponseProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.ListEncryptionZonesRequestProto; import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeIDProto; @@ -1319,6 +1321,21 @@ public class ClientNamenodeProtocolServe } @Override + public GetEZForPathResponseProto getEZForPath( + RpcController controller, GetEZForPathRequestProto req) + throws ServiceException { + try { + GetEZForPathResponseProto.Builder builder = + GetEZForPathResponseProto.newBuilder(); + final EncryptionZoneWithId ret = server.getEZForPath(req.getSrc()); + builder.setZone(PBHelper.convert(ret)); + return builder.build(); + } catch (IOException e) { + throw new ServiceException(e); + } + } + + @Override public ListEncryptionZonesResponseProto listEncryptionZones( RpcController controller, ListEncryptionZonesRequestProto req) throws ServiceException { Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolTranslatorPB.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolTranslatorPB.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolTranslatorPB.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/protocolPB/ClientNamenodeProtocolTranslatorPB.java Thu Aug 14 19:11:06 2014 @@ -151,6 +151,7 @@ import org.apache.hadoop.hdfs.protocol.p import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CheckAccessRequestProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.CreateEncryptionZoneRequestProto; +import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.GetEZForPathRequestProto; import org.apache.hadoop.hdfs.protocol.proto.EncryptionZonesProtos.ListEncryptionZonesRequestProto; import org.apache.hadoop.hdfs.protocol.proto.XAttrProtos.GetXAttrsRequestProto; import org.apache.hadoop.hdfs.protocol.proto.XAttrProtos.ListXAttrsRequestProto; @@ -1326,6 +1327,22 @@ public class ClientNamenodeProtocolTrans } @Override + public EncryptionZoneWithId getEZForPath(String src) + throws IOException { + final GetEZForPathRequestProto.Builder builder = + GetEZForPathRequestProto.newBuilder(); + builder.setSrc(src); + final GetEZForPathRequestProto req = builder.build(); + try { + final EncryptionZonesProtos.GetEZForPathResponseProto response = + rpcProxy.getEZForPath(null, req); + return PBHelper.convert(response.getZone()); + } catch (ServiceException e) { + throw ProtobufHelper.getRemoteException(e); + } + } + + @Override public BatchedEntries<EncryptionZoneWithId> listEncryptionZones(long id) throws IOException { final ListEncryptionZonesRequestProto req = Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java Thu Aug 14 19:11:06 2014 @@ -36,6 +36,9 @@ public class EncryptionZoneManager { public static Logger LOG = LoggerFactory.getLogger(EncryptionZoneManager .class); + private static final EncryptionZoneWithId NULL_EZ = + new EncryptionZoneWithId("", "", -1); + /** * EncryptionZoneInt is the internal representation of an encryption zone. The * external representation of an EZ is embodied in an EncryptionZone and @@ -57,7 +60,6 @@ public class EncryptionZoneManager { long getINodeId() { return inodeId; } - } private final TreeMap<Long, EncryptionZoneInt> encryptionZones; @@ -165,6 +167,23 @@ public class EncryptionZoneManager { } /** + * Returns an EncryptionZoneWithId representing the ez for a given path. + * Returns an empty marker EncryptionZoneWithId if path is not in an ez. + * + * @param iip The INodesInPath of the path to check + * @return the EncryptionZoneWithId representing the ez for the path. + */ + EncryptionZoneWithId getEZINodeForPath(INodesInPath iip) { + final EncryptionZoneInt ezi = getEncryptionZoneForPath(iip); + if (ezi == null) { + return NULL_EZ; + } else { + return new EncryptionZoneWithId(getFullPathName(ezi), ezi.getKeyName(), + ezi.getINodeId()); + } + } + + /** * Throws an exception if the provided path cannot be renamed into the * destination because of differing encryption zones. * <p/> Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java Thu Aug 14 19:11:06 2014 @@ -2640,6 +2640,15 @@ public class FSDirectory implements Clos } } + EncryptionZoneWithId getEZForPath(INodesInPath iip) { + readLock(); + try { + return ezManager.getEZINodeForPath(iip); + } finally { + readUnlock(); + } + } + BatchedListEntries<EncryptionZoneWithId> listEncryptionZones(long prevId) throws IOException { readLock(); Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java Thu Aug 14 19:11:06 2014 @@ -8571,6 +8571,41 @@ public class FSNamesystem implements Nam logAuditEvent(true, "createEncryptionZone", srcArg, null, resultingStat); } + /** + * Get the encryption zone for the specified path. + * + * @param srcArg the path of a file or directory to get the EZ for. + * @return the EZ of the of the path or null if none. + * @throws AccessControlException if the caller is not the superuser. + * @throws UnresolvedLinkException if the path can't be resolved. + */ + EncryptionZoneWithId getEZForPath(final String srcArg) + throws AccessControlException, UnresolvedLinkException, IOException { + String src = srcArg; + HdfsFileStatus resultingStat = null; + final byte[][] pathComponents = + FSDirectory.getPathComponentsForReservedPath(src); + boolean success = false; + final FSPermissionChecker pc = getPermissionChecker(); + checkOperation(OperationCategory.READ); + readLock(); + try { + if (isPermissionEnabled) { + checkPathAccess(pc, src, FsAction.READ); + } + checkOperation(OperationCategory.READ); + src = resolvePath(src, pathComponents); + final INodesInPath iip = dir.getINodesInPath(src, true); + final EncryptionZoneWithId ret = dir.getEZForPath(iip); + resultingStat = getAuditFileInfo(src, false); + success = true; + return ret; + } finally { + readUnlock(); + logAuditEvent(success, "getEZForPath", srcArg, null, resultingStat); + } + } + BatchedListEntries<EncryptionZoneWithId> listEncryptionZones(long prevId) throws IOException { boolean success = false; Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNodeRpcServer.java Thu Aug 14 19:11:06 2014 @@ -1433,6 +1433,12 @@ class NameNodeRpcServer implements Namen } @Override + public EncryptionZoneWithId getEZForPath(String src) + throws IOException { + return namesystem.getEZForPath(src); + } + + @Override public BatchedEntries<EncryptionZoneWithId> listEncryptionZones( long prevId) throws IOException { return namesystem.listEncryptionZones(prevId); Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/ClientNamenodeProtocol.proto Thu Aug 14 19:11:06 2014 @@ -799,4 +799,6 @@ service ClientNamenodeProtocol { returns(CreateEncryptionZoneResponseProto); rpc listEncryptionZones(ListEncryptionZonesRequestProto) returns(ListEncryptionZonesResponseProto); + rpc getEZForPath(GetEZForPathRequestProto) + returns(GetEZForPathResponseProto); } Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/encryption.proto URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/encryption.proto?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/encryption.proto (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/main/proto/encryption.proto Thu Aug 14 19:11:06 2014 @@ -55,3 +55,11 @@ message ListEncryptionZonesResponseProto repeated EncryptionZoneWithIdProto zones = 1; required bool hasMore = 2; } + +message GetEZForPathRequestProto { + required string src = 1; +} + +message GetEZForPathResponseProto { + required EncryptionZoneWithIdProto zone = 1; +} Modified: hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java?rev=1618022&r1=1618021&r2=1618022&view=diff ============================================================================== --- hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java (original) +++ hadoop/common/branches/fs-encryption/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestEncryptionZones.java Thu Aug 14 19:11:06 2014 @@ -19,7 +19,6 @@ package org.apache.hadoop.hdfs; import java.io.File; import java.io.IOException; -import java.security.NoSuchAlgorithmException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.List; @@ -64,6 +63,7 @@ import static org.apache.hadoop.test.Gen import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -338,6 +338,104 @@ public class TestEncryptionZones { } /** + * Test getEncryptionZoneForPath as a non super user. + */ + @Test(timeout = 60000) + public void testGetEZAsNonSuperUser() throws Exception { + + final UserGroupInformation user = UserGroupInformation. + createUserForTesting("user", new String[] { "mygroup" }); + + final Path testRoot = new Path(fsHelper.getTestRootDir()); + final Path superPath = new Path(testRoot, "superuseronly"); + final Path superPathFile = new Path(superPath, "file1"); + final Path allPath = new Path(testRoot, "accessall"); + final Path allPathFile = new Path(allPath, "file1"); + final Path nonEZDir = new Path(testRoot, "nonEZDir"); + final Path nonEZFile = new Path(nonEZDir, "file1"); + final int len = 8192; + + fsWrapper.mkdir(testRoot, new FsPermission((short) 0777), true); + fsWrapper.mkdir(superPath, new FsPermission((short) 0700), false); + fsWrapper.mkdir(allPath, new FsPermission((short) 0777), false); + fsWrapper.mkdir(nonEZDir, new FsPermission((short) 0777), false); + dfsAdmin.createEncryptionZone(superPath, TEST_KEY); + dfsAdmin.createEncryptionZone(allPath, TEST_KEY); + dfsAdmin.allowSnapshot(new Path("/")); + final Path newSnap = fs.createSnapshot(new Path("/")); + DFSTestUtil.createFile(fs, superPathFile, len, (short) 1, 0xFEED); + DFSTestUtil.createFile(fs, allPathFile, len, (short) 1, 0xFEED); + DFSTestUtil.createFile(fs, nonEZFile, len, (short) 1, 0xFEED); + + user.doAs(new PrivilegedExceptionAction<Object>() { + @Override + public Object run() throws Exception { + final HdfsAdmin userAdmin = + new HdfsAdmin(FileSystem.getDefaultUri(conf), conf); + + // Check null arg + try { + userAdmin.getEncryptionZoneForPath(null); + fail("should have thrown NPE"); + } catch (NullPointerException e) { + /* + * IWBNI we could use assertExceptionContains, but the NPE that is + * thrown has no message text. + */ + } + + // Check operation with accessible paths + assertEquals("expected ez path", allPath.toString(), + userAdmin.getEncryptionZoneForPath(allPath).getPath(). + toString()); + assertEquals("expected ez path", allPath.toString(), + userAdmin.getEncryptionZoneForPath(allPathFile).getPath(). + toString()); + + // Check operation with inaccessible (lack of permissions) path + try { + userAdmin.getEncryptionZoneForPath(superPathFile); + fail("expected AccessControlException"); + } catch (AccessControlException e) { + assertExceptionContains("Permission denied:", e); + } + + // Check operation with non-ez paths + assertNull("expected null for non-ez path", + userAdmin.getEncryptionZoneForPath(nonEZDir)); + assertNull("expected null for non-ez path", + userAdmin.getEncryptionZoneForPath(nonEZFile)); + + // Check operation with snapshots + String snapshottedAllPath = newSnap.toString() + allPath.toString(); + assertEquals("expected ez path", allPath.toString(), + userAdmin.getEncryptionZoneForPath( + new Path(snapshottedAllPath)).getPath().toString()); + + /* + * Delete the file from the non-snapshot and test that it is still ok + * in the ez. + */ + fs.delete(allPathFile, false); + assertEquals("expected ez path", allPath.toString(), + userAdmin.getEncryptionZoneForPath( + new Path(snapshottedAllPath)).getPath().toString()); + + // Delete the ez and make sure ss's ez is still ok. + fs.delete(allPath, true); + assertEquals("expected ez path", allPath.toString(), + userAdmin.getEncryptionZoneForPath( + new Path(snapshottedAllPath)).getPath().toString()); + assertNull("expected null for deleted file path", + userAdmin.getEncryptionZoneForPath(allPathFile)); + assertNull("expected null for deleted directory path", + userAdmin.getEncryptionZoneForPath(allPath)); + return null; + } + }); + } + + /** * Test success of Rename EZ on a directory which is already an EZ. */ private void doRenameEncryptionZone(FSTestWrapper wrapper) throws Exception {