|
@@ -19,6 +19,7 @@
|
|
|
package org.apache.hadoop.yarn.server.router.clientrm;
|
|
|
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
+import static org.mockito.Mockito.when;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
@@ -32,6 +33,7 @@ import java.util.stream.Collectors;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collection;
|
|
|
|
|
|
+import org.apache.hadoop.io.Text;
|
|
|
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
|
|
|
import org.apache.hadoop.test.LambdaTestUtils;
|
|
|
import org.apache.hadoop.util.Time;
|
|
@@ -100,6 +102,12 @@ import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest;
|
|
|
import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateResponse;
|
|
|
import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest;
|
|
|
import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.GetDelegationTokenRequest;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.GetDelegationTokenResponse;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.CancelDelegationTokenRequest;
|
|
|
+import org.apache.hadoop.yarn.api.protocolrecords.CancelDelegationTokenResponse;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
|
|
import org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext;
|
|
@@ -123,10 +131,13 @@ import org.apache.hadoop.yarn.api.records.ReservationRequest;
|
|
|
import org.apache.hadoop.yarn.api.records.ReservationDefinition;
|
|
|
import org.apache.hadoop.yarn.api.records.ReservationRequestInterpreter;
|
|
|
import org.apache.hadoop.yarn.api.records.ReservationRequests;
|
|
|
+import org.apache.hadoop.yarn.api.records.Token;
|
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
|
|
+import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
|
|
|
import org.apache.hadoop.yarn.server.federation.policies.manager.UniformBroadcastPolicyManager;
|
|
|
import org.apache.hadoop.yarn.server.federation.store.impl.MemoryFederationStateStore;
|
|
|
+import org.apache.hadoop.yarn.server.federation.store.records.RouterRMDTSecretManagerState;
|
|
|
import org.apache.hadoop.yarn.server.federation.store.records.SubClusterId;
|
|
|
import org.apache.hadoop.yarn.server.federation.store.records.SubClusterInfo;
|
|
|
import org.apache.hadoop.yarn.server.federation.utils.FederationStateStoreFacade;
|
|
@@ -138,6 +149,9 @@ import org.apache.hadoop.yarn.server.resourcemanager.reservation.ReservationSyst
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState;
|
|
|
+import org.apache.hadoop.yarn.server.router.security.RouterDelegationTokenSecretManager;
|
|
|
+import org.apache.hadoop.yarn.util.ConverterUtils;
|
|
|
+import org.apache.hadoop.yarn.util.Records;
|
|
|
import org.apache.hadoop.yarn.util.Times;
|
|
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
|
|
import org.junit.Assert;
|
|
@@ -170,7 +184,7 @@ public class TestFederationClientInterceptor extends BaseRouterClientRMTest {
|
|
|
private final static long DEFAULT_DURATION = 10 * 60 * 1000;
|
|
|
|
|
|
@Override
|
|
|
- public void setUp() {
|
|
|
+ public void setUp() throws IOException {
|
|
|
super.setUpConfig();
|
|
|
interceptor = new TestableFederationClientInterceptor();
|
|
|
|
|
@@ -181,6 +195,11 @@ public class TestFederationClientInterceptor extends BaseRouterClientRMTest {
|
|
|
|
|
|
interceptor.setConf(this.getConf());
|
|
|
interceptor.init(user);
|
|
|
+ RouterDelegationTokenSecretManager tokenSecretManager =
|
|
|
+ interceptor.createRouterRMDelegationTokenSecretManager(this.getConf());
|
|
|
+
|
|
|
+ tokenSecretManager.startThreads();
|
|
|
+ interceptor.setTokenSecretManager(tokenSecretManager);
|
|
|
|
|
|
subClusters = new ArrayList<>();
|
|
|
|
|
@@ -230,6 +249,7 @@ public class TestFederationClientInterceptor extends BaseRouterClientRMTest {
|
|
|
conf.setInt("yarn.scheduler.maximum-allocation-mb", 100 * 1024);
|
|
|
conf.setInt("yarn.scheduler.maximum-allocation-vcores", 100);
|
|
|
|
|
|
+ conf.setBoolean("hadoop.security.authentication", true);
|
|
|
return conf;
|
|
|
}
|
|
|
|
|
@@ -1550,4 +1570,138 @@ public class TestFederationClientInterceptor extends BaseRouterClientRMTest {
|
|
|
int minThreads2 = interceptor.getNumMaxThreads(this.getConf());
|
|
|
Assert.assertEquals(8, minThreads2);
|
|
|
}
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testGetDelegationToken() throws IOException, YarnException {
|
|
|
+
|
|
|
+ // We design such a unit test to check
|
|
|
+ // that the execution of the GetDelegationToken method is as expected.
|
|
|
+ //
|
|
|
+ // 1. Apply for a DelegationToken for renewer1,
|
|
|
+ // the Router returns the DelegationToken of the user, and the KIND of the token is
|
|
|
+ // RM_DELEGATION_TOKEN
|
|
|
+ //
|
|
|
+ // 2. We maintain the compatibility with RMDelegationTokenIdentifier,
|
|
|
+ // we can serialize the token into RMDelegationTokenIdentifier.
|
|
|
+ //
|
|
|
+ // 3. We can get the issueDate, and compare the data in the StateStore,
|
|
|
+ // the data should be consistent.
|
|
|
+
|
|
|
+ // Step1. We apply for DelegationToken for renewer1
|
|
|
+ // Both response & delegationToken cannot be empty
|
|
|
+ GetDelegationTokenRequest request = mock(GetDelegationTokenRequest.class);
|
|
|
+ when(request.getRenewer()).thenReturn("renewer1");
|
|
|
+ GetDelegationTokenResponse response = interceptor.getDelegationToken(request);
|
|
|
+ Assert.assertNotNull(response);
|
|
|
+ Token delegationToken = response.getRMDelegationToken();
|
|
|
+ Assert.assertNotNull(delegationToken);
|
|
|
+ Assert.assertEquals("RM_DELEGATION_TOKEN", delegationToken.getKind());
|
|
|
+
|
|
|
+ // Step2. Serialize the returned Token as RMDelegationTokenIdentifier.
|
|
|
+ org.apache.hadoop.security.token.Token<RMDelegationTokenIdentifier> token =
|
|
|
+ ConverterUtils.convertFromYarn(delegationToken, (Text) null);
|
|
|
+ RMDelegationTokenIdentifier rMDelegationTokenIdentifier = token.decodeIdentifier();
|
|
|
+ Assert.assertNotNull(rMDelegationTokenIdentifier);
|
|
|
+
|
|
|
+ // Step3. Verify the returned data of the token.
|
|
|
+ String renewer = rMDelegationTokenIdentifier.getRenewer().toString();
|
|
|
+ long issueDate = rMDelegationTokenIdentifier.getIssueDate();
|
|
|
+ long maxDate = rMDelegationTokenIdentifier.getMaxDate();
|
|
|
+ Assert.assertEquals("renewer1", renewer);
|
|
|
+
|
|
|
+ long tokenMaxLifetime = this.getConf().getLong(
|
|
|
+ YarnConfiguration.RM_DELEGATION_TOKEN_MAX_LIFETIME_KEY,
|
|
|
+ YarnConfiguration.RM_DELEGATION_TOKEN_MAX_LIFETIME_DEFAULT);
|
|
|
+ Assert.assertEquals(issueDate + tokenMaxLifetime, maxDate);
|
|
|
+
|
|
|
+ RouterRMDTSecretManagerState managerState = stateStore.getRouterRMSecretManagerState();
|
|
|
+ Assert.assertNotNull(managerState);
|
|
|
+
|
|
|
+ Map<RMDelegationTokenIdentifier, Long> delegationTokenState = managerState.getTokenState();
|
|
|
+ Assert.assertNotNull(delegationTokenState);
|
|
|
+ Assert.assertTrue(delegationTokenState.containsKey(rMDelegationTokenIdentifier));
|
|
|
+
|
|
|
+ long tokenRenewInterval = this.getConf().getLong(
|
|
|
+ YarnConfiguration.RM_DELEGATION_TOKEN_RENEW_INTERVAL_KEY,
|
|
|
+ YarnConfiguration.RM_DELEGATION_TOKEN_RENEW_INTERVAL_DEFAULT);
|
|
|
+ long renewDate = delegationTokenState.get(rMDelegationTokenIdentifier);
|
|
|
+ Assert.assertEquals(issueDate + tokenRenewInterval, renewDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testRenewDelegationToken() throws IOException, YarnException {
|
|
|
+
|
|
|
+ // We design such a unit test to check
|
|
|
+ // that the execution of the GetDelegationToken method is as expected
|
|
|
+ // 1. Call GetDelegationToken to apply for delegationToken.
|
|
|
+ // 2. Call renewDelegationToken to refresh delegationToken.
|
|
|
+ // By looking at the code of AbstractDelegationTokenSecretManager#renewToken,
|
|
|
+ // we know that renewTime is calculated as Math.min(id.getMaxDate(), now + tokenRenewInterval)
|
|
|
+ // so renewTime will be less than or equal to maxDate.
|
|
|
+ // 3. We will compare whether the expirationTime returned to the
|
|
|
+ // client is consistent with the renewDate in the stateStore.
|
|
|
+
|
|
|
+ // Step1. Call GetDelegationToken to apply for delegationToken.
|
|
|
+ GetDelegationTokenRequest request = mock(GetDelegationTokenRequest.class);
|
|
|
+ when(request.getRenewer()).thenReturn("renewer2");
|
|
|
+ GetDelegationTokenResponse response = interceptor.getDelegationToken(request);
|
|
|
+ Assert.assertNotNull(response);
|
|
|
+ Token delegationToken = response.getRMDelegationToken();
|
|
|
+
|
|
|
+ org.apache.hadoop.security.token.Token<RMDelegationTokenIdentifier> token =
|
|
|
+ ConverterUtils.convertFromYarn(delegationToken, (Text) null);
|
|
|
+ RMDelegationTokenIdentifier rMDelegationTokenIdentifier = token.decodeIdentifier();
|
|
|
+ String renewer = rMDelegationTokenIdentifier.getRenewer().toString();
|
|
|
+ long maxDate = rMDelegationTokenIdentifier.getMaxDate();
|
|
|
+ Assert.assertEquals("renewer2", renewer);
|
|
|
+
|
|
|
+ // Step2. Call renewDelegationToken to refresh delegationToken.
|
|
|
+ RenewDelegationTokenRequest renewRequest = Records.newRecord(RenewDelegationTokenRequest.class);
|
|
|
+ renewRequest.setDelegationToken(delegationToken);
|
|
|
+ RenewDelegationTokenResponse renewResponse = interceptor.renewDelegationToken(renewRequest);
|
|
|
+ Assert.assertNotNull(renewResponse);
|
|
|
+
|
|
|
+ long expDate = renewResponse.getNextExpirationTime();
|
|
|
+ Assert.assertTrue(expDate <= maxDate);
|
|
|
+
|
|
|
+ // Step3. Compare whether the expirationTime returned to
|
|
|
+ // the client is consistent with the renewDate in the stateStore
|
|
|
+ RouterRMDTSecretManagerState managerState = stateStore.getRouterRMSecretManagerState();
|
|
|
+ Map<RMDelegationTokenIdentifier, Long> delegationTokenState = managerState.getTokenState();
|
|
|
+ Assert.assertNotNull(delegationTokenState);
|
|
|
+ Assert.assertTrue(delegationTokenState.containsKey(rMDelegationTokenIdentifier));
|
|
|
+ long renewDate = delegationTokenState.get(rMDelegationTokenIdentifier);
|
|
|
+ Assert.assertEquals(expDate, renewDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testCancelDelegationToken() throws IOException, YarnException {
|
|
|
+
|
|
|
+ // We design such a unit test to check
|
|
|
+ // that the execution of the CancelDelegationToken method is as expected
|
|
|
+ // 1. Call GetDelegationToken to apply for delegationToken.
|
|
|
+ // 2. Call CancelDelegationToken to cancel delegationToken.
|
|
|
+ // 3. Query the data in the StateStore and confirm that the Delegation has been deleted.
|
|
|
+
|
|
|
+ // Step1. Call GetDelegationToken to apply for delegationToken.
|
|
|
+ GetDelegationTokenRequest request = mock(GetDelegationTokenRequest.class);
|
|
|
+ when(request.getRenewer()).thenReturn("renewer3");
|
|
|
+ GetDelegationTokenResponse response = interceptor.getDelegationToken(request);
|
|
|
+ Assert.assertNotNull(response);
|
|
|
+ Token delegationToken = response.getRMDelegationToken();
|
|
|
+
|
|
|
+ // Step2. Call CancelDelegationToken to cancel delegationToken.
|
|
|
+ CancelDelegationTokenRequest cancelTokenRequest =
|
|
|
+ CancelDelegationTokenRequest.newInstance(delegationToken);
|
|
|
+ CancelDelegationTokenResponse cancelTokenResponse =
|
|
|
+ interceptor.cancelDelegationToken(cancelTokenRequest);
|
|
|
+ Assert.assertNotNull(cancelTokenResponse);
|
|
|
+
|
|
|
+ // Step3. Query the data in the StateStore and confirm that the Delegation has been deleted.
|
|
|
+ // At this point, the size of delegationTokenState should be 0.
|
|
|
+ RouterRMDTSecretManagerState managerState = stateStore.getRouterRMSecretManagerState();
|
|
|
+ Map<RMDelegationTokenIdentifier, Long> delegationTokenState = managerState.getTokenState();
|
|
|
+ Assert.assertNotNull(delegationTokenState);
|
|
|
+ Assert.assertEquals(0, delegationTokenState.size());
|
|
|
+ }
|
|
|
}
|