diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/DelegationTokenRenewer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/DelegationTokenRenewer.java index 4177ee2..ab16864 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/DelegationTokenRenewer.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/security/DelegationTokenRenewer.java @@ -443,11 +443,14 @@ private void handleAppSubmitEvent(AbstractDelegationTokenRenewerAppEvent evt) Collections.synchronizedSet(new HashSet())); Set tokenList = new HashSet(); boolean hasHdfsToken = false; + Credentials submittedSystemCred = new Credentials(); for (Token token : tokens) { if (token.isManaged()) { if (token.getKind().equals(HDFS_DELEGATION_KIND)) { LOG.info(applicationId + " found existing hdfs token " + token); hasHdfsToken = true; + // HDFS uses service as alias of the token + submittedSystemCred.addToken(token.getService(), token); } if (skipTokenRenewal(token)) { continue; @@ -479,6 +482,13 @@ private void handleAppSubmitEvent(AbstractDelegationTokenRenewerAppEvent evt) } } + if (submittedSystemCred.getAllTokens().size() > 0) { + DataOutputBuffer dob = new DataOutputBuffer(); + submittedSystemCred.writeTokenStorageToStream(dob); + rmContext.getSystemCredentialsForApps().put(applicationId, + ByteBuffer.wrap(dob.getData(), 0, dob.getLength())); + } + if (!tokenList.isEmpty()) { // Renewing token and adding it to timer calls are separated purposefully // If user provides incorrect token then it should not be added for diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestDelegationTokenRenewer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestDelegationTokenRenewer.java index 74fe534..5390d81 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestDelegationTokenRenewer.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/security/TestDelegationTokenRenewer.java @@ -1163,6 +1163,41 @@ public void testAppSubmissionWithPreviousToken() throws Exception{ Assert.assertFalse(Renewer.cancelled); } + // submit an app, the hdfs delegation token should be added to systemCredentials. + @Test (timeout = 30000) + public void testHDFSDelegationTokenBeAddedToSystemCredentials() throws Exception{ + MockRM rm = new TestSecurityMockRM(conf, null); + rm.start(); + + // create Token: + Text userText = new Text("user"); + DelegationTokenIdentifier dtId = + new DelegationTokenIdentifier(userText, new Text("renewer"), + userText); + final Token token = + new Token(dtId.getBytes(), + "password".getBytes(), dtId.getKind(), new Text("service")); + + Credentials credentials = new Credentials(); + credentials.addToken(userText, token); + + // submit app1 with a token, set cancelTokenWhenComplete to false; + Resource resource = Records.newRecord(Resource.class); + resource.setMemory(200); + RMApp app = rm.submitApp(resource, "name", "user", null, false, null, 2, + credentials, null, true, false, false, null, 0, null, false, null); + + ByteBuffer tokenBuffer = rm.getRMContext() + .getSystemCredentialsForApps().get(app.getApplicationId()); + Assert.assertNotNull(tokenBuffer); + Credentials appCredentials = new Credentials(); + DataInputByteBuffer buf = new DataInputByteBuffer(); + tokenBuffer.rewind(); + buf.reset(tokenBuffer); + appCredentials.readTokenStorageStream(buf); + Assert.assertTrue(appCredentials.getAllTokens().contains(token)); + } + // Test FileSystem memory leak in obtainSystemTokensForUser. @Test public void testFSLeakInObtainSystemTokensForUser() throws Exception{