diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java index e7a22bd..5891879 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.java @@ -158,7 +158,7 @@ public ContainerInfo getContainer(@Context HttpServletRequest req, if (stateQuery != null && !stateQuery.isEmpty()) { statesQuery.add(stateQuery); } - Set appStates = parseQueries(statesQuery, true); + Set appStates = parseQueries(statesQuery, ParamType.STATES); for (String appState : appStates) { switch (YarnApplicationState.valueOf( StringUtils.toUpperCase(appState))) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java index 40e40c9..9319ac4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java @@ -66,6 +66,8 @@ protected ApplicationBaseProtocol appBaseProt; + protected enum ParamType {STATES, TYPES, TAGS, USERS} + public WebServices(ApplicationBaseProtocol appBaseProt) { this.appBaseProt = appBaseProt; } @@ -130,7 +132,7 @@ public AppsInfo getApps(HttpServletRequest req, HttpServletResponse res, "finishTimeEnd must be greater than finishTimeBegin"); } - Set appTypes = parseQueries(applicationTypes, false); + Set appTypes = parseQueries(applicationTypes, ParamType.TYPES); if (!appTypes.isEmpty()) { checkAppTypes = true; } @@ -139,7 +141,7 @@ public AppsInfo getApps(HttpServletRequest req, HttpServletResponse res, if (stateQuery != null && !stateQuery.isEmpty()) { statesQuery.add(stateQuery); } - Set appStates = parseQueries(statesQuery, true); + Set appStates = parseQueries(statesQuery, ParamType.STATES); if (!appStates.isEmpty()) { checkAppStates = true; } @@ -394,7 +396,7 @@ protected void init(HttpServletResponse response) { } protected static Set - parseQueries(Set queries, boolean isState) { + parseQueries(Set queries, ParamType paramType) { Set params = new HashSet(); if (!queries.isEmpty()) { for (String query : queries) { @@ -402,7 +404,7 @@ protected void init(HttpServletResponse response) { String[] paramStrs = query.split(","); for (String paramStr : paramStrs) { if (paramStr != null && !paramStr.trim().isEmpty()) { - if (isState) { + if (paramType == ParamType.STATES) { try { // enum string is in the uppercase YarnApplicationState.valueOf( @@ -415,8 +417,13 @@ protected void init(HttpServletResponse response) { + paramStr.trim() + " specified. It should be one of " + allAppStates); } + params.add(StringUtils.toLowerCase(paramStr.trim())); + } else if (paramType == ParamType.TYPES || + paramType == ParamType.TAGS) { + params.add(StringUtils.toLowerCase(paramStr.trim())); + } else if (paramType == ParamType.USERS) { + params.add(paramStr.trim()); } - params.add(StringUtils.toLowerCase(paramStr.trim())); } } } 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 6c5dbd0..d569f63 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 @@ -392,6 +392,7 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, @QueryParam("states") Set statesQuery, @QueryParam("finalStatus") String finalStatusQuery, @QueryParam("user") String userQuery, + @QueryParam("users") Set usersQuery, @QueryParam("queue") String queueQuery, @QueryParam("limit") String count, @QueryParam("startedTimeBegin") String startedBegin, @@ -461,12 +462,12 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, "finishTimeEnd must be greater than finishTimeBegin"); } - Set appTypes = parseQueries(applicationTypes, false); + Set appTypes = parseQueries(applicationTypes, ParamType.TYPES); if (!appTypes.isEmpty()) { checkAppTypes = true; } - Set appTags = parseQueries(applicationTags, false); + Set appTags = parseQueries(applicationTags, ParamType.TAGS); if (!appTags.isEmpty()) { checkAppTags = true; } @@ -475,7 +476,7 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, if (stateQuery != null && !stateQuery.isEmpty()) { statesQuery.add(stateQuery); } - Set appStates = parseQueries(statesQuery, true); + Set appStates = parseQueries(statesQuery, ParamType.STATES); if (!appStates.isEmpty()) { checkAppStates = true; } @@ -523,9 +524,11 @@ public AppsInfo getApps(@Context HttpServletRequest hsr, } if (userQuery != null && !userQuery.isEmpty()) { - Set users = new HashSet(1); - users.add(userQuery); - request.setUsers(users); + usersQuery.add(userQuery); + } + Set appUsers = parseQueries(usersQuery, ParamType.USERS); + if (!appUsers.isEmpty()) { + request.setUsers(appUsers); } List appReports = null; @@ -573,8 +576,8 @@ public ApplicationStatisticsInfo getAppStatistics( // parse the params and build the scoreboard // converting state/type name to lowercase - Set states = parseQueries(stateQueries, true); - Set types = parseQueries(typeQueries, false); + Set states = parseQueries(stateQueries, ParamType.STATES); + Set types = parseQueries(typeQueries, ParamType.TYPES); // if no types, counts the applications of any types if (types.size() == 0) { types.add(ANY); 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/TestRMWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServices.java index c329629..1e55c47 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServices.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServices.java @@ -648,13 +648,13 @@ public void testAppsRace() throws Exception { // verify we don't get any apps when querying HttpServletRequest mockHsr = mock(HttpServletRequest.class); - AppsInfo appsInfo = webSvc.getApps(mockHsr, null, emptySet, null, - null, null, null, null, null, null, null, emptySet, emptySet); + AppsInfo appsInfo = webSvc.getApps(mockHsr, null, emptySet, null, null, + emptySet, null, null, null, null, null, null, emptySet, emptySet); assertTrue(appsInfo.getApps().isEmpty()); // verify we don't get an NPE when specifying a final status query - appsInfo = webSvc.getApps(mockHsr, null, emptySet, "FAILED", - null, null, null, null, null, null, null, emptySet, emptySet); + appsInfo = webSvc.getApps(mockHsr, null, emptySet, "FAILED", null, + emptySet, null, null, null, null, null, null, emptySet, emptySet); assertTrue(appsInfo.getApps().isEmpty()); } 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 05f141f..bab6443 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 @@ -555,6 +555,51 @@ public void testAppsQueryUser() throws JSONException, Exception { } @Test + public void testAppsQueryUsers() throws JSONException, Exception { + rm.start(); + MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048); + rm.submitApp(CONTAINER_MB, "", "user1"); + rm.submitApp(CONTAINER_MB, "", "user2"); + rm.submitApp(CONTAINER_MB, "", "uSEr3"); + + amNodeManager.nodeHeartbeat(true); + WebResource r = resource(); + ClientResponse response1 = r + .path("ws") + .path("v1") + .path("cluster") + .path("apps") + .queryParam("users", "user1,user3") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response1.getType()); + JSONObject json1 = response1.getEntity(JSONObject.class); + + assertEquals("incorrect number of elements", 1, json1.length()); + JSONObject apps1 = json1.getJSONObject("apps"); + assertEquals("incorrect number of elements", 1, apps1.length()); + JSONArray array1 = apps1.getJSONArray("app"); + assertEquals("incorrect number of elements", 1, array1.length()); + + ClientResponse response2 = r + .path("ws") + .path("v1") + .path("cluster") + .path("apps") + .queryParam("users", "user2,uSEr3") + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + assertEquals(MediaType.APPLICATION_JSON_TYPE, response2.getType()); + JSONObject json2 = response2.getEntity(JSONObject.class); + + assertEquals("incorrect number of elements", 1, json2.length()); + JSONObject apps2 = json2.getJSONObject("apps"); + assertEquals("incorrect number of elements", 1, apps2.length()); + JSONArray array2 = apps2.getJSONArray("app"); + assertEquals("incorrect number of elements", 2, array2.length()); + + rm.stop(); + } + + @Test public void testAppsQueryQueue() throws JSONException, Exception { rm.start(); MockNM amNodeManager = rm.registerNode("127.0.0.1:1234", 2048);