diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index ebbc12d..a2a2529 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -1385,6 +1385,13 @@ private static void addDeprecatedKeys() { public static final long DEFAULT_TIMELINE_SERVICE_CLIENT_RETRY_INTERVAL_MS = 1000; + /** Timeline client policy for whether connections are fatal */ + public static final String TIMELINE_SERVICE_CLIENT_BEST_EFFORT = + TIMELINE_SERVICE_CLIENT_PREFIX + "best-effort"; + + public static final boolean + DEFAULT_TIMELINE_SERVICE_CLIENT_BEST_EFFORT = false; + /** Flag to enable recovery of timeline service */ public static final String TIMELINE_SERVICE_RECOVERY_ENABLED = TIMELINE_SERVICE_PREFIX + "recovery.enabled"; diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index e4f31f2..c0b4a2e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -126,6 +126,9 @@ @VisibleForTesting String timelineDTRenewer; protected boolean timelineServiceEnabled; + @Private + @VisibleForTesting + public boolean timelineServiceBestEffort; private static final String ROOT = "root"; @@ -165,6 +168,10 @@ protected void serviceInit(Configuration conf) throws Exception { timelineDTRenewer = getTimelineDelegationTokenRenewer(conf); timelineService = TimelineUtils.buildTimelineTokenService(conf); } + + timelineServiceBestEffort = conf.getBoolean( + YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, + YarnConfiguration.DEFAULT_TIMELINE_SERVICE_CLIENT_BEST_EFFORT); super.serviceInit(conf); } @@ -322,7 +329,15 @@ private void addTimelineDelegationToken( @VisibleForTesting org.apache.hadoop.security.token.Token getTimelineDelegationToken() throws IOException, YarnException { - return timelineClient.getDelegationToken(timelineDTRenewer); + try { + return timelineClient.getDelegationToken(timelineDTRenewer); + } catch (Exception e ) { + if (timelineServiceBestEffort) { + LOG.warn("Failed to get delegation token from the timeline server"); + return null; + } + throw e; + } } private static String getTimelineDelegationTokenRenewer(Configuration conf) diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java index 02f2882..5987c21 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java @@ -761,6 +761,49 @@ private void testAsyncAPIPollTimeoutHelper(Long valueForTimeout, } @Test + public void testBestEffortTimelineDelegationToken() + throws Exception { + Configuration conf = new YarnConfiguration(); + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf); + // crate a mock client + YarnClientImpl client = spy(new YarnClientImpl() { + @Override + protected void serviceInit(Configuration conf) throws Exception { + if (getConfig().getBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, + YarnConfiguration.DEFAULT_TIMELINE_SERVICE_ENABLED)) { + timelineServiceEnabled = true; + timelineClient = mock(TimelineClient.class); + when(timelineClient.getDelegationToken(any(String.class))) + .thenThrow(new IOException("Fake exception")); + timelineClient.init(getConfig()); + timelineService = TimelineUtils.buildTimelineTokenService(getConfig()); + timelineServiceBestEffort = getConfig().getBoolean( + YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, + YarnConfiguration.DEFAULT_TIMELINE_SERVICE_CLIENT_BEST_EFFORT); + } + this.setConfig(conf); + } + }); + client.init(conf); + try { + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, true); + client.serviceInit(conf); + client.getTimelineDelegationToken(); + } catch (Exception e) { + Assert.fail("Should not have thrown an exception"); + } + try { + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, false); + client.serviceInit(conf); + client.getTimelineDelegationToken(); + Assert.fail("Get delegation token should have thrown an exception"); + } catch (Exception e) { + // Success + } + } + + @Test public void testAutomaticTimelineDelegationTokenLoading() throws Exception { Configuration conf = new YarnConfiguration();