From 9361fc8f704dfcb3b5ecdf7b0d68e59f31ba31a7 Mon Sep 17 00:00:00 2001 From: Jason Lowe Date: Fri, 6 Feb 2015 20:55:00 +0000 Subject: [PATCH] YARN-3144. Configuration for making delegation token failures to timeline server not-fatal. Contributed by Jonathan Eagles (cherry picked from commit 6f10434a5ad965d50352602ce31a9fce353cb90c) --- hadoop-yarn-project/CHANGES.txt | 3 + .../hadoop/yarn/conf/YarnConfiguration.java | 7 +++ .../yarn/client/api/impl/YarnClientImpl.java | 22 +++++++- .../yarn/client/api/impl/TestYarnClient.java | 56 +++++++++++++++---- .../src/main/resources/yarn-default.xml | 6 ++ 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 3457c3887aa..70df5b3d719 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -218,6 +218,9 @@ Release 2.7.0 - UNRELEASED ApplicationHistoryClientService are uniform when application-attempt is not found. (zjshen via acmurthy) + YARN-3144. Configuration for making delegation token failures to timeline + server not-fatal (Jonathan Eagles via jlowe) + OPTIMIZATIONS BUG FIXES diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index ebbc12d439a..a2a25298354 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -1385,6 +1385,13 @@ public class YarnConfiguration extends Configuration { 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 a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index 975c26796e2..91fbd007193 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -129,6 +129,7 @@ public class YarnClientImpl extends YarnClient { @VisibleForTesting String timelineDTRenewer; protected boolean timelineServiceEnabled; + protected boolean timelineServiceBestEffort; private static final String ROOT = "root"; @@ -163,14 +164,22 @@ public class YarnClientImpl extends YarnClient { if (conf.getBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, YarnConfiguration.DEFAULT_TIMELINE_SERVICE_ENABLED)) { timelineServiceEnabled = true; - timelineClient = TimelineClient.createTimelineClient(); + timelineClient = createTimelineClient(); timelineClient.init(conf); 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); } + TimelineClient createTimelineClient() throws IOException, YarnException { + return TimelineClient.createTimelineClient(); + } + @Override protected void serviceStart() throws Exception { try { @@ -325,7 +334,16 @@ public class YarnClientImpl extends YarnClient { @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: " + + e.getMessage()); + return null; + } + throw e; + } } private static String getTimelineDelegationTokenRenewer(Configuration conf) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java index eb8ca484830..73e06afd9b0 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java @@ -853,6 +853,42 @@ public class TestYarnClient { } } + @Test + public void testBestEffortTimelineDelegationToken() + throws Exception { + Configuration conf = new YarnConfiguration(); + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true); + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf); + + YarnClientImpl client = spy(new YarnClientImpl() { + + @Override + TimelineClient createTimelineClient() throws IOException, YarnException { + timelineClient = mock(TimelineClient.class); + when(timelineClient.getDelegationToken(any(String.class))) + .thenThrow(new IOException("Best effort test exception")); + return timelineClient; + } + }); + + 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 { @@ -864,22 +900,18 @@ public class TestYarnClient { final Token dToken = new Token( timelineDT.getBytes(), new byte[0], timelineDT.getKind(), new Text()); - // crate a mock client + // create 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))) - .thenReturn(dToken); - timelineClient.init(getConfig()); - timelineService = TimelineUtils.buildTimelineTokenService(getConfig()); - } - this.setConfig(conf); + TimelineClient createTimelineClient() throws IOException, YarnException { + timelineClient = mock(TimelineClient.class); + when(timelineClient.getDelegationToken(any(String.class))) + .thenReturn(dToken); + return timelineClient; } + @Override protected void serviceStart() throws Exception { rmClient = mock(ApplicationClientProtocol.class); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml index f1e6e674c66..f662ee1100d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/yarn-default.xml @@ -1369,6 +1369,12 @@ 30 + + Client policy for whether timeline operations are non-fatal + yarn.timeline-service.client.best-effort + false + + Default retry time interval for timeline servive client.