YARN-2770. Added functionality to renew/cancel TimeLineDelegationToken. Contributed by Zhijie Shen
(cherry picked from commit 1b4be91866
)
This commit is contained in:
parent
268af259b5
commit
a87f827ae4
|
@ -78,10 +78,14 @@ public class DelegationTokenAuthenticatedURL extends AuthenticatedURL {
|
||||||
org.apache.hadoop.security.token.Token<AbstractDelegationTokenIdentifier>
|
org.apache.hadoop.security.token.Token<AbstractDelegationTokenIdentifier>
|
||||||
delegationToken;
|
delegationToken;
|
||||||
|
|
||||||
org.apache.hadoop.security.token.Token<AbstractDelegationTokenIdentifier>
|
public org.apache.hadoop.security.token.Token<AbstractDelegationTokenIdentifier>
|
||||||
getDelegationToken() {
|
getDelegationToken() {
|
||||||
return delegationToken;
|
return delegationToken;
|
||||||
}
|
}
|
||||||
|
public void setDelegationToken(
|
||||||
|
org.apache.hadoop.security.token.Token<AbstractDelegationTokenIdentifier> delegationToken) {
|
||||||
|
this.delegationToken = delegationToken;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -396,6 +396,9 @@ Release 2.6.0 - UNRELEASED
|
||||||
YARN-2778. Moved node-lables' reports to the yarn nodes CLI from the admin
|
YARN-2778. Moved node-lables' reports to the yarn nodes CLI from the admin
|
||||||
CLI. (Wangda Tan via vinodkv)
|
CLI. (Wangda Tan via vinodkv)
|
||||||
|
|
||||||
|
YARN-2770. Added functionality to renew/cancel TimeLineDelegationToken.
|
||||||
|
(Zhijie Shen via jianhe)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.hadoop.io.DataOutputBuffer;
|
||||||
import org.apache.hadoop.io.Text;
|
import org.apache.hadoop.io.Text;
|
||||||
import org.apache.hadoop.ipc.RPC;
|
import org.apache.hadoop.ipc.RPC;
|
||||||
import org.apache.hadoop.security.Credentials;
|
import org.apache.hadoop.security.Credentials;
|
||||||
|
import org.apache.hadoop.security.HadoopKerberosName;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.token.TokenIdentifier;
|
import org.apache.hadoop.security.token.TokenIdentifier;
|
||||||
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
|
import org.apache.hadoop.yarn.api.ApplicationClientProtocol;
|
||||||
|
@ -319,8 +320,14 @@ public class YarnClientImpl extends YarnClient {
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
org.apache.hadoop.security.token.Token<TimelineDelegationTokenIdentifier>
|
org.apache.hadoop.security.token.Token<TimelineDelegationTokenIdentifier>
|
||||||
getTimelineDelegationToken() throws IOException, YarnException {
|
getTimelineDelegationToken() throws IOException, YarnException {
|
||||||
return timelineClient.getDelegationToken(
|
// Parse the RM daemon user if it exists in the config
|
||||||
UserGroupInformation.getCurrentUser().getUserName());
|
String rmPrincipal = getConfig().get(YarnConfiguration.RM_PRINCIPAL);
|
||||||
|
String renewer = null;
|
||||||
|
if (rmPrincipal != null && rmPrincipal.length() > 0) {
|
||||||
|
HadoopKerberosName renewerKrbName = new HadoopKerberosName(rmPrincipal);
|
||||||
|
renewer = renewerKrbName.getShortName();
|
||||||
|
}
|
||||||
|
return timelineClient.getDelegationToken(renewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
|
|
|
@ -102,4 +102,34 @@ public abstract class TimelineClient extends AbstractService {
|
||||||
public abstract Token<TimelineDelegationTokenIdentifier> getDelegationToken(
|
public abstract Token<TimelineDelegationTokenIdentifier> getDelegationToken(
|
||||||
String renewer) throws IOException, YarnException;
|
String renewer) throws IOException, YarnException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Renew a timeline delegation token.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param timelineDT
|
||||||
|
* the delegation token to renew
|
||||||
|
* @return the new expiration time
|
||||||
|
* @throws IOException
|
||||||
|
* @throws YarnException
|
||||||
|
*/
|
||||||
|
@Public
|
||||||
|
public abstract long renewDelegationToken(
|
||||||
|
Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
|
throws IOException, YarnException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Cancel a timeline delegation token.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param timelineDT
|
||||||
|
* the delegation token to cancel
|
||||||
|
* @throws IOException
|
||||||
|
* @throws YarnException
|
||||||
|
*/
|
||||||
|
@Public
|
||||||
|
public abstract void cancelDelegationToken(
|
||||||
|
Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
|
throws IOException, YarnException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,13 +68,13 @@ import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.sun.jersey.api.client.Client;
|
import com.sun.jersey.api.client.Client;
|
||||||
import com.sun.jersey.api.client.filter.ClientFilter;
|
|
||||||
import com.sun.jersey.api.client.ClientResponse;
|
|
||||||
import com.sun.jersey.api.client.ClientRequest;
|
|
||||||
import com.sun.jersey.api.client.ClientHandlerException;
|
import com.sun.jersey.api.client.ClientHandlerException;
|
||||||
|
import com.sun.jersey.api.client.ClientRequest;
|
||||||
|
import com.sun.jersey.api.client.ClientResponse;
|
||||||
import com.sun.jersey.api.client.WebResource;
|
import com.sun.jersey.api.client.WebResource;
|
||||||
import com.sun.jersey.api.client.config.ClientConfig;
|
import com.sun.jersey.api.client.config.ClientConfig;
|
||||||
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
||||||
|
import com.sun.jersey.api.client.filter.ClientFilter;
|
||||||
import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
|
import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
|
||||||
import com.sun.jersey.client.urlconnection.URLConnectionClientHandler;
|
import com.sun.jersey.client.urlconnection.URLConnectionClientHandler;
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
@Private
|
@Private
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class TimelineClientConnectionRetry {
|
static class TimelineClientConnectionRetry {
|
||||||
|
|
||||||
// maxRetries < 0 means keep trying
|
// maxRetries < 0 means keep trying
|
||||||
@Private
|
@Private
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -344,8 +345,97 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
@Override
|
@Override
|
||||||
public Token<TimelineDelegationTokenIdentifier> getDelegationToken(
|
public Token<TimelineDelegationTokenIdentifier> getDelegationToken(
|
||||||
final String renewer) throws IOException, YarnException {
|
final String renewer) throws IOException, YarnException {
|
||||||
|
boolean isProxyAccess =
|
||||||
|
UserGroupInformation.getCurrentUser().getAuthenticationMethod()
|
||||||
|
== UserGroupInformation.AuthenticationMethod.PROXY;
|
||||||
|
final String doAsUser = isProxyAccess ?
|
||||||
|
UserGroupInformation.getCurrentUser().getShortUserName() : null;
|
||||||
|
PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>> getDTAction =
|
||||||
|
new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token<TimelineDelegationTokenIdentifier> run()
|
||||||
|
throws Exception {
|
||||||
|
DelegationTokenAuthenticatedURL authUrl =
|
||||||
|
new DelegationTokenAuthenticatedURL(authenticator,
|
||||||
|
connConfigurator);
|
||||||
|
return (Token) authUrl.getDelegationToken(
|
||||||
|
resURI.toURL(), token, renewer, doAsUser);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (Token<TimelineDelegationTokenIdentifier>) operateDelegationToken(getDTAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public long renewDelegationToken(
|
||||||
|
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
|
throws IOException, YarnException {
|
||||||
|
boolean isProxyAccess =
|
||||||
|
UserGroupInformation.getCurrentUser().getAuthenticationMethod()
|
||||||
|
== UserGroupInformation.AuthenticationMethod.PROXY;
|
||||||
|
final String doAsUser = isProxyAccess ?
|
||||||
|
UserGroupInformation.getCurrentUser().getShortUserName() : null;
|
||||||
|
PrivilegedExceptionAction<Long> renewDTAction =
|
||||||
|
new PrivilegedExceptionAction<Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long run()
|
||||||
|
throws Exception {
|
||||||
|
// If the timeline DT to renew is different than cached, replace it.
|
||||||
|
// Token to set every time for retry, because when exception happens,
|
||||||
|
// DelegationTokenAuthenticatedURL will reset it to null;
|
||||||
|
if (!timelineDT.equals(token.getDelegationToken())) {
|
||||||
|
token.setDelegationToken((Token) timelineDT);
|
||||||
|
}
|
||||||
|
DelegationTokenAuthenticatedURL authUrl =
|
||||||
|
new DelegationTokenAuthenticatedURL(authenticator,
|
||||||
|
connConfigurator);
|
||||||
|
return authUrl
|
||||||
|
.renewDelegationToken(resURI.toURL(), token, doAsUser);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (Long) operateDelegationToken(renewDTAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void cancelDelegationToken(
|
||||||
|
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
|
throws IOException, YarnException {
|
||||||
|
boolean isProxyAccess =
|
||||||
|
UserGroupInformation.getCurrentUser().getAuthenticationMethod()
|
||||||
|
== UserGroupInformation.AuthenticationMethod.PROXY;
|
||||||
|
final String doAsUser = isProxyAccess ?
|
||||||
|
UserGroupInformation.getCurrentUser().getShortUserName() : null;
|
||||||
|
PrivilegedExceptionAction<Void> cancelDTAction =
|
||||||
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void run()
|
||||||
|
throws Exception {
|
||||||
|
// If the timeline DT to cancel is different than cached, replace it.
|
||||||
|
// Token to set every time for retry, because when exception happens,
|
||||||
|
// DelegationTokenAuthenticatedURL will reset it to null;
|
||||||
|
if (!timelineDT.equals(token.getDelegationToken())) {
|
||||||
|
token.setDelegationToken((Token) timelineDT);
|
||||||
|
}
|
||||||
|
DelegationTokenAuthenticatedURL authUrl =
|
||||||
|
new DelegationTokenAuthenticatedURL(authenticator,
|
||||||
|
connConfigurator);
|
||||||
|
authUrl.cancelDelegationToken(resURI.toURL(), token, doAsUser);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
operateDelegationToken(cancelDTAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object operateDelegationToken(
|
||||||
|
final PrivilegedExceptionAction<?> action)
|
||||||
|
throws IOException, YarnException {
|
||||||
// Set up the retry operation
|
// Set up the retry operation
|
||||||
TimelineClientRetryOp tokenRetryOp = new TimelineClientRetryOp() {
|
TimelineClientRetryOp tokenRetryOp = new TimelineClientRetryOp() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object run() throws IOException {
|
public Object run() throws IOException {
|
||||||
// Try pass the request, if fail, keep retrying
|
// Try pass the request, if fail, keep retrying
|
||||||
|
@ -355,25 +445,15 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
UserGroupInformation callerUGI = isProxyAccess ?
|
UserGroupInformation callerUGI = isProxyAccess ?
|
||||||
UserGroupInformation.getCurrentUser().getRealUser()
|
UserGroupInformation.getCurrentUser().getRealUser()
|
||||||
: UserGroupInformation.getCurrentUser();
|
: UserGroupInformation.getCurrentUser();
|
||||||
final String doAsUser = isProxyAccess ?
|
|
||||||
UserGroupInformation.getCurrentUser().getShortUserName() : null;
|
|
||||||
try {
|
try {
|
||||||
return callerUGI.doAs(
|
return callerUGI.doAs(action);
|
||||||
new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() {
|
|
||||||
@Override
|
|
||||||
public Token<TimelineDelegationTokenIdentifier> run() throws Exception {
|
|
||||||
DelegationTokenAuthenticatedURL authUrl =
|
|
||||||
new DelegationTokenAuthenticatedURL(authenticator, connConfigurator);
|
|
||||||
return (Token) authUrl.getDelegationToken(
|
|
||||||
resURI.toURL(), token, renewer, doAsUser);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (UndeclaredThrowableException e) {
|
} catch (UndeclaredThrowableException e) {
|
||||||
throw new IOException(e.getCause());
|
throw new IOException(e.getCause());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRetryOn(Exception e) {
|
public boolean shouldRetryOn(Exception e) {
|
||||||
// Only retry on connection exceptions
|
// Only retry on connection exceptions
|
||||||
|
@ -381,8 +461,7 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (Token<TimelineDelegationTokenIdentifier>)
|
return connectionRetry.retryOn(tokenRetryOp);
|
||||||
connectionRetry.retryOn(tokenRetryOp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
|
|
|
@ -18,11 +18,17 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.security.client;
|
package org.apache.hadoop.yarn.security.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Public;
|
import org.apache.hadoop.classification.InterfaceAudience.Public;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.io.Text;
|
import org.apache.hadoop.io.Text;
|
||||||
import org.apache.hadoop.security.token.Token;
|
import org.apache.hadoop.security.token.Token;
|
||||||
|
import org.apache.hadoop.security.token.TokenRenewer;
|
||||||
|
import org.apache.hadoop.yarn.client.api.TimelineClient;
|
||||||
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
|
|
||||||
@Public
|
@Public
|
||||||
@Unstable
|
@Unstable
|
||||||
|
@ -52,10 +58,50 @@ public class TimelineDelegationTokenIdentifier extends YARNDelegationTokenIdenti
|
||||||
}
|
}
|
||||||
|
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public static class Renewer extends Token.TrivialRenewer {
|
public static class Renewer extends TokenRenewer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Text getKind() {
|
public boolean handleKind(Text kind) {
|
||||||
return KIND_NAME;
|
return KIND_NAME.equals(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isManaged(Token<?> token) throws IOException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public long renew(Token<?> token, Configuration conf) throws IOException,
|
||||||
|
InterruptedException {
|
||||||
|
TimelineClient client = TimelineClient.createTimelineClient();
|
||||||
|
try {
|
||||||
|
client.init(conf);
|
||||||
|
client.start();
|
||||||
|
return client.renewDelegationToken(
|
||||||
|
(Token<TimelineDelegationTokenIdentifier>) token);
|
||||||
|
} catch (YarnException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
} finally {
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void cancel(Token<?> token, Configuration conf) throws IOException,
|
||||||
|
InterruptedException {
|
||||||
|
TimelineClient client = TimelineClient.createTimelineClient();
|
||||||
|
try {
|
||||||
|
client.init(conf);
|
||||||
|
client.start();
|
||||||
|
client.cancelDelegationToken(
|
||||||
|
(Token<TimelineDelegationTokenIdentifier>) token);
|
||||||
|
} catch (YarnException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
} finally {
|
||||||
|
client.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,19 @@ import static org.mockito.Mockito.when;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
|
|
||||||
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
||||||
|
import org.apache.hadoop.io.Text;
|
||||||
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.delegation.AbstractDelegationTokenSecretManager;
|
||||||
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineDomain;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineDomain;
|
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelinePutResponse;
|
||||||
import org.apache.hadoop.yarn.client.api.TimelineClient;
|
import org.apache.hadoop.yarn.client.api.TimelineClient;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.exceptions.YarnException;
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
|
import org.apache.hadoop.yarn.security.client.TimelineDelegationTokenIdentifier;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -197,7 +201,7 @@ public class TestTimelineClient {
|
||||||
try {
|
try {
|
||||||
// This call should fail because there is no timeline server
|
// This call should fail because there is no timeline server
|
||||||
client.putEntities(generateEntity());
|
client.putEntities(generateEntity());
|
||||||
Assert.fail("Exception expected!"
|
Assert.fail("Exception expected! "
|
||||||
+ "Timeline server should be off to run this test. ");
|
+ "Timeline server should be off to run this test. ");
|
||||||
} catch (RuntimeException ce) {
|
} catch (RuntimeException ce) {
|
||||||
Assert.assertTrue(
|
Assert.assertTrue(
|
||||||
|
@ -210,7 +214,7 @@ public class TestTimelineClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTokenRetry() throws Exception {
|
public void testDelegationTokenOperationsRetry() throws Exception {
|
||||||
int newMaxRetries = 5;
|
int newMaxRetries = 5;
|
||||||
long newIntervalMs = 500;
|
long newIntervalMs = 500;
|
||||||
YarnConfiguration conf = new YarnConfiguration();
|
YarnConfiguration conf = new YarnConfiguration();
|
||||||
|
@ -222,24 +226,67 @@ public class TestTimelineClient {
|
||||||
// use kerberos to bypass the issue in HADOOP-11215
|
// use kerberos to bypass the issue in HADOOP-11215
|
||||||
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
|
||||||
"kerberos");
|
"kerberos");
|
||||||
UserGroupInformation.setConfiguration(conf);
|
UserGroupInformation.setConfiguration(conf);
|
||||||
|
|
||||||
TimelineClientImpl client = createTimelineClient(conf);
|
TimelineClientImpl client = createTimelineClient(conf);
|
||||||
|
TestTimlineDelegationTokenSecretManager dtManager =
|
||||||
|
new TestTimlineDelegationTokenSecretManager();
|
||||||
try {
|
try {
|
||||||
// try getting a delegation token
|
dtManager.startThreads();
|
||||||
client.getDelegationToken(
|
Thread.sleep(3000);
|
||||||
UserGroupInformation.getCurrentUser().getShortUserName());
|
|
||||||
Assert.fail("Exception expected!"
|
try {
|
||||||
+ "Timeline server should be off to run this test. ");
|
// try getting a delegation token
|
||||||
} catch (RuntimeException ce) {
|
client.getDelegationToken(
|
||||||
Assert.assertTrue(
|
UserGroupInformation.getCurrentUser().getShortUserName());
|
||||||
"Handler exception for reason other than retry: " + ce.toString(), ce
|
assertFail();
|
||||||
.getMessage().contains("Connection retries limit exceeded"));
|
} catch (RuntimeException ce) {
|
||||||
// we would expect this exception here, check if the client has retried
|
assertException(client, ce);
|
||||||
Assert.assertTrue("Retry filter didn't perform any retries! ",
|
}
|
||||||
client.connectionRetry.retried);
|
|
||||||
|
try {
|
||||||
|
// try renew a delegation token
|
||||||
|
TimelineDelegationTokenIdentifier timelineDT =
|
||||||
|
new TimelineDelegationTokenIdentifier(
|
||||||
|
new Text("tester"), new Text("tester"), new Text("tester"));
|
||||||
|
client.renewDelegationToken(
|
||||||
|
new Token<TimelineDelegationTokenIdentifier>(timelineDT, dtManager));
|
||||||
|
assertFail();
|
||||||
|
} catch (RuntimeException ce) {
|
||||||
|
assertException(client, ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// try cancel a delegation token
|
||||||
|
TimelineDelegationTokenIdentifier timelineDT =
|
||||||
|
new TimelineDelegationTokenIdentifier(
|
||||||
|
new Text("tester"), new Text("tester"), new Text("tester"));
|
||||||
|
client.cancelDelegationToken(
|
||||||
|
new Token<TimelineDelegationTokenIdentifier>(timelineDT, dtManager));
|
||||||
|
assertFail();
|
||||||
|
} catch (RuntimeException ce) {
|
||||||
|
assertException(client, ce);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
client.stop();
|
||||||
|
dtManager.stopThreads();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void assertFail() {
|
||||||
|
Assert.fail("Exception expected! "
|
||||||
|
+ "Timeline server should be off to run this test.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertException(TimelineClientImpl client, RuntimeException ce) {
|
||||||
|
Assert.assertTrue(
|
||||||
|
"Handler exception for reason other than retry: " + ce.toString(), ce
|
||||||
|
.getMessage().contains("Connection retries limit exceeded"));
|
||||||
|
// we would expect this exception here, check if the client has retried
|
||||||
|
Assert.assertTrue("Retry filter didn't perform any retries! ",
|
||||||
|
client.connectionRetry.retried);
|
||||||
|
}
|
||||||
|
|
||||||
private static ClientResponse mockEntityClientResponse(
|
private static ClientResponse mockEntityClientResponse(
|
||||||
TimelineClientImpl client, ClientResponse.Status status,
|
TimelineClientImpl client, ClientResponse.Status status,
|
||||||
boolean hasError, boolean hasRuntimeError) {
|
boolean hasError, boolean hasRuntimeError) {
|
||||||
|
@ -324,4 +371,17 @@ public class TestTimelineClient {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TestTimlineDelegationTokenSecretManager extends
|
||||||
|
AbstractDelegationTokenSecretManager<TimelineDelegationTokenIdentifier> {
|
||||||
|
|
||||||
|
public TestTimlineDelegationTokenSecretManager() {
|
||||||
|
super(100000, 100000, 100000, 100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimelineDelegationTokenIdentifier createIdentifier() {
|
||||||
|
return new TimelineDelegationTokenIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ public class TestTimelineAuthenticationFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetDelegationToken() throws Exception {
|
public void testDelegationTokenOperations() throws Exception {
|
||||||
KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() {
|
KerberosTestUtils.doAs(HTTP_USER + "/localhost", new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
|
@ -227,6 +227,23 @@ public class TestTimelineAuthenticationFilter {
|
||||||
Assert.assertNotNull(tDT);
|
Assert.assertNotNull(tDT);
|
||||||
Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
||||||
|
|
||||||
|
// Renew token
|
||||||
|
long renewTime1 = client.renewDelegationToken(token);
|
||||||
|
Thread.sleep(100);
|
||||||
|
long renewTime2 = client.renewDelegationToken(token);
|
||||||
|
Assert.assertTrue(renewTime1 < renewTime2);
|
||||||
|
|
||||||
|
// Cancel token
|
||||||
|
client.cancelDelegationToken(token);
|
||||||
|
// Renew should not be successful because the token is canceled
|
||||||
|
try {
|
||||||
|
client.renewDelegationToken(token);
|
||||||
|
Assert.fail();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Assert.assertTrue(e.getMessage().contains(
|
||||||
|
"Renewal request for unknown token"));
|
||||||
|
}
|
||||||
|
|
||||||
// Let HTTP user to get the delegation token for FOO user
|
// Let HTTP user to get the delegation token for FOO user
|
||||||
UserGroupInformation fooUgi = UserGroupInformation.createProxyUser(
|
UserGroupInformation fooUgi = UserGroupInformation.createProxyUser(
|
||||||
FOO_USER, UserGroupInformation.getCurrentUser());
|
FOO_USER, UserGroupInformation.getCurrentUser());
|
||||||
|
@ -245,6 +262,49 @@ public class TestTimelineAuthenticationFilter {
|
||||||
Assert.assertEquals(new Text(FOO_USER), tDT.getOwner());
|
Assert.assertEquals(new Text(FOO_USER), tDT.getOwner());
|
||||||
Assert.assertEquals(new Text(HTTP_USER), tDT.getRealUser());
|
Assert.assertEquals(new Text(HTTP_USER), tDT.getRealUser());
|
||||||
|
|
||||||
|
// Renew token
|
||||||
|
final Token<TimelineDelegationTokenIdentifier> tokenToRenew = token;
|
||||||
|
renewTime1 = fooUgi.doAs(
|
||||||
|
new PrivilegedExceptionAction<Long>() {
|
||||||
|
@Override
|
||||||
|
public Long run() throws Exception {
|
||||||
|
return client.renewDelegationToken(tokenToRenew);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
renewTime2 = fooUgi.doAs(
|
||||||
|
new PrivilegedExceptionAction<Long>() {
|
||||||
|
@Override
|
||||||
|
public Long run() throws Exception {
|
||||||
|
return client.renewDelegationToken(tokenToRenew);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Assert.assertTrue(renewTime1 < renewTime2);
|
||||||
|
|
||||||
|
// Cancel token
|
||||||
|
fooUgi.doAs(
|
||||||
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void run() throws Exception {
|
||||||
|
client.cancelDelegationToken(tokenToRenew);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Renew should not be successful because the token is canceled
|
||||||
|
try {
|
||||||
|
fooUgi.doAs(
|
||||||
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void run() throws Exception {
|
||||||
|
client.renewDelegationToken(tokenToRenew);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Assert.fail();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Assert.assertTrue(e.getMessage().contains(
|
||||||
|
"Renewal request for unknown token"));
|
||||||
|
}
|
||||||
|
|
||||||
// Let HTTP user to get the delegation token for BAR user
|
// Let HTTP user to get the delegation token for BAR user
|
||||||
UserGroupInformation barUgi = UserGroupInformation.createProxyUser(
|
UserGroupInformation barUgi = UserGroupInformation.createProxyUser(
|
||||||
BAR_USER, UserGroupInformation.getCurrentUser());
|
BAR_USER, UserGroupInformation.getCurrentUser());
|
||||||
|
|
Loading…
Reference in New Issue