HADOOP-7933. Add a getDelegationTokens api to FileSystem which checks for known tokens in the passed Credentials object. (sseth)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1226916 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
05ed36cd52
commit
7ee3e072b8
@ -202,6 +202,9 @@ Release 0.23.1 - Unreleased
|
|||||||
|
|
||||||
HADOOP-7504. Add the missing Ganglia31 opts to hadoop-metrics.properties as a comment. (harsh)
|
HADOOP-7504. Add the missing Ganglia31 opts to hadoop-metrics.properties as a comment. (harsh)
|
||||||
|
|
||||||
|
HADOOP-7933. Add a getDelegationTokens api to FileSystem which checks
|
||||||
|
for known tokens in the passed Credentials object. (sseth)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
import org.apache.hadoop.fs.Options.Rename;
|
import org.apache.hadoop.fs.Options.Rename;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.io.MultipleIOException;
|
import org.apache.hadoop.io.MultipleIOException;
|
||||||
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.SecurityUtil;
|
import org.apache.hadoop.security.SecurityUtil;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
@ -393,6 +394,40 @@ public Token<?> getDelegationToken(String renewer) throws IOException {
|
|||||||
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
||||||
return new ArrayList<Token<?>>(0);
|
return new ArrayList<Token<?>>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #getDelegationTokens(String)
|
||||||
|
* This is similar to getDelegationTokens, with the added restriction that if
|
||||||
|
* a token is already present in the passed Credentials object - that token
|
||||||
|
* is returned instead of a new delegation token.
|
||||||
|
*
|
||||||
|
* If the token is found to be cached in the Credentials object, this API does
|
||||||
|
* not verify the token validity or the passed in renewer.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param renewer the account name that is allowed to renew the token.
|
||||||
|
* @param credentials a Credentials object containing already knowing
|
||||||
|
* delegationTokens.
|
||||||
|
* @return a list of delegation tokens.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.LimitedPrivate({ "HDFS", "MapReduce" })
|
||||||
|
public List<Token<?>> getDelegationTokens(String renewer,
|
||||||
|
Credentials credentials) throws IOException {
|
||||||
|
List<Token<?>> allTokens = getDelegationTokens(renewer);
|
||||||
|
List<Token<?>> newTokens = new ArrayList<Token<?>>();
|
||||||
|
if (allTokens != null) {
|
||||||
|
for (Token<?> token : allTokens) {
|
||||||
|
Token<?> knownToken = credentials.getToken(token.getService());
|
||||||
|
if (knownToken == null) {
|
||||||
|
newTokens.add(token);
|
||||||
|
} else {
|
||||||
|
newTokens.add(knownToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newTokens;
|
||||||
|
}
|
||||||
|
|
||||||
/** create a file with the provided permission
|
/** create a file with the provided permission
|
||||||
* The permission of the file is set to be the provided permission as in
|
* The permission of the file is set to be the provided permission as in
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
import org.apache.hadoop.util.Progressable;
|
import org.apache.hadoop.util.Progressable;
|
||||||
|
|
||||||
@ -388,4 +389,11 @@ public Token<?> getDelegationToken(String renewer) throws IOException {
|
|||||||
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
||||||
return fs.getDelegationTokens(renewer);
|
return fs.getDelegationTokens(renewer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
// FileSystem
|
||||||
|
public List<Token<?>> getDelegationTokens(String renewer,
|
||||||
|
Credentials credentials) throws IOException {
|
||||||
|
return fs.getDelegationTokens(renewer, credentials);
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,9 @@
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
@ -45,7 +47,9 @@
|
|||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.fs.viewfs.InodeTree.INode;
|
import org.apache.hadoop.fs.viewfs.InodeTree.INode;
|
||||||
import org.apache.hadoop.fs.viewfs.InodeTree.INodeLink;
|
import org.apache.hadoop.fs.viewfs.InodeTree.INodeLink;
|
||||||
|
import org.apache.hadoop.io.Text;
|
||||||
import org.apache.hadoop.security.AccessControlException;
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
import org.apache.hadoop.util.Progressable;
|
import org.apache.hadoop.util.Progressable;
|
||||||
@ -495,7 +499,40 @@ public List<Token<?>> getDelegationTokens(String renewer) throws IOException {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Token<?>> getDelegationTokens(String renewer,
|
||||||
|
Credentials credentials) throws IOException {
|
||||||
|
List<InodeTree.MountPoint<FileSystem>> mountPoints =
|
||||||
|
fsState.getMountPoints();
|
||||||
|
int initialListSize = 0;
|
||||||
|
for (InodeTree.MountPoint<FileSystem> im : mountPoints) {
|
||||||
|
initialListSize += im.target.targetDirLinkList.length;
|
||||||
|
}
|
||||||
|
Set<String> seenServiceNames = new HashSet<String>();
|
||||||
|
List<Token<?>> result = new ArrayList<Token<?>>(initialListSize);
|
||||||
|
for (int i = 0; i < mountPoints.size(); ++i) {
|
||||||
|
String serviceName =
|
||||||
|
mountPoints.get(i).target.targetFileSystem.getCanonicalServiceName();
|
||||||
|
if (seenServiceNames.contains(serviceName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seenServiceNames.add(serviceName);
|
||||||
|
Token<?> knownToken = credentials.getToken(new Text(serviceName));
|
||||||
|
if (knownToken != null) {
|
||||||
|
result.add(knownToken);
|
||||||
|
} else {
|
||||||
|
List<Token<?>> tokens =
|
||||||
|
mountPoints.get(i).target.targetFileSystem
|
||||||
|
.getDelegationTokens(renewer);
|
||||||
|
if (tokens != null) {
|
||||||
|
result.addAll(tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An instance of this class represents an internal dir of the viewFs
|
* An instance of this class represents an internal dir of the viewFs
|
||||||
* that is internal dir of the mount table.
|
* that is internal dir of the mount table.
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
import org.apache.hadoop.fs.viewfs.ViewFileSystem;
|
import org.apache.hadoop.fs.viewfs.ViewFileSystem;
|
||||||
import org.apache.hadoop.fs.viewfs.ViewFileSystem.MountPoint;
|
import org.apache.hadoop.fs.viewfs.ViewFileSystem.MountPoint;
|
||||||
import org.apache.hadoop.security.AccessControlException;
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@ -89,6 +90,16 @@ public void setUp() throws Exception {
|
|||||||
// Set up the defaultMT in the config with our mount point links
|
// Set up the defaultMT in the config with our mount point links
|
||||||
//Configuration conf = new Configuration();
|
//Configuration conf = new Configuration();
|
||||||
conf = ViewFileSystemTestSetup.configWithViewfsScheme();
|
conf = ViewFileSystemTestSetup.configWithViewfsScheme();
|
||||||
|
setupMountPoints();
|
||||||
|
fsView = FileSystem.get(FsConstants.VIEWFS_URI, conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
fsTarget.delete(FileSystemTestHelper.getTestRootPath(fsTarget), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupMountPoints() {
|
||||||
ConfigUtil.addLink(conf, "/user", new Path(targetTestRoot,"user").toUri());
|
ConfigUtil.addLink(conf, "/user", new Path(targetTestRoot,"user").toUri());
|
||||||
ConfigUtil.addLink(conf, "/user2", new Path(targetTestRoot,"user").toUri());
|
ConfigUtil.addLink(conf, "/user2", new Path(targetTestRoot,"user").toUri());
|
||||||
ConfigUtil.addLink(conf, "/data", new Path(targetTestRoot,"data").toUri());
|
ConfigUtil.addLink(conf, "/data", new Path(targetTestRoot,"data").toUri());
|
||||||
@ -100,20 +111,17 @@ public void setUp() throws Exception {
|
|||||||
new Path(targetTestRoot,"missingTarget").toUri());
|
new Path(targetTestRoot,"missingTarget").toUri());
|
||||||
ConfigUtil.addLink(conf, "/linkToAFile",
|
ConfigUtil.addLink(conf, "/linkToAFile",
|
||||||
new Path(targetTestRoot,"aFile").toUri());
|
new Path(targetTestRoot,"aFile").toUri());
|
||||||
|
|
||||||
fsView = FileSystem.get(FsConstants.VIEWFS_URI, conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
fsTarget.delete(FileSystemTestHelper.getTestRootPath(fsTarget), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetMountPoints() {
|
public void testGetMountPoints() {
|
||||||
ViewFileSystem viewfs = (ViewFileSystem) fsView;
|
ViewFileSystem viewfs = (ViewFileSystem) fsView;
|
||||||
MountPoint[] mountPoints = viewfs.getMountPoints();
|
MountPoint[] mountPoints = viewfs.getMountPoints();
|
||||||
Assert.assertEquals(7, mountPoints.length);
|
Assert.assertEquals(getExpectedMountPoints(), mountPoints.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getExpectedMountPoints() {
|
||||||
|
return 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,9 +133,46 @@ public void testGetMountPoints() {
|
|||||||
public void testGetDelegationTokens() throws IOException {
|
public void testGetDelegationTokens() throws IOException {
|
||||||
List<Token<?>> delTokens =
|
List<Token<?>> delTokens =
|
||||||
fsView.getDelegationTokens("sanjay");
|
fsView.getDelegationTokens("sanjay");
|
||||||
Assert.assertEquals(0, delTokens.size());
|
Assert.assertEquals(getExpectedDelegationTokenCount(), delTokens.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getExpectedDelegationTokenCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDelegationTokensWithCredentials() throws IOException {
|
||||||
|
Credentials credentials = new Credentials();
|
||||||
|
List<Token<?>> delTokens =
|
||||||
|
fsView.getDelegationTokens("sanjay", credentials);
|
||||||
|
|
||||||
|
int expectedTokenCount = getExpectedDelegationTokenCountWithCredentials();
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedTokenCount, delTokens.size());
|
||||||
|
for (int i = 0; i < expectedTokenCount / 2; i++) {
|
||||||
|
Token<?> token = delTokens.get(i);
|
||||||
|
credentials.addToken(token.getService(), token);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Token<?>> delTokens2 =
|
||||||
|
fsView.getDelegationTokens("sanjay", credentials);
|
||||||
|
Assert.assertEquals(expectedTokenCount, delTokens2.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < delTokens2.size(); i++) {
|
||||||
|
for (int j = 0; j < delTokens.size(); j++) {
|
||||||
|
if (delTokens.get(j) == delTokens2.get(i)) {
|
||||||
|
delTokens.remove(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertEquals(expectedTokenCount / 2, delTokens.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int getExpectedDelegationTokenCountWithCredentials() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicPaths() {
|
public void testBasicPaths() {
|
||||||
Assert.assertEquals(FsConstants.VIEWFS_URI,
|
Assert.assertEquals(FsConstants.VIEWFS_URI,
|
||||||
@ -340,7 +385,7 @@ public void testListOnInternalDirsOfMountTable() throws IOException {
|
|||||||
|
|
||||||
FileStatus[] dirPaths = fsView.listStatus(new Path("/"));
|
FileStatus[] dirPaths = fsView.listStatus(new Path("/"));
|
||||||
FileStatus fs;
|
FileStatus fs;
|
||||||
Assert.assertEquals(6, dirPaths.length);
|
Assert.assertEquals(getExpectedDirPaths(), dirPaths.length);
|
||||||
fs = FileSystemTestHelper.containsPath(fsView, "/user", dirPaths);
|
fs = FileSystemTestHelper.containsPath(fsView, "/user", dirPaths);
|
||||||
Assert.assertNotNull(fs);
|
Assert.assertNotNull(fs);
|
||||||
Assert.assertTrue("A mount should appear as symlink", fs.isSymlink());
|
Assert.assertTrue("A mount should appear as symlink", fs.isSymlink());
|
||||||
@ -372,6 +417,10 @@ public void testListOnInternalDirsOfMountTable() throws IOException {
|
|||||||
Assert.assertTrue("A mount should appear as symlink", fs.isSymlink());
|
Assert.assertTrue("A mount should appear as symlink", fs.isSymlink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getExpectedDirPaths() {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListOnMountTargetDirs() throws IOException {
|
public void testListOnMountTargetDirs() throws IOException {
|
||||||
FileStatus[] dirPaths = fsView.listStatus(new Path("/data"));
|
FileStatus[] dirPaths = fsView.listStatus(new Path("/data"));
|
||||||
|
Loading…
Reference in New Issue
Block a user