diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java index d17c880..c0f5c08 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.util.Collection; import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.ConcurrentMap; import javax.servlet.http.HttpServletRequest; @@ -231,7 +233,8 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, @QueryParam("startedTimeBegin") String startedBegin, @QueryParam("startedTimeEnd") String startedEnd, @QueryParam("finishedTimeBegin") String finishBegin, - @QueryParam("finishedTimeEnd") String finishEnd) { + @QueryParam("finishedTimeEnd") String finishEnd, + @QueryParam("applicationTypes") String appTypesQuery) { long num = 0; boolean checkCount = false; boolean checkStart = false; @@ -332,6 +335,19 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, continue; } } + if (appTypesQuery != null && !appTypesQuery.isEmpty()) { + String[] appTypes = appTypesQuery.split(","); + Set applicationTypes = new HashSet(); + for (String appType : appTypes) { + if (!appType.trim().isEmpty()) { + applicationTypes.add(appType); + } + } + if (!applicationTypes.isEmpty() + && !applicationTypes.contains(rmapp.getApplicationType())) { + continue; + } + } if (checkStart && (rmapp.getStartTime() < sBegin || rmapp.getStartTime() > sEnd)) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java index deb53eb..4aaaf62 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesApps.java @@ -638,6 +638,81 @@ public void testAppsQueryFinishBeginEnd() throws JSONException, Exception { } @Test + public void testAppsQueryAppTypes() throws JSONException, Exception { + rm.start(); + MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); + Thread.sleep(1); + RMApp app1 = rm.submitApp(1024); + amNodeManager.nodeHeartbeat(true); + // finish App + MockAM am = rm + .sendAMLaunched(app1.getCurrentAppAttempt().getAppAttemptId()); + am.registerAppAttempt(); + am.unregisterAppAttempt(); + amNodeManager.nodeHeartbeat(app1.getCurrentAppAttempt().getAppAttemptId(), + 1, ContainerState.COMPLETE); + + rm.submitApp(1024); + rm.submitApp(1024); + + WebResource r = resource(); + ClientResponse response = r.path("ws").path("v1").path("cluster") + .path("apps").queryParam("applicationTypes", "MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + JSONObject json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + assertTrue(json.isNull("apps")); + + r = resource(); + response = r.path("ws").path("v1").path("cluster") + .path("apps").queryParam("applicationTypes", "YARN,MAPREDUCE") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + JSONObject apps = json.getJSONObject("apps"); + assertEquals("incorrect number of elements", 1, apps.length()); + JSONArray array = apps.getJSONArray("app"); + assertEquals("incorrect number of elements", 3, array.length()); + + r = resource(); + response = r.path("ws").path("v1").path("cluster") + .path("apps").queryParam("applicationTypes", "") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + JSONObject apps1 = json.getJSONObject("apps"); + assertEquals("incorrect number of elements", 1, apps1.length()); + JSONArray array1 = apps1.getJSONArray("app"); + assertEquals("incorrect number of elements", 3, array1.length()); + + r = resource(); + response = r.path("ws").path("v1").path("cluster") + .path("apps").queryParam("applicationTypes", " , ,,,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + JSONObject apps2 = json.getJSONObject("apps"); + assertEquals("incorrect number of elements", 1, apps2.length()); + JSONArray array2 = apps2.getJSONArray("app"); + assertEquals("incorrect number of elements", 3, array2.length()); + + r = resource(); + response = r.path("ws").path("v1").path("cluster") + .path("apps").queryParam("applicationTypes", "MAPREDUCE, ,") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType()); + json = response.getEntity(JSONObject.class); + assertEquals("incorrect number of elements", 1, json.length()); + assertTrue(json.isNull("apps")); + + rm.stop(); + } + + @Test public void testSingleApp() throws JSONException, Exception { rm.start(); MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/ResourceManagerRest.apt.vm b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/ResourceManagerRest.apt.vm index c1c8889..ab3493b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/ResourceManagerRest.apt.vm +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/apt/ResourceManagerRest.apt.vm @@ -1108,7 +1108,7 @@ ResourceManager REST API's. ** Query Parameters Supported Multiple paramters can be specified. The started and finished times have a begin and end parameter to allow you to specify ranges. For example, one could request all applications that started between 1:00am and 2:00pm on 12/19/2011 with startedTimeBegin=1324256400&startedTimeEnd=1324303200. If the Begin parameter is not specfied, it defaults to 0, and if the End parameter is not specified, it defaults to infinity. - + The applicationTypes parameter allows you to filter the applications. For example, one could request all applications whose applicationType is either YARN or MAPREDUCE with applicationTypes=YARN,MAPREDUCE. The comma is used as Delimiter. If applicationTypes parameter is not specified, it defaults to all applications. ------ * state - state of the application * finalStatus - the final status of the application - reported by the application itself @@ -1119,6 +1119,7 @@ ResourceManager REST API's. * startedTimeEnd - applications with start time ending with this time, specified in ms since epoch * finishedTimeBegin - applications with finish time beginning with this time, specified in ms since epoch * finishedTimeEnd - applications with finish time ending with this time, specified in ms since epoch + * applicationTypes - applications matching the given application Type ------ ** Elements of the (Applications) object