Selaa lähdekoodia

YARN-2900. Application (Attempt and Container) Not Found in AHS results
in Internal Server Error (500). Contributed by Zhijie Shen and Mit Desai

(cherry picked from commit 9686261ecb872ad159fac3ca44f1792143c6d7db)

Xuan 10 vuotta sitten
vanhempi
commit
4563411e04

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

@@ -562,6 +562,9 @@ Release 2.7.1 - UNRELEASED
     YARN-3686. CapacityScheduler should trim default_node_label_expression. 
     YARN-3686. CapacityScheduler should trim default_node_label_expression. 
     (Sunil G via wangda)
     (Sunil G via wangda)
 
 
+    YARN-2900. Application (Attempt and Container) Not Found in AHS results
+    in Internal Server Error (500). (Zhijie Shen and Mit Desai via xgong)
+
 Release 2.7.0 - 2015-04-20
 Release 2.7.0 - 2015-04-20
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 69 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/TestApplicationHistoryClientService.java

@@ -41,6 +41,9 @@ import org.apache.hadoop.yarn.api.records.ApplicationReport;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.ContainerReport;
 import org.apache.hadoop.yarn.api.records.ContainerReport;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.ApplicationAttemptNotFoundException;
+import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
+import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
 import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
 import org.apache.hadoop.yarn.server.timeline.TimelineDataManager;
 import org.apache.hadoop.yarn.server.timeline.TimelineDataManager;
@@ -54,12 +57,13 @@ public class TestApplicationHistoryClientService {
 
 
   private static ApplicationHistoryClientService clientService;
   private static ApplicationHistoryClientService clientService;
   private static TimelineDataManager dataManager;
   private static TimelineDataManager dataManager;
+  private final static int MAX_APPS = 2;
 
 
   @BeforeClass
   @BeforeClass
   public static void setup() throws Exception {
   public static void setup() throws Exception {
     Configuration conf = new YarnConfiguration();
     Configuration conf = new YarnConfiguration();
     TimelineStore store =
     TimelineStore store =
-        TestApplicationHistoryManagerOnTimelineStore.createStore(2);
+        TestApplicationHistoryManagerOnTimelineStore.createStore(MAX_APPS);
     TimelineACLsManager aclsManager = new TimelineACLsManager(conf);
     TimelineACLsManager aclsManager = new TimelineACLsManager(conf);
     dataManager =
     dataManager =
         new TimelineDataManager(store, aclsManager);
         new TimelineDataManager(store, aclsManager);
@@ -71,6 +75,70 @@ public class TestApplicationHistoryClientService {
     clientService = new ApplicationHistoryClientService(historyManager);
     clientService = new ApplicationHistoryClientService(historyManager);
   }
   }
 
 
+  @Test
+  public void testApplicationNotFound() throws IOException, YarnException {
+    ApplicationId appId = null;
+    appId = ApplicationId.newInstance(0, MAX_APPS + 1);
+    GetApplicationReportRequest request =
+        GetApplicationReportRequest.newInstance(appId);
+    try {
+      @SuppressWarnings("unused")
+      GetApplicationReportResponse response =
+          clientService.getApplicationReport(request);
+      Assert.fail("Exception should have been thrown before we reach here.");
+    } catch (ApplicationNotFoundException e) {
+      //This exception is expected.
+      Assert.assertTrue(e.getMessage().contains(
+          "doesn't exist in the timeline store"));
+    } catch (Exception e) {
+      Assert.fail("Undesired exception caught");
+    }
+  }
+
+  @Test
+  public void testApplicationAttemptNotFound() throws IOException, YarnException {
+    ApplicationId appId = ApplicationId.newInstance(0, 1);
+    ApplicationAttemptId appAttemptId =
+        ApplicationAttemptId.newInstance(appId, MAX_APPS + 1);
+    GetApplicationAttemptReportRequest request =
+        GetApplicationAttemptReportRequest.newInstance(appAttemptId);
+    try {
+      @SuppressWarnings("unused")
+      GetApplicationAttemptReportResponse response =
+          clientService.getApplicationAttemptReport(request);
+      Assert.fail("Exception should have been thrown before we reach here.");
+    } catch (ApplicationAttemptNotFoundException e) {
+      //This Exception is expected
+      System.out.println(e.getMessage());
+      Assert.assertTrue(e.getMessage().contains(
+          "doesn't exist in the timeline store"));
+    } catch (Exception e) {
+      Assert.fail("Undesired exception caught");
+    }
+  }
+
+  @Test
+  public void testContainerNotFound() throws IOException, YarnException {
+   ApplicationId appId = ApplicationId.newInstance(0, 1);
+   ApplicationAttemptId appAttemptId =
+       ApplicationAttemptId.newInstance(appId, 1);
+   ContainerId containerId = ContainerId.newContainerId(appAttemptId,
+       MAX_APPS + 1);
+   GetContainerReportRequest request =
+       GetContainerReportRequest.newInstance(containerId);
+   try {
+   @SuppressWarnings("unused")
+   GetContainerReportResponse response =
+       clientService.getContainerReport(request);
+   } catch (ContainerNotFoundException e) {
+     //This exception is expected
+     Assert.assertTrue(e.getMessage().contains(
+         "doesn't exist in the timeline store"));
+   }  catch (Exception e) {
+      Assert.fail("Undesired exception caught");
+   }
+ }
+
   @Test
   @Test
   public void testApplicationReport() throws IOException, YarnException {
   public void testApplicationReport() throws IOException, YarnException {
     ApplicationId appId = null;
     ApplicationId appId = null;

+ 62 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebServices.java

@@ -82,12 +82,13 @@ public class TestAHSWebServices extends JerseyTestBase {
 
 
   private static ApplicationHistoryClientService historyClientService;
   private static ApplicationHistoryClientService historyClientService;
   private static final String[] USERS = new String[] { "foo" , "bar" };
   private static final String[] USERS = new String[] { "foo" , "bar" };
+  private static final int MAX_APPS = 5;
 
 
   @BeforeClass
   @BeforeClass
   public static void setupClass() throws Exception {
   public static void setupClass() throws Exception {
     Configuration conf = new YarnConfiguration();
     Configuration conf = new YarnConfiguration();
     TimelineStore store =
     TimelineStore store =
-        TestApplicationHistoryManagerOnTimelineStore.createStore(5);
+        TestApplicationHistoryManagerOnTimelineStore.createStore(MAX_APPS);
     TimelineACLsManager aclsManager = new TimelineACLsManager(conf);
     TimelineACLsManager aclsManager = new TimelineACLsManager(conf);
     TimelineDataManager dataManager =
     TimelineDataManager dataManager =
         new TimelineDataManager(store, aclsManager);
         new TimelineDataManager(store, aclsManager);
@@ -164,6 +165,66 @@ public class TestAHSWebServices extends JerseyTestBase {
     this.round = round;
     this.round = round;
   }
   }
 
 
+  @Test
+  public void testInvalidApp() {
+    ApplicationId appId = ApplicationId.newInstance(0, MAX_APPS + 1);
+    WebResource r = resource();
+    ClientResponse response =
+        r.path("ws").path("v1").path("applicationhistory").path("apps")
+          .path(appId.toString())
+          .queryParam("user.name", USERS[round])
+          .accept(MediaType.APPLICATION_JSON)
+          .get(ClientResponse.class);
+    assertEquals("404 not found expected", Status.NOT_FOUND,
+        response.getClientResponseStatus());
+  }
+
+  @Test
+  public void testInvalidAttempt() {
+    ApplicationId appId = ApplicationId.newInstance(0, 1);
+    ApplicationAttemptId appAttemptId =
+        ApplicationAttemptId.newInstance(appId, MAX_APPS + 1);
+    WebResource r = resource();
+    ClientResponse response =
+        r.path("ws").path("v1").path("applicationhistory").path("apps")
+          .path(appId.toString()).path("appattempts")
+          .path(appAttemptId.toString())
+          .queryParam("user.name", USERS[round])
+          .accept(MediaType.APPLICATION_JSON)
+          .get(ClientResponse.class);
+    if (round == 1) {
+      assertEquals(Status.FORBIDDEN, response.getClientResponseStatus());
+      return;
+    }
+    assertEquals("404 not found expected", Status.NOT_FOUND,
+            response.getClientResponseStatus());
+  }
+
+  @Test
+  public void testInvalidContainer() throws Exception {
+    ApplicationId appId = ApplicationId.newInstance(0, 1);
+    ApplicationAttemptId appAttemptId =
+        ApplicationAttemptId.newInstance(appId, 1);
+    ContainerId containerId = ContainerId.newContainerId(appAttemptId,
+        MAX_APPS + 1);
+    WebResource r = resource();
+    ClientResponse response =
+        r.path("ws").path("v1").path("applicationhistory").path("apps")
+          .path(appId.toString()).path("appattempts")
+          .path(appAttemptId.toString()).path("containers")
+          .path(containerId.toString())
+          .queryParam("user.name", USERS[round])
+          .accept(MediaType.APPLICATION_JSON)
+          .get(ClientResponse.class);
+    if (round == 1) {
+      assertEquals(
+          Status.FORBIDDEN, response.getClientResponseStatus());
+      return;
+    }
+    assertEquals("404 not found expected", Status.NOT_FOUND,
+            response.getClientResponseStatus());
+  }
+
   @Test
   @Test
   public void testInvalidUri() throws JSONException, Exception {
   public void testInvalidUri() throws JSONException, Exception {
     WebResource r = resource();
     WebResource r = resource();

+ 17 - 10
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java

@@ -47,6 +47,9 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationReportRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainerReportRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainerReportRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainersRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainersRequest;
+import org.apache.hadoop.yarn.exceptions.ApplicationAttemptNotFoundException;
+import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
+import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptsInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptsInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
@@ -477,17 +480,21 @@ public class WebServices {
 
 
   private static void rewrapAndThrowException(Exception e) {
   private static void rewrapAndThrowException(Exception e) {
     if (e instanceof UndeclaredThrowableException) {
     if (e instanceof UndeclaredThrowableException) {
-      if (e.getCause() instanceof AuthorizationException) {
-        throw new ForbiddenException(e.getCause());
-      } else {
-        throw new WebApplicationException(e.getCause());
-      }
+      rewrapAndThrowThrowable(e.getCause());
     } else {
     } else {
-      if (e instanceof AuthorizationException) {
-        throw new ForbiddenException(e);
-      } else {
-        throw new WebApplicationException(e);
-      }
+      rewrapAndThrowThrowable(e);
+    }
+  }
+
+  private static void rewrapAndThrowThrowable(Throwable t) {
+    if (t instanceof AuthorizationException) {
+      throw new ForbiddenException(t);
+    } else if (t instanceof ApplicationNotFoundException ||
+        t instanceof ApplicationAttemptNotFoundException ||
+        t instanceof ContainerNotFoundException) {
+      throw new NotFoundException(t);
+    } else {
+      throw new WebApplicationException(t);
     }
     }
   }
   }