Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebApp.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebApp.java (revision 1567251) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebApp.java (working copy) @@ -105,6 +105,52 @@ WebAppTests.flushOutput(injector); } + @Test public void testQueueView() { + Injector injector = WebAppTests.createMockInjector(RMContext.class, + mockRMContext(15, 1, 2, 8*GiB), + new Module() { + @Override + public void configure(Binder binder) { + try { + binder.bind(ResourceManager.class).toInstance(mockRm(3, 1, 2, 8*GiB)); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + }); + RmView rmViewInstance = injector.getInstance(QueuePage.class); + rmViewInstance.set(YarnWebParams.QUEUE_NAME, "a.a2"); + rmViewInstance.render(); + WebAppTests.flushOutput(injector); + rmViewInstance.set(YarnWebParams.QUEUE_NAME, StringHelper.cjoin( + "a.a2", "b.b2")); + rmViewInstance.render(); + WebAppTests.flushOutput(injector); + } + + @Test public void testUserView() { + Injector injector = WebAppTests.createMockInjector(RMContext.class, + mockRMContext(15, 1, 2, 8*GiB), + new Module() { + @Override + public void configure(Binder binder) { + try { + binder.bind(ResourceManager.class).toInstance(mockRm(3, 1, 2, 8*GiB)); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + }); + RmView rmViewInstance = injector.getInstance(UserAppPage.class); + rmViewInstance.set(YarnWebParams.APP_OWNER, "toto"); + rmViewInstance.render(); + WebAppTests.flushOutput(injector); + rmViewInstance.set(YarnWebParams.APP_OWNER, StringHelper.cjoin( + "toto", "glinda")); + rmViewInstance.render(); + WebAppTests.flushOutput(injector); + } + @Test public void testNodesPage() { // 10 nodes. Two of each type. final RMContext rmContext = mockRMContext(3, 2, 12, 8*GiB); Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueueBlock.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueueBlock.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueueBlock.java (revision 0) @@ -0,0 +1,54 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import static org.apache.hadoop.yarn.webapp.YarnWebParams.QUEUE_NAME; +import java.util.concurrent.ConcurrentMap; + +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.server.resourcemanager.RMContext; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; + +import com.google.inject.Inject; + +public class QueueBlock extends HtmlBlock { + + final ConcurrentMap apps; + + @Inject + QueueBlock(RMContext rmContext, ViewContext ctx) { + super(ctx); + apps = rmContext.getRMApps(); + } + + @Override + protected void render(Block html) { + String queue = $(QUEUE_NAME); + if (queue.isEmpty()) { + puts("Bad request: requires queue name"); + return; + } + + html._(MetricsOverviewTable.class); + QueryAppsBlock appsBlock = new QueryAppsBlock(apps, queue, QueryAppsBlock.QUERY_QUEUE); + appsBlock.render(html, url("app")); + + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueryAppsBlock.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueryAppsBlock.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueryAppsBlock.java (revision 0) @@ -0,0 +1,114 @@ +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import static org.apache.hadoop.yarn.util.StringHelper.join; +import static org.apache.hadoop.yarn.webapp.YarnWebParams.QUEUE_NAME; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE; + +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.ConcurrentMap; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock.Block; +import org.apache.hadoop.yarn.util.StringHelper; + +public class QueryAppsBlock { + public static final String QUERY_USER = "user"; + public static final String QUERY_QUEUE = "queue"; + + private ConcurrentMap apps; + private String keyWord; + private String queryString; + + public QueryAppsBlock(ConcurrentMap apps, String keyWord, String queryString) { + this.apps = apps; + this.keyWord = keyWord; + this.queryString = queryString; + } + + protected void render(Block html, String pathPrefix) { + TBODY> tbody = html. + table("#apps"). + thead(). + tr(). + th(".id", "ID"). + th(".user", "User"). + th(".name", "Name"). + th(".queue", "Queue"). + th(".starttime", "StartTime"). + th(".finishtime", "FinishTime"). + th(".state", "State"). + th(".finalstatus", "FinalStatus"). + th(".totalmemory", "Total Memory"). + th(".totalcores", "Total Cores"). + th(".progress", "Progress"). + th(".ui", "Application Overview")._()._(). + tbody(); + Collection keyNames = null; + if (keyWord != null && !keyWord.isEmpty()) { + String[] keyStrings = keyWord.split(","); + keyNames = new HashSet(keyStrings.length); + for(String key : keyStrings) { + keyNames.add(key); + } + } + StringBuilder appsTableData = new StringBuilder("[\n"); + for (RMApp app : apps.values()) { + if(queryString.equals(QUERY_USER)) { + if (keyNames != null && !keyNames.contains(app.getUser())) { + continue; + } + } else if(queryString.equals(QUERY_QUEUE)) { + if (keyNames != null && !keyNames.contains(app.getQueue())) { + continue; + } + + } + AppInfo appInfo = new AppInfo(app, true); + String trackingURL = + !appInfo.isTrackingUrlReady()? "#" : appInfo.getTrackingUrlPretty(); + String percent = String.format("%.1f", appInfo.getProgress()); + //AppID numerical value parsed by parseHadoopID in yarn.dt.plugins.js + appsTableData.append("[\"") + .append(appInfo.getAppId()).append("\",\"") + .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml( + appInfo.getUser()))).append("\",\"") + .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml( + appInfo.getName()))).append("\",\"") + .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml( + appInfo.getQueue()))).append("\",\"") + .append(appInfo.getStartTime()).append("\",\"") + .append(appInfo.getFinishTime()).append("\",\"") + .append(appInfo.getState()).append("\",\"") + .append(appInfo.getFinalStatus()).append("\",\"") + .append(StringUtils.byteDesc(appInfo.getTotalMemory())).append("\",\"") + .append(appInfo.getTotalCores()).append("\",\"") + // Progress bar + .append("
").append("
") + .append("\",\"").append("RM app").append("\"],\n"); + } + if(appsTableData.charAt(appsTableData.length() - 2) == ',') { + appsTableData.delete(appsTableData.length()-2, appsTableData.length()-1); + } + appsTableData.append("]"); + html.script().$type("text/javascript"). + _("var appsTableData=" + appsTableData)._(); + tbody._()._(); + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmView.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmView.java (revision 1567251) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmView.java (working copy) @@ -37,7 +37,10 @@ set(DATATABLES_ID, "apps"); set(initID(DATATABLES, "apps"), appsTableInit()); setTableStyles(html, "apps", ".queue {width:6em}", ".ui {width:8em}"); - + setTitle(); + } + + protected void setTitle(){ // Set the correct title. String reqState = $(APP_STATE); reqState = (reqState == null || reqState.isEmpty() ? "All" : reqState); Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppPage.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppPage.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppPage.java (revision 0) @@ -0,0 +1,38 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import static org.apache.hadoop.yarn.util.StringHelper.sjoin; +import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_OWNER; + +import org.apache.hadoop.yarn.webapp.SubView; + +public class UserAppPage extends RmView { + @Override + protected void setTitle() { + // Set the correct title. + String user = $(APP_OWNER); + user = (user == null || user.isEmpty() ? "All" : user + "\'s"); + setTitle(sjoin(user, "Applications")); + } + + @Override protected Class content() { + return UserAppBlock.class; + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java (revision 1567251) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebApp.java (working copy) @@ -58,5 +58,6 @@ route(pajoin("/app", APPLICATION_ID), RmController.class, "app"); route("/scheduler", RmController.class, "scheduler"); route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue"); + route(pajoin("/user", APP_OWNER), RmController.class, "user"); } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueuePage.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueuePage.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/QueuePage.java (revision 0) @@ -0,0 +1,38 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import static org.apache.hadoop.yarn.util.StringHelper.sjoin; +import static org.apache.hadoop.yarn.webapp.YarnWebParams.QUEUE_NAME; + +import org.apache.hadoop.yarn.webapp.SubView; + +public class QueuePage extends RmView { + + protected void setTitle() { + // Set the correct title. + String queue = $(QUEUE_NAME); + queue = (queue == null || queue.isEmpty() ? "All" : queue + "\'s"); + setTitle(sjoin(queue, "Applications")); + } + + @Override protected Class content() { + return QueueBlock.class; + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java (revision 1567251) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RmController.java (working copy) @@ -58,6 +58,10 @@ public void nodes() { render(NodesPage.class); } + + public void user(){ + render(UserAppPage.class); + } public void scheduler() { // limit applications to those in states relevant to scheduling @@ -87,7 +91,7 @@ } public void queue() { - setTitle(join("Queue ", get(QUEUE_NAME, "unknown"))); + render(QueuePage.class); } public void submit() { Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppBlock.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppBlock.java (revision 0) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/UserAppBlock.java (revision 0) @@ -0,0 +1,84 @@ +/** +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.hadoop.yarn.server.resourcemanager.webapp; + +import static org.apache.hadoop.yarn.util.StringHelper.join; +import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_OWNER; +import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD; +import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH; + +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.ConcurrentMap; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.hadoop.http.HttpConfig; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.util.StringUtils; +import org.apache.hadoop.yarn.api.records.ApplicationAccessType; +import org.apache.hadoop.yarn.api.records.ApplicationId; +import org.apache.hadoop.yarn.server.resourcemanager.RMContext; +import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; +import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppAttemptInfo; +import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo; +import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; +import org.apache.hadoop.yarn.util.Apps; +import org.apache.hadoop.yarn.util.Times; +import org.apache.hadoop.yarn.webapp.View.ViewContext; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; +import org.apache.hadoop.yarn.webapp.view.InfoBlock; + +import com.google.inject.Inject; + +public class UserAppBlock extends HtmlBlock { + + private final ConcurrentMap apps; + + @Inject + UserAppBlock(RMContext rmContext, ViewContext ctx) { + super(ctx); + apps = rmContext.getRMApps(); + } + + @Override + protected void render(Block html) { + String user = $(APP_OWNER); + if (user.isEmpty()) { + puts("Bad request: requires user name"); + return; + } + + html._(MetricsOverviewTable.class); + + QueryAppsBlock appsBlock = new QueryAppsBlock(apps, user, QueryAppsBlock.QUERY_USER); + appsBlock.render(html, url("app")); + } +}