Prechádzať zdrojové kódy

YARN-3393. Getting application(s) goes wrong when app finishes before
starting the attempt. Contributed by Zhijie Shen

(cherry picked from commit 9fae455e26e0230107e1c6db58a49a5b6b296cf4)
(cherry picked from commit cbdcdfad6de81e17fb586bc2a53b37da43defd79)
(cherry picked from commit 61aafdcfa589cbae8363976c745ea528b03f152d)

Xuan 10 rokov pred
rodič
commit
914cc8f4a4

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -117,6 +117,9 @@ Release 2.6.1 - UNRELEASED
     YARN-3369. Missing NullPointer check in AppSchedulingInfo causes RM to die.
     (Brahma Reddy Battula via wangda)
 
+    YARN-3393. Getting application(s) goes wrong when app finishes before
+    starting the attempt. (Zhijie Shen via xgong)
+
 Release 2.6.0 - 2014-11-18
 
   INCOMPATIBLE CHANGES

+ 8 - 6
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryManagerOnTimelineStore.java

@@ -498,17 +498,19 @@ public class ApplicationHistoryManagerOnTimelineStore extends AbstractService
       if (app.appReport.getCurrentApplicationAttemptId() != null) {
         ApplicationAttemptReport appAttempt =
             getApplicationAttempt(app.appReport.getCurrentApplicationAttemptId());
-        if (appAttempt != null) {
-          app.appReport.setHost(appAttempt.getHost());
-          app.appReport.setRpcPort(appAttempt.getRpcPort());
-          app.appReport.setTrackingUrl(appAttempt.getTrackingUrl());
-          app.appReport.setOriginalTrackingUrl(appAttempt.getOriginalTrackingUrl());
-        }
+        app.appReport.setHost(appAttempt.getHost());
+        app.appReport.setRpcPort(appAttempt.getRpcPort());
+        app.appReport.setTrackingUrl(appAttempt.getTrackingUrl());
+        app.appReport.setOriginalTrackingUrl(appAttempt.getOriginalTrackingUrl());
       }
     } catch (AuthorizationException e) {
       // AuthorizationException is thrown because the user doesn't have access
       app.appReport.setDiagnostics(null);
       app.appReport.setCurrentApplicationAttemptId(null);
+    } catch (ApplicationAttemptNotFoundException e) {
+      // It's possible that the app is finished before the first attempt is created.
+      app.appReport.setDiagnostics(null);
+      app.appReport.setCurrentApplicationAttemptId(null);
     }
     if (app.appReport.getCurrentApplicationAttemptId() == null) {
       app.appReport.setCurrentApplicationAttemptId(

+ 33 - 6
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/TestApplicationHistoryManagerOnTimelineStore.java

@@ -75,6 +75,10 @@ public class TestApplicationHistoryManagerOnTimelineStore {
   @BeforeClass
   public static void prepareStore() throws Exception {
     store = createStore(SCALE);
+    TimelineEntities entities = new TimelineEntities();
+    entities.addEntity(createApplicationTimelineEntity(
+        ApplicationId.newInstance(0, SCALE + 1), true, false));
+    store.put(entities);
   }
 
   public static TimelineStore createStore(int scale) throws Exception {
@@ -128,9 +132,9 @@ public class TestApplicationHistoryManagerOnTimelineStore {
       TimelineEntities entities = new TimelineEntities();
       ApplicationId appId = ApplicationId.newInstance(0, i);
       if (i == 2) {
-        entities.addEntity(createApplicationTimelineEntity(appId, true));
+        entities.addEntity(createApplicationTimelineEntity(appId, true, true));
       } else {
-        entities.addEntity(createApplicationTimelineEntity(appId, false));
+        entities.addEntity(createApplicationTimelineEntity(appId, false, true));
       }
       store.put(entities);
       for (int j = 1; j <= scale; ++j) {
@@ -208,6 +212,27 @@ public class TestApplicationHistoryManagerOnTimelineStore {
     }
   }
 
+  @Test
+  public void testGetApplicationReportWithNotAttempt() throws Exception {
+    final ApplicationId appId = ApplicationId.newInstance(0, SCALE + 1);
+    ApplicationReport app;
+    if (callerUGI == null) {
+      app = historyManager.getApplication(appId);
+    } else {
+      app =
+          callerUGI.doAs(new PrivilegedExceptionAction<ApplicationReport> () {
+            @Override
+            public ApplicationReport run() throws Exception {
+              return historyManager.getApplication(appId);
+            }
+          });
+    }
+    Assert.assertNotNull(app);
+    Assert.assertEquals(appId, app.getApplicationId());
+    Assert.assertEquals(ApplicationAttemptId.newInstance(appId, -1),
+        app.getCurrentApplicationAttemptId());
+  }
+
   @Test
   public void testGetApplicationAttemptReport() throws Exception {
     final ApplicationAttemptId appAttemptId =
@@ -301,7 +326,7 @@ public class TestApplicationHistoryManagerOnTimelineStore {
     Collection<ApplicationReport> apps =
         historyManager.getAllApplications().values();
     Assert.assertNotNull(apps);
-    Assert.assertEquals(SCALE, apps.size());
+    Assert.assertEquals(SCALE + 1, apps.size());
   }
 
   @Test
@@ -401,7 +426,7 @@ public class TestApplicationHistoryManagerOnTimelineStore {
   }
 
   private static TimelineEntity createApplicationTimelineEntity(
-      ApplicationId appId, boolean emptyACLs) {
+      ApplicationId appId, boolean emptyACLs, boolean noAttempt) {
     TimelineEntity entity = new TimelineEntity();
     entity.setEntityType(ApplicationMetricsConstants.ENTITY_TYPE);
     entity.setEntityId(appId.toString());
@@ -438,8 +463,10 @@ public class TestApplicationHistoryManagerOnTimelineStore {
         FinalApplicationStatus.UNDEFINED.toString());
     eventInfo.put(ApplicationMetricsConstants.STATE_EVENT_INFO,
         YarnApplicationState.FINISHED.toString());
-    eventInfo.put(ApplicationMetricsConstants.LATEST_APP_ATTEMPT_EVENT_INFO,
-        ApplicationAttemptId.newInstance(appId, 1));
+    if (noAttempt) {
+      eventInfo.put(ApplicationMetricsConstants.LATEST_APP_ATTEMPT_EVENT_INFO,
+          ApplicationAttemptId.newInstance(appId, 1));
+    }
     tEvent.setEventInfo(eventInfo);
     entity.addEvent(tEvent);
     return entity;