From 4170c99147b0cb6d561ff626cea140e0a061b314 Mon Sep 17 00:00:00 2001 From: Tsuyoshi Ozawa Date: Wed, 25 Mar 2015 00:56:26 +0900 Subject: [PATCH] MAPREDUCE-6285. ClientServiceDelegate should not retry upon AuthenticationException. Contributed by Jonathan Eagles. --- hadoop-mapreduce-project/CHANGES.txt | 3 ++ .../hadoop/mapred/ClientServiceDelegate.java | 6 +++ .../mapred/TestClientServiceDelegate.java | 44 +++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/hadoop-mapreduce-project/CHANGES.txt b/hadoop-mapreduce-project/CHANGES.txt index b8a2a1cdd2..2b16c30903 100644 --- a/hadoop-mapreduce-project/CHANGES.txt +++ b/hadoop-mapreduce-project/CHANGES.txt @@ -496,6 +496,9 @@ Release 2.7.0 - UNRELEASED MAPREDUCE-6275. Race condition in FileOutputCommitter v2 for user-specified task output subdirs (Gera Shegalov and Siqi Li via jlowe) + MAPREDUCE-6285. ClientServiceDelegate should not retry upon + AuthenticationException. (Jonathan Eagles via ozawa) + Release 2.6.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java index 686fa0c70c..8517c19737 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ClientServiceDelegate.java @@ -64,6 +64,7 @@ import org.apache.hadoop.mapreduce.v2.util.MRApps; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.security.token.Token; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; @@ -328,6 +329,11 @@ private synchronized Object invoke(String method, Class argClass, // Force reconnection by setting the proxy to null. realProxy = null; // HS/AMS shut down + + if (e.getCause() instanceof AuthorizationException) { + throw new IOException(e.getTargetException()); + } + // if it's AM shut down, do not decrement maxClientRetry as we wait for // AM to be restarted. if (!usingAMProxy.get()) { diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientServiceDelegate.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientServiceDelegate.java index 7d6b2f3081..b85f18db4e 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientServiceDelegate.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientServiceDelegate.java @@ -48,6 +48,7 @@ import org.apache.hadoop.mapreduce.v2.api.records.JobReport; import org.apache.hadoop.mapreduce.v2.api.records.JobState; import org.apache.hadoop.mapreduce.v2.util.MRBuilderUtils; +import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; @@ -182,6 +183,49 @@ MRClientProtocol instantiateAMProxy( verify(amProxy, times(5)).getJobReport(any(GetJobReportRequest.class)); } + @Test + public void testNoRetryOnAMAuthorizationException() throws Exception { + if (!isAMReachableFromClient) { + return; + } + + ResourceMgrDelegate rm = mock(ResourceMgrDelegate.class); + when(rm.getApplicationReport(TypeConverter.toYarn(oldJobId).getAppId())) + .thenReturn(getRunningApplicationReport("am1", 78)); + + // throw authorization exception on first invocation + final MRClientProtocol amProxy = mock(MRClientProtocol.class); + when(amProxy.getJobReport(any(GetJobReportRequest.class))) + .thenThrow(new AuthorizationException("Denied")); + Configuration conf = new YarnConfiguration(); + conf.set(MRConfig.FRAMEWORK_NAME, MRConfig.YARN_FRAMEWORK_NAME); + conf.setBoolean(MRJobConfig.JOB_AM_ACCESS_DISABLED, + !isAMReachableFromClient); + ClientServiceDelegate clientServiceDelegate = + new ClientServiceDelegate(conf, rm, oldJobId, null) { + @Override + MRClientProtocol instantiateAMProxy( + final InetSocketAddress serviceAddr) throws IOException { + super.instantiateAMProxy(serviceAddr); + return amProxy; + } + }; + + try { + clientServiceDelegate.getJobStatus(oldJobId); + Assert.fail("Exception should be thrown upon AuthorizationException"); + } catch (IOException e) { + Assert.assertEquals(AuthorizationException.class.getName() + ": Denied", + e.getMessage()); + } + + // assert maxClientRetry is not decremented. + Assert.assertEquals(conf.getInt(MRJobConfig.MR_CLIENT_MAX_RETRIES, + MRJobConfig.DEFAULT_MR_CLIENT_MAX_RETRIES), clientServiceDelegate + .getMaxClientRetry()); + verify(amProxy, times(1)).getJobReport(any(GetJobReportRequest.class)); + } + @Test public void testHistoryServerNotConfigured() throws Exception { //RM doesn't have app report and job History Server is not configured