diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java
index 121e5344fdb..c286766ea36 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/Router.java
@@ -23,6 +23,7 @@
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.apache.hadoop.service.CompositeService;
import org.apache.hadoop.util.ShutdownHookManager;
import org.apache.hadoop.util.StringUtils;
@@ -74,6 +75,8 @@
*/
public static final int SHUTDOWN_HOOK_PRIORITY = 30;
+ private static final String METRICS_NAME = "YARN Router";
+
public Router() {
super(Router.class.getName());
}
@@ -95,6 +98,8 @@ protected void serviceInit(Configuration config) throws Exception {
webAppAddress = WebAppUtils.getWebAppBindURL(this.conf,
YarnConfiguration.ROUTER_BIND_HOST,
WebAppUtils.getRouterWebAppURLWithoutScheme(this.conf));
+ // Metrics
+ DefaultMetricsSystem.initialize(METRICS_NAME);
super.serviceInit(conf);
}
@@ -118,6 +123,7 @@ protected void serviceStop() throws Exception {
return;
}
super.serviceStop();
+ DefaultMetricsSystem.shutdown();
}
protected void shutDown() {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutBlock.java
new file mode 100644
index 00000000000..a8575c48ad5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutBlock.java
@@ -0,0 +1,87 @@
+/**
+* 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.router.webapp;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWSConsts;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
+import org.apache.hadoop.yarn.server.router.Router;
+import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+import com.google.inject.Inject;
+
+/**
+ * About block for the Router Web UI.
+ */
+public class AboutBlock extends HtmlBlock {
+
+ private static final long BYTES_IN_MB = 1024 * 1024;
+
+ private final Router router;
+
+ @Inject
+ AboutBlock(Router router, ViewContext ctx) {
+ super(ctx);
+ this.router = router;
+ }
+
+ @Override
+ protected void render(Block html) {
+ Configuration conf = this.router.getConfig();
+ String webAppAddress = WebAppUtils.getRouterWebAppURLWithScheme(conf);
+LOG.info("webAppAddress " + webAppAddress);
+ ClusterMetricsInfo metrics = RouterWebServiceUtil.genericForward(
+ webAppAddress, null, ClusterMetricsInfo.class, HTTPMethods.GET,
+ RMWSConsts.RM_WEB_SERVICE_PATH + RMWSConsts.METRICS, null, null);
+ boolean isEnabled = conf.getBoolean(
+ YarnConfiguration.FEDERATION_ENABLED,
+ YarnConfiguration.DEFAULT_FEDERATION_ENABLED);
+ info("Cluster Status").
+ __("Federation Enabled", isEnabled).
+ __("Applications Submitted", "N/A").
+ __("Applications Pending", "N/A").
+ __("Applications Running", "N/A").
+ __("Applications Failed", "N/A").
+ __("Applications Killed", "N/A").
+ __("Applications Completed", "N/A").
+ __("Containers Allocated", metrics.getContainersAllocated()).
+ __("Containers Reserved", metrics.getReservedContainers()).
+ __("Containers Pending", metrics.getPendingContainers()).
+ __("Available Memory", StringUtils.byteDesc(metrics.getAvailableMB() * BYTES_IN_MB)).
+ __("Allocated Memory", StringUtils.byteDesc(metrics.getAllocatedMB() * BYTES_IN_MB)).
+ __("Reserved Memory", StringUtils.byteDesc(metrics.getReservedMB() * BYTES_IN_MB)).
+ __("Total Memory", StringUtils.byteDesc(metrics.getTotalMB() * BYTES_IN_MB)).
+ __("Available VirtualCores", metrics.getAvailableVirtualCores()).
+ __("Allocated VirtualCores", metrics.getAllocatedVirtualCores()).
+ __("Reserved VirtualCores", metrics.getReservedVirtualCores()).
+ __("Total VirtualCores", metrics.getTotalVirtualCores()).
+ __("Active Nodes", metrics.getActiveNodes()).
+ __("Lost Nodes", metrics.getLostNodes()).
+ __("Available Nodes", metrics.getDecommissionedNodes()).
+ __("Unhealthy Nodes", metrics.getUnhealthyNodes()).
+ __("Rebooted Nodes", metrics.getRebootedNodes()).
+ __("Total Nodes", metrics.getTotalNodes());
+
+ html.__(InfoBlock.class);
+ }
+}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutPage.java
new file mode 100644
index 00000000000..3c9f00dbfc6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AboutPage.java
@@ -0,0 +1,37 @@
+/**
+* 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.router.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+/**
+ * About page for the Router Web UI.
+ */
+public class AboutPage extends RouterView {
+
+ @Override
+ protected void preHead(Page.HTML<__> html) {
+ commonPreHead(html);
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AboutBlock.class;
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsBlock.java
new file mode 100644
index 00000000000..56fa73e2507
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsBlock.java
@@ -0,0 +1,130 @@
+/**
+ * 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.router.webapp;
+
+import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
+import static org.apache.commons.lang.StringEscapeUtils.escapeJavaScript;
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWSConsts;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppsInfo;
+import org.apache.hadoop.yarn.server.router.Router;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TBODY;
+import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+/**
+ * Applications block for the Router Web UI.
+ */
+public class AppsBlock extends HtmlBlock {
+ private final Router router;
+
+ @Inject
+ AppsBlock(Router router, ViewContext ctx) {
+ super(ctx);
+ this.router = router;
+ }
+
+ @Override
+ protected void render(Block html) {
+ // Get the applications from the Resource Managers
+ Configuration conf = this.router.getConfig();
+ String webAppAddress = WebAppUtils.getRouterWebAppURLWithScheme(conf);
+ AppsInfo apps = RouterWebServiceUtil.genericForward(webAppAddress, null,
+ AppsInfo.class, HTTPMethods.GET,
+ RMWSConsts.RM_WEB_SERVICE_PATH + RMWSConsts.APPS, null, null);
+
+ setTitle("Applications");
+
+ TBODY
> tbody = html.table("#apps").thead()
+ .tr()
+ .th(".id", "ID")
+ .th(".user", "User")
+ .th(".name", "Name")
+ .th(".type", "Application Type")
+ .th(".queue", "Queue")
+ .th(".priority", "Application Priority")
+ .th(".starttime", "StartTime")
+ .th(".finishtime", "FinishTime")
+ .th(".state", "State")
+ .th(".finalstatus", "FinalStatus")
+ .th(".progress", "Progress")
+ .th(".ui", "Tracking UI")
+ .__().__().tbody();
+
+ // Render the applications
+ StringBuilder appsTableData = new StringBuilder("[\n");
+ for (AppInfo app : apps.getApps()) {
+ try {
+
+ String percent = String.format("%.1f", app.getProgress() * 100.0F);
+ String trackingURL =
+ app.getTrackingUrl() == null ? "#" : app.getTrackingUrl();
+ // AppID numerical value parsed by parseHadoopID in yarn.dt.plugins.js
+ appsTableData.append("[\"")
+ .append("")
+ .append(app.getAppId()).append("\",\"")
+ .append(escape(app.getUser())).append("\",\"")
+ .append(escape(app.getName())).append("\",\"")
+ .append(escape(app.getApplicationType())).append("\",\"")
+ .append(escape(app.getQueue())).append("\",\"")
+ .append(String.valueOf(app.getPriority())).append("\",\"")
+ .append(app.getStartTime()).append("\",\"")
+ .append(app.getFinishTime()).append("\",\"")
+ .append(app.getState()).append("\",\"")
+ .append(app.getFinalStatus()).append("\",\"")
+ // Progress bar
+ .append("
")
+ // History link
+ .append("\",\"")
+ .append("History").append("");
+ appsTableData.append("\"],\n");
+
+ } catch (Exception e) {
+ LOG.info(
+ "Cannot add application {}: {}", app.getAppId(), e.getMessage());
+ }
+ }
+ 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.__().__();
+ }
+
+ private static String escape(String str) {
+ return escapeJavaScript(escapeHtml(str));
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsPage.java
new file mode 100644
index 00000000000..12d0b5b4ede
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/AppsPage.java
@@ -0,0 +1,77 @@
+/**
+ * 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.router.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.sjoin;
+import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+class AppsPage extends RouterView {
+
+ @Override
+ protected void preHead(Page.HTML<__> html) {
+ commonPreHead(html);
+ set(DATATABLES_ID, "apps");
+ set(initID(DATATABLES, "apps"), appsTableInit());
+ setTableStyles(html, "apps", ".queue {width:6em}", ".ui {width:8em}");
+
+ // Set the correct title.
+ String reqState = $(APP_STATE);
+ reqState = (reqState == null || reqState.isEmpty() ? "All" : reqState);
+ setTitle(sjoin(reqState, "Applications"));
+ }
+
+ private String appsTableInit() {
+ // id, user, name, queue, starttime, finishtime, state, status, progress, ui
+ return tableInit()
+ .append(", 'aaData': appsTableData")
+ .append(", bDeferRender: true")
+ .append(", bProcessing: true")
+
+ .append("\n, aoColumnDefs: ")
+ .append(getAppsTableColumnDefs())
+
+ // Sort by id upon page load
+ .append(", aaSorting: [[0, 'desc']]}").toString();
+ }
+
+ protected String getAppsTableColumnDefs() {
+ StringBuilder sb = new StringBuilder();
+ return sb
+ .append("[\n")
+ .append("{'sType':'string', 'aTargets': [0]")
+ .append(", 'mRender': parseHadoopID }")
+
+ .append("\n, {'sType':'numeric', 'aTargets': [6, 7]")
+ .append(", 'mRender': renderHadoopDate }")
+
+ .append("\n, {'sType':'numeric', bSearchable:false, 'aTargets': [10]")
+ .append(", 'mRender': parseHadoopProgress }]").toString();
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AppsBlock.class;
+ }
+}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/DefaultRequestInterceptorREST.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/DefaultRequestInterceptorREST.java
index abd8ca6ec10..d63fc66501b 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/DefaultRequestInterceptorREST.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/DefaultRequestInterceptorREST.java
@@ -129,7 +129,9 @@ public String dumpSchedulerLogs(String time, HttpServletRequest hsr)
public NodesInfo getNodes(String states) {
// states will be part of additionalParam
Map additionalParam = new HashMap();
- additionalParam.put(RMWSConsts.STATES, new String[] {states});
+ if (states != null && !states.isEmpty()) {
+ additionalParam.put(RMWSConsts.STATES, new String[] { states });
+ }
return RouterWebServiceUtil.genericForward(webAppAddress, null,
NodesInfo.class, HTTPMethods.GET,
RMWSConsts.RM_WEB_SERVICE_PATH + RMWSConsts.NODES, null,
@@ -227,8 +229,10 @@ public LabelsToNodesInfo getLabelsToNodes(Set labels)
throws IOException {
// labels will be part of additionalParam
Map additionalParam = new HashMap();
- additionalParam.put(RMWSConsts.LABELS,
- labels.toArray(new String[labels.size()]));
+ if (labels != null && !labels.isEmpty()) {
+ additionalParam.put(RMWSConsts.LABELS,
+ labels.toArray(new String[labels.size()]));
+ }
return RouterWebServiceUtil.genericForward(webAppAddress, null,
LabelsToNodesInfo.class, HTTPMethods.GET,
RMWSConsts.RM_WEB_SERVICE_PATH + RMWSConsts.LABEL_MAPPINGS, null,
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationBlock.java
new file mode 100644
index 00000000000..187b1c8bff5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationBlock.java
@@ -0,0 +1,172 @@
+/**
+ * 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.router.webapp;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.hadoop.yarn.server.federation.store.records.SubClusterId;
+import org.apache.hadoop.yarn.server.federation.store.records.SubClusterInfo;
+import org.apache.hadoop.yarn.server.federation.utils.FederationStateStoreFacade;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
+import org.apache.hadoop.yarn.server.router.Router;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TBODY;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+import com.sun.jersey.api.json.JSONConfiguration;
+import com.sun.jersey.api.json.JSONJAXBContext;
+import com.sun.jersey.api.json.JSONUnmarshaller;
+
+class FederationBlock extends HtmlBlock {
+
+ private static final long BYTES_IN_MB = 1024 * 1024;
+
+ private final Router router;
+
+ @Inject
+ FederationBlock(ViewContext ctx, Router router) {
+ super(ctx);
+ this.router = router;
+ }
+
+ @Override
+ public void render(Block html) {
+ Configuration conf = this.router.getConfig();
+ boolean isEnabled = conf.getBoolean(
+ YarnConfiguration.FEDERATION_ENABLED,
+ YarnConfiguration.DEFAULT_FEDERATION_ENABLED);
+ if (isEnabled) {
+ setTitle("Federation");
+
+ // Table header
+ TBODY> tbody = html.table("#rms").thead().tr()
+ .th(".id", "SubCluster")
+ .th(".submittedA", "Applications Submitted*")
+ .th(".pendingA", "Applications Pending*")
+ .th(".runningA", "Applications Running*")
+ .th(".failedA", "Applications Failed*")
+ .th(".killedA", "Applications Killed*")
+ .th(".completedA", "Applications Completed*")
+ .th(".contAllocated", "Containers Allocated")
+ .th(".contReserved", "Containers Reserved")
+ .th(".contPending", "Containers Pending")
+ .th(".availableM", "Available Memory")
+ .th(".allocatedM", "Allocated Memory")
+ .th(".reservedM", "Reserved Memory")
+ .th(".totalM", "Total Memory")
+ .th(".availableVC", "Available VirtualCores")
+ .th(".allocatedVC", "Allocated VirtualCores")
+ .th(".reservedVC", "Reserved VirtualCores")
+ .th(".totalVC", "Total VirtualCores")
+ .th(".activeN", "Active Nodes")
+ .th(".lostN", "Lost Nodes")
+ .th(".availableN", "Available Nodes")
+ .th(".unhealtyN", "Unhealthy Nodes")
+ .th(".rebootedN", "Rebooted Nodes")
+ .th(".totalN", "Total Nodes")
+ .__().__().tbody();
+
+ try {
+ // Binding to the FederationStateStore
+ FederationStateStoreFacade facade =
+ FederationStateStoreFacade.getInstance();
+ Map subClustersInfo =
+ facade.getSubClusters(true);
+
+ // Sort the SubClusters
+ List subclusters = new ArrayList<>();
+ subclusters.addAll(subClustersInfo.values());
+ Comparator super SubClusterInfo> cmp =
+ new Comparator() {
+ @Override
+ public int compare(SubClusterInfo o1, SubClusterInfo o2) {
+ return o1.getSubClusterId().compareTo(o2.getSubClusterId());
+ }
+ };
+ Collections.sort(subclusters, cmp);
+
+ for (SubClusterInfo subcluster : subclusters) {
+ SubClusterId subClusterId = subcluster.getSubClusterId();
+ String webAppAddress = subcluster.getRMWebServiceAddress();
+ String capability = subcluster.getCapability();
+ ClusterMetricsInfo subClusterInfo = getClusterMetricsInfo(capability);
+
+ // Building row per SubCluster
+ tbody.tr().td().a("//" + webAppAddress, subClusterId.toString()).__()
+ .td(Integer.toString(subClusterInfo.getAppsSubmitted()))
+ .td(Integer.toString(subClusterInfo.getAppsPending()))
+ .td(Integer.toString(subClusterInfo.getAppsRunning()))
+ .td(Integer.toString(subClusterInfo.getAppsFailed()))
+ .td(Integer.toString(subClusterInfo.getAppsKilled()))
+ .td(Integer.toString(subClusterInfo.getAppsCompleted()))
+ .td(Integer.toString(subClusterInfo.getContainersAllocated()))
+ .td(Integer.toString(subClusterInfo.getReservedContainers()))
+ .td(Integer.toString(subClusterInfo.getPendingContainers()))
+ .td(StringUtils.byteDesc(subClusterInfo.getAvailableMB() * BYTES_IN_MB))
+ .td(StringUtils.byteDesc(subClusterInfo.getAllocatedMB() * BYTES_IN_MB))
+ .td(StringUtils.byteDesc(subClusterInfo.getReservedMB() * BYTES_IN_MB))
+ .td(StringUtils.byteDesc(subClusterInfo.getTotalMB() * BYTES_IN_MB))
+ .td(Long.toString(subClusterInfo.getAvailableVirtualCores()))
+ .td(Long.toString(subClusterInfo.getAllocatedVirtualCores()))
+ .td(Long.toString(subClusterInfo.getReservedVirtualCores()))
+ .td(Long.toString(subClusterInfo.getTotalVirtualCores()))
+ .td(Integer.toString(subClusterInfo.getActiveNodes()))
+ .td(Integer.toString(subClusterInfo.getLostNodes()))
+ .td(Integer.toString(subClusterInfo.getDecommissionedNodes()))
+ .td(Integer.toString(subClusterInfo.getUnhealthyNodes()))
+ .td(Integer.toString(subClusterInfo.getRebootedNodes()))
+ .td(Integer.toString(subClusterInfo.getTotalNodes())).__();
+ }
+ } catch (YarnException e) {
+ LOG.error("Cannot render ResourceManager", e);
+ }
+
+ tbody.__().__().div()
+ .p().__("*The application counts are local per subcluster").__().__();
+ } else {
+ setTitle("Federation is not Enabled!");
+ }
+ }
+
+ private static ClusterMetricsInfo getClusterMetricsInfo(String capability) {
+ ClusterMetricsInfo clusterMetrics = null;
+ try {
+ JSONJAXBContext jc = new JSONJAXBContext(
+ JSONConfiguration.mapped().rootUnwrapping(false).build(),
+ ClusterMetricsInfo.class);
+ JSONUnmarshaller unmarshaller = jc.createJSONUnmarshaller();
+ clusterMetrics = unmarshaller.unmarshalFromJSON(
+ new StringReader(capability), ClusterMetricsInfo.class);
+ } catch (Exception e) {
+ LOG.error("Cannot parse SubCluster info", e);
+ }
+ return clusterMetrics;
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
index bfd35c5f769..aaee06563fb 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
@@ -19,6 +19,7 @@
package org.apache.hadoop.yarn.server.router.webapp;
import java.io.IOException;
+import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -31,6 +32,7 @@
import java.util.concurrent.Future;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@@ -129,7 +131,7 @@ public void init(String user) {
policyFacade = new RouterPolicyFacade(conf, federationFacade,
this.federationFacade.getSubClusterResolver(), null);
} catch (FederationPolicyInitializationException e) {
- LOG.error(e.getMessage());
+ throw new YarnRuntimeException(e);
}
numSubmitRetries =
@@ -210,7 +212,7 @@ private DefaultRequestInterceptorREST createInterceptorForSubCluster(
e);
}
- interceptorInstance.setWebAppAddress(webAppAddress);
+ interceptorInstance.setWebAppAddress("http://" + webAppAddress);
interceptorInstance.setSubClusterId(subClusterId);
interceptors.put(subClusterId, interceptorInstance);
return interceptorInstance;
@@ -646,17 +648,55 @@ public AppsInfo getApps(HttpServletRequest hsr, String stateQuery,
ExecutorCompletionService compSvc =
new ExecutorCompletionService(this.threadpool);
+ final String ugi = (hsr == null) ? null : hsr.getRemoteUser();
+ final Principal ugiPrincipal =
+ (hsr == null) ? null : hsr.getUserPrincipal();
+ final Map param =
+ (hsr == null) ? null : hsr.getParameterMap();
+ final String path = (hsr == null) ? null : hsr.getPathInfo();
+ final String mediaType =
+ RouterWebServiceUtil.getMediaTypeFromHttpServletRequest(
+ hsr, AppsInfo.class);
+
for (final SubClusterInfo info : subClustersActive.values()) {
+
+ // HttpServletRequest does not work with ExecutorCompletionService.
+ // Create a duplicate hsr.
+ final HttpServletRequest hsrCopy =
+ (hsr == null) ? null : new HttpServletRequestWrapper(hsr) {
+ public Map getParameterMap() {
+ return param;
+ }
+ public String getPathInfo() {
+ return path;
+ }
+ public String getRemoteUser() {
+ return ugi;
+ }
+ public Principal getUserPrincipal() {
+ return ugiPrincipal;
+ }
+
+ public String getHeader(String value) {
+ // we override only Accept
+ if (value.equals(RouterWebServiceUtil.ACCEPT)) {
+ return mediaType;
+ }
+ return null;
+ }
+ };
+
compSvc.submit(new Callable() {
+
@Override
public AppsInfo call() {
DefaultRequestInterceptorREST interceptor =
getOrCreateInterceptorForSubCluster(info.getSubClusterId(),
- info.getClientRMServiceAddress());
- AppsInfo rmApps = interceptor.getApps(hsr, stateQuery, statesQuery,
- finalStatusQuery, userQuery, queueQuery, count, startedBegin,
- startedEnd, finishBegin, finishEnd, applicationTypes,
- applicationTags, unselectedFields);
+ info.getRMWebServiceAddress());
+ AppsInfo rmApps = interceptor.getApps(hsrCopy, stateQuery,
+ statesQuery, finalStatusQuery, userQuery, queueQuery, count,
+ startedBegin, startedEnd, finishBegin, finishEnd,
+ applicationTypes, applicationTags, unselectedFields);
if (rmApps == null) {
routerMetrics.incrMultipleAppsFailedRetrieved();
@@ -739,7 +779,7 @@ public NodeInfo getNode(String nodeId) {
public NodeInfo call() {
DefaultRequestInterceptorREST interceptor =
getOrCreateInterceptorForSubCluster(info.getSubClusterId(),
- info.getClientRMServiceAddress());
+ info.getRMWebServiceAddress());
try {
NodeInfo nodeInfo = interceptor.getNode(nodeId);
return nodeInfo;
@@ -821,7 +861,7 @@ public NodesInfo getNodes(String states) {
public NodesInfo call() {
DefaultRequestInterceptorREST interceptor =
getOrCreateInterceptorForSubCluster(info.getSubClusterId(),
- info.getClientRMServiceAddress());
+ info.getRMWebServiceAddress());
try {
NodesInfo nodesInfo = interceptor.getNodes(states);
return nodesInfo;
@@ -880,7 +920,7 @@ public ClusterMetricsInfo getClusterMetricsInfo() {
public ClusterMetricsInfo call() {
DefaultRequestInterceptorREST interceptor =
getOrCreateInterceptorForSubCluster(info.getSubClusterId(),
- info.getClientRMServiceAddress());
+ info.getRMWebServiceAddress());
try {
ClusterMetricsInfo metrics = interceptor.getClusterMetricsInfo();
return metrics;
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationPage.java
new file mode 100644
index 00000000000..ddd2866e3b1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationPage.java
@@ -0,0 +1,57 @@
+/**
+* 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.router.webapp;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+/**
+ * Renders a block for the applications with metrics information.
+ */
+class FederationPage extends RouterView {
+
+ @Override
+ protected void preHead(Page.HTML<__> html) {
+ commonPreHead(html);
+ setTitle("Federation");
+ set(DATATABLES_ID, "rms");
+ set(initID(DATATABLES, "rms"), rmsTableInit());
+ setTableStyles(html, "rms", ".healthStatus {width:10em}",
+ ".healthReport {width:10em}");
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return FederationBlock.class;
+ }
+
+ private String rmsTableInit() {
+ StringBuilder b = tableInit().append(", aoColumnDefs: [");
+ b.append("{'bSearchable': false, 'aTargets': [ 7 ]}");
+ b.append(", {'sType': 'title-numeric', 'bSearchable': false, "
+ + "'aTargets': [ 8, 9 ] }");
+ b.append(", {'sType': 'title-numeric', 'aTargets': [ 5 ]}");
+ b.append("]}");
+ return b.toString();
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NavBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NavBlock.java
new file mode 100644
index 00000000000..9c39bb7b7a2
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NavBlock.java
@@ -0,0 +1,46 @@
+/**
+* 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.router.webapp;
+
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+/**
+ * Navigation block for the Router Web UI.
+ */
+public class NavBlock extends HtmlBlock {
+
+ @Override
+ public void render(Block html) {
+ html.
+ div("#nav").
+ h3("Cluster").
+ ul().
+ li().a(url(""), "About").__().
+ li().a(url("federation"), "Federation").__().
+ li().a(url("nodes"), "Nodes").__().
+ li().a(url("apps"), "Applications").__().
+ __().
+ h3("Tools").
+ ul().
+ li().a("/conf", "Configuration").__().
+ li().a("/logs", "Local logs").__().
+ li().a("/stacks", "Server stacks").__().
+ li().a("/jmx?qry=Hadoop:*", "Server metrics").__().__().__();
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesBlock.java
new file mode 100644
index 00000000000..720302e5a0d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesBlock.java
@@ -0,0 +1,109 @@
+/**
+ * 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.router.webapp;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWSConsts;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodesInfo;
+import org.apache.hadoop.yarn.server.router.Router;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TBODY;
+import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet.TR;
+import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+/**
+ * Nodes block for the Router Web UI.
+ */
+public class NodesBlock extends HtmlBlock {
+
+ private static final long BYTES_IN_MB = 1024 * 1024;
+
+ private final Router router;
+
+ @Inject
+ NodesBlock(Router router, ViewContext ctx) {
+ super(ctx);
+ this.router = router;
+ }
+
+ @Override
+ protected void render(Block html) {
+ // Get the node info from the federation
+ Configuration conf = this.router.getConfig();
+ String webAppAddress = WebAppUtils.getRouterWebAppURLWithScheme(conf);
+ NodesInfo nodes = RouterWebServiceUtil.genericForward(webAppAddress, null,
+ NodesInfo.class, HTTPMethods.GET,
+ RMWSConsts.RM_WEB_SERVICE_PATH + RMWSConsts.NODES, null, null);
+
+ setTitle("Nodes");
+
+ TBODY> tbody = html.table("#nodes").thead().tr()
+ .th(".nodelabels", "Node Labels")
+ .th(".rack", "Rack")
+ .th(".state", "Node State")
+ .th(".nodeaddress", "Node Address")
+ .th(".nodehttpaddress", "Node HTTP Address")
+ .th(".lastHealthUpdate", "Last health-update")
+ .th(".healthReport", "Health-report")
+ .th(".containers", "Containers")
+ .th(".mem", "Mem Used")
+ .th(".mem", "Mem Avail")
+ .th(".vcores", "VCores Used")
+ .th(".vcores", "VCores Avail")
+ .th(".nodeManagerVersion", "Version")
+ .__().__().tbody();
+
+ // Add nodes to the web UI
+ for (NodeInfo info : nodes.getNodes()) {
+ int usedMemory = (int) info.getUsedMemory();
+ int availableMemory = (int) info.getAvailableMemory();
+ TR>> row = tbody.tr();
+ row.td().__(StringUtils.join(",", info.getNodeLabels())).__();
+ row.td().__(info.getRack()).__();
+ row.td().__(info.getState()).__();
+ row.td().__(info.getNodeId()).__();
+ boolean isInactive = false;
+ if (isInactive) {
+ row.td().__("N/A").__();
+ } else {
+ String httpAddress = info.getNodeHTTPAddress();
+ row.td().a("//" + httpAddress, httpAddress).__();
+ }
+ row.td().br().$title(String.valueOf(info.getLastHealthUpdate())).__()
+ .__(Times.format(info.getLastHealthUpdate())).__()
+ .td(info.getHealthReport())
+ .td(String.valueOf(info.getNumContainers())).td().br()
+ .$title(String.valueOf(usedMemory)).__()
+ .__(StringUtils.byteDesc(usedMemory * BYTES_IN_MB)).__().td().br()
+ .$title(String.valueOf(availableMemory)).__()
+ .__(StringUtils.byteDesc(availableMemory * BYTES_IN_MB)).__()
+ .td(String.valueOf(info.getUsedVirtualCores()))
+ .td(String.valueOf(info.getAvailableVirtualCores()))
+ .td(info.getVersion()).__();
+ }
+ tbody.__().__();
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesPage.java
new file mode 100644
index 00000000000..0351cbac3a3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/NodesPage.java
@@ -0,0 +1,60 @@
+/**
+ * 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.router.webapp;
+
+import static org.apache.hadoop.yarn.webapp.YarnWebParams.NODE_STATE;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+class NodesPage extends RouterView {
+
+ @Override
+ protected void preHead(Page.HTML<__> html) {
+ commonPreHead(html);
+ String type = $(NODE_STATE);
+ String title = "Nodes of the cluster";
+ if (type != null && !type.isEmpty()) {
+ title = title + " (" + type + ")";
+ }
+ setTitle(title);
+ set(DATATABLES_ID, "nodes");
+ set(initID(DATATABLES, "nodes"), nodesTableInit());
+ setTableStyles(html, "nodes", ".healthStatus {width:10em}",
+ ".healthReport {width:10em}");
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return NodesBlock.class;
+ }
+
+ private String nodesTableInit() {
+ StringBuilder b = tableInit().append(", aoColumnDefs: [");
+ b.append("{'bSearchable': false, 'aTargets': [ 7 ]}");
+ b.append(", {'sType': 'title-numeric', 'bSearchable': false, "
+ + "'aTargets': [ 2, 3, 4, 5, 6 ] }");
+ b.append(", {'sType': 'title-numeric', 'aTargets': [ 5 ]}");
+ b.append("]}");
+ return b.toString();
+ }
+}
\ No newline at end of file
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterController.java
new file mode 100644
index 00000000000..e8cd0de6657
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterController.java
@@ -0,0 +1,60 @@
+/**
+* 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.router.webapp;
+
+import org.apache.hadoop.yarn.webapp.Controller;
+
+import com.google.inject.Inject;
+
+/**
+ * Controller for the Router Web UI.
+ */
+public class RouterController extends Controller {
+
+ @Inject
+ RouterController(RequestContext ctx) {
+ super(ctx);
+ }
+
+ @Override
+ public void index() {
+ setTitle("Router");
+ render(AboutPage.class);
+ }
+
+ public void about() {
+ setTitle("About the Cluster");
+ render(AboutPage.class);
+ }
+
+ public void federation() {
+ setTitle("Federation");
+ render(FederationPage.class);
+ }
+
+ public void apps() {
+ setTitle("Applications");
+ render(AppsPage.class);
+ }
+
+ public void nodes() {
+ setTitle("Nodes");
+ render(NodesPage.class);
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterView.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterView.java
new file mode 100644
index 00000000000..b377f7dc1dd
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterView.java
@@ -0,0 +1,52 @@
+/**
+* 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.router.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.view.TwoColumnLayout;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+/**
+ * View for the Router Web UI.
+ */
+public class RouterView extends TwoColumnLayout {
+
+ @Override
+ protected void preHead(Page.HTML<__> html) {
+ commonPreHead(html);
+
+ setTitle("Router");
+ }
+
+ protected void commonPreHead(Page.HTML<__> html) {
+ set(ACCORDION_ID, "nav");
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:0}");
+ }
+
+ @Override
+ protected Class extends SubView> nav() {
+ return NavBlock.class;
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AboutBlock.class;
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebApp.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebApp.java
index 5436badfb63..ba07a1afba4 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebApp.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebApp.java
@@ -44,5 +44,11 @@ public void setup() {
if (router != null) {
bind(Router.class).toInstance(router);
}
+ route("/", RouterController.class);
+ route("/cluster", RouterController.class, "about");
+ route("/about", RouterController.class, "about");
+ route("/apps", RouterController.class, "apps");
+ route("/nodes", RouterController.class, "nodes");
+ route("/federation", RouterController.class, "federation");
}
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServiceUtil.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServiceUtil.java
index e769a86bba3..087d231feee 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServiceUtil.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServiceUtil.java
@@ -19,6 +19,7 @@
package org.apache.hadoop.yarn.server.router.webapp;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashMap;
@@ -67,6 +68,8 @@
private final static String PARTIAL_REPORT = "Partial Report ";
+ protected static final String ACCEPT = "accept";
+
/** Disable constructor. */
private RouterWebServiceUtil() {
}
@@ -119,9 +122,10 @@ public T run() {
paramMap = additionalParam;
}
- ClientResponse response = RouterWebServiceUtil.invokeRMWebService(
- webApp, targetPath, method,
- (hsr == null) ? null : hsr.getPathInfo(), paramMap, formParam);
+ ClientResponse response =
+ RouterWebServiceUtil.invokeRMWebService(webApp, targetPath,
+ method, (hsr == null) ? null : hsr.getPathInfo(), paramMap,
+ formParam, getMediaTypeFromHttpServletRequest(hsr, returnType));
if (Response.class.equals(returnType)) {
return (T) RouterWebServiceUtil.clientResponseToResponse(response);
}
@@ -129,6 +133,13 @@ public T run() {
if (response.getStatus() == 200) {
return response.getEntity(returnType);
}
+ if (response.getStatus() == 204) {
+ try {
+ return returnType.getConstructor().newInstance();
+ } catch (RuntimeException | ReflectiveOperationException e) {
+ LOG.error("Cannot create empty entity for " + returnType, e);
+ }
+ }
RouterWebServiceUtil.retrieveException(response);
return null;
}
@@ -147,11 +158,10 @@ public T run() {
*/
private static ClientResponse invokeRMWebService(String webApp, String path,
HTTPMethods method, String additionalPath,
- Map queryParams, Object formParam) {
+ Map queryParams, Object formParam, String mediaType) {
Client client = Client.create();
WebResource webResource = client.resource(webApp).path(path);
-
if (additionalPath != null && !additionalPath.isEmpty()) {
webResource = webResource.path(additionalPath);
}
@@ -168,14 +178,12 @@ private static ClientResponse invokeRMWebService(String webApp, String path,
webResource = webResource.queryParams(paramMap);
}
- // I can forward the call in JSON or XML since the Router will convert it
- // again in Object before send it back to the client
Builder builder = null;
if (formParam != null) {
- builder = webResource.entity(formParam, MediaType.APPLICATION_XML);
- builder = builder.accept(MediaType.APPLICATION_XML);
+ builder = webResource.entity(formParam, mediaType);
+ builder = builder.accept(mediaType);
} else {
- builder = webResource.accept(MediaType.APPLICATION_XML);
+ builder = webResource.accept(mediaType);
}
ClientResponse response = null;
@@ -424,4 +432,25 @@ public static void mergeMetrics(ClusterMetricsInfo metrics,
metrics.getShutdownNodes() + metrics.getShutdownNodes());
}
+ /**
+ * Extract from HttpServletRequest the MediaType in output.
+ */
+ protected static String getMediaTypeFromHttpServletRequest(
+ HttpServletRequest request, final Class returnType) {
+ if (request == null) {
+ // By default we return XML for REST call without HttpServletRequest
+ return MediaType.APPLICATION_XML;
+ }
+ // TODO
+ if (!returnType.equals(Response.class)) {
+ return MediaType.APPLICATION_XML;
+ }
+ String header = request.getHeader(ACCEPT);
+ if (header == null || header.equals("*")) {
+ // By default we return JSON
+ return MediaType.APPLICATION_JSON;
+ }
+ return header;
+ }
+
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServices.java
index bbb83268274..fbe3fc5db42 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServices.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/RouterWebServices.java
@@ -158,10 +158,17 @@ private void init() {
}
@VisibleForTesting
- protected RequestInterceptorChainWrapper getInterceptorChain() {
+ protected RequestInterceptorChainWrapper getInterceptorChain(
+ HttpServletRequest hsr) {
String user = "";
+ if (hsr != null) {
+ user = hsr.getRemoteUser();
+ }
try {
- user = UserGroupInformation.getCurrentUser().getUserName();
+ if (user == null || user.equals("")) {
+ // Yarn Router user
+ user = UserGroupInformation.getCurrentUser().getUserName();
+ }
} catch (IOException e) {
LOG.error("IOException " + e.getMessage());
}
@@ -316,7 +323,7 @@ public ClusterInfo get() {
@Override
public ClusterInfo getClusterInfo() {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getClusterInfo();
}
@@ -327,7 +334,7 @@ public ClusterInfo getClusterInfo() {
@Override
public ClusterMetricsInfo getClusterMetricsInfo() {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getClusterMetricsInfo();
}
@@ -338,7 +345,7 @@ public ClusterMetricsInfo getClusterMetricsInfo() {
@Override
public SchedulerTypeInfo getSchedulerInfo() {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getSchedulerInfo();
}
@@ -350,7 +357,7 @@ public SchedulerTypeInfo getSchedulerInfo() {
public String dumpSchedulerLogs(@FormParam(RMWSConsts.TIME) String time,
@Context HttpServletRequest hsr) throws IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().dumpSchedulerLogs(time, hsr);
}
@@ -361,7 +368,7 @@ public String dumpSchedulerLogs(@FormParam(RMWSConsts.TIME) String time,
@Override
public NodesInfo getNodes(@QueryParam(RMWSConsts.STATES) String states) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getNodes(states);
}
@@ -372,7 +379,7 @@ public NodesInfo getNodes(@QueryParam(RMWSConsts.STATES) String states) {
@Override
public NodeInfo getNode(@PathParam(RMWSConsts.NODEID) String nodeId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getNode(nodeId);
}
@@ -396,7 +403,7 @@ public AppsInfo getApps(@Context HttpServletRequest hsr,
@QueryParam(RMWSConsts.APPLICATION_TAGS) Set applicationTags,
@QueryParam(RMWSConsts.DESELECTS) Set unselectedFields) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getApps(hsr, stateQuery, statesQuery,
finalStatusQuery, userQuery, queueQuery, count, startedBegin,
startedEnd, finishBegin, finishEnd, applicationTypes, applicationTags,
@@ -411,7 +418,7 @@ public AppsInfo getApps(@Context HttpServletRequest hsr,
public ActivitiesInfo getActivities(@Context HttpServletRequest hsr,
@QueryParam(RMWSConsts.NODEID) String nodeId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getActivities(hsr, nodeId);
}
@@ -424,7 +431,7 @@ public AppActivitiesInfo getAppActivities(@Context HttpServletRequest hsr,
@QueryParam(RMWSConsts.APP_ID) String appId,
@QueryParam(RMWSConsts.MAX_TIME) String time) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppActivities(hsr, appId, time);
}
@@ -438,7 +445,7 @@ public ApplicationStatisticsInfo getAppStatistics(
@QueryParam(RMWSConsts.STATES) Set stateQueries,
@QueryParam(RMWSConsts.APPLICATION_TYPES) Set typeQueries) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppStatistics(hsr, stateQueries,
typeQueries);
}
@@ -452,7 +459,7 @@ public AppInfo getApp(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId,
@QueryParam(RMWSConsts.DESELECTS) Set unselectedFields) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getApp(hsr, appId, unselectedFields);
}
@@ -464,7 +471,7 @@ public AppInfo getApp(@Context HttpServletRequest hsr,
public AppState getAppState(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppState(hsr, appId);
}
@@ -478,7 +485,7 @@ public Response updateAppState(AppState targetState,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException,
YarnException, InterruptedException, IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().updateAppState(targetState, hsr,
appId);
}
@@ -491,7 +498,7 @@ public Response updateAppState(AppState targetState,
public NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr)
throws IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getNodeToLabels(hsr);
}
@@ -503,7 +510,7 @@ public NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr)
public LabelsToNodesInfo getLabelsToNodes(
@QueryParam(RMWSConsts.LABELS) Set labels) throws IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(null);
return pipeline.getRootInterceptor().getLabelsToNodes(labels);
}
@@ -516,7 +523,7 @@ public Response replaceLabelsOnNodes(
final NodeToLabelsEntryList newNodeToLabels,
@Context HttpServletRequest hsr) throws Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().replaceLabelsOnNodes(newNodeToLabels,
hsr);
}
@@ -531,7 +538,7 @@ public Response replaceLabelsOnNode(
@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.NODEID) String nodeId) throws Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().replaceLabelsOnNode(newNodeLabelsName,
hsr, nodeId);
}
@@ -544,7 +551,7 @@ public Response replaceLabelsOnNode(
public NodeLabelsInfo getClusterNodeLabels(@Context HttpServletRequest hsr)
throws IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getClusterNodeLabels(hsr);
}
@@ -556,7 +563,7 @@ public NodeLabelsInfo getClusterNodeLabels(@Context HttpServletRequest hsr)
public Response addToClusterNodeLabels(NodeLabelsInfo newNodeLabels,
@Context HttpServletRequest hsr) throws Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().addToClusterNodeLabels(newNodeLabels,
hsr);
}
@@ -570,7 +577,7 @@ public Response removeFromCluserNodeLabels(
@QueryParam(RMWSConsts.LABELS) Set oldNodeLabels,
@Context HttpServletRequest hsr) throws Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor()
.removeFromCluserNodeLabels(oldNodeLabels, hsr);
}
@@ -583,7 +590,7 @@ public Response removeFromCluserNodeLabels(
public NodeLabelsInfo getLabelsOnNode(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.NODEID) String nodeId) throws IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getLabelsOnNode(hsr, nodeId);
}
@@ -595,7 +602,7 @@ public NodeLabelsInfo getLabelsOnNode(@Context HttpServletRequest hsr,
public AppPriority getAppPriority(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppPriority(hsr, appId);
}
@@ -609,7 +616,7 @@ public Response updateApplicationPriority(AppPriority targetPriority,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException,
YarnException, InterruptedException, IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor()
.updateApplicationPriority(targetPriority, hsr, appId);
}
@@ -622,7 +629,7 @@ public Response updateApplicationPriority(AppPriority targetPriority,
public AppQueue getAppQueue(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppQueue(hsr, appId);
}
@@ -636,7 +643,7 @@ public Response updateAppQueue(AppQueue targetQueue,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException,
YarnException, InterruptedException, IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().updateAppQueue(targetQueue, hsr,
appId);
}
@@ -649,7 +656,7 @@ public Response updateAppQueue(AppQueue targetQueue,
public Response createNewApplication(@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().createNewApplication(hsr);
}
@@ -662,7 +669,7 @@ public Response submitApplication(ApplicationSubmissionContextInfo newApp,
@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().submitApplication(newApp, hsr);
}
@@ -675,7 +682,7 @@ public Response postDelegationToken(DelegationToken tokenData,
@Context HttpServletRequest hsr) throws AuthorizationException,
IOException, InterruptedException, Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().postDelegationToken(tokenData, hsr);
}
@@ -687,7 +694,7 @@ public Response postDelegationToken(DelegationToken tokenData,
public Response postDelegationTokenExpiration(@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().postDelegationTokenExpiration(hsr);
}
@@ -700,7 +707,7 @@ public Response cancelDelegationToken(@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException,
Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().cancelDelegationToken(hsr);
}
@@ -712,7 +719,7 @@ public Response cancelDelegationToken(@Context HttpServletRequest hsr)
public Response createNewReservation(@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().createNewReservation(hsr);
}
@@ -725,7 +732,7 @@ public Response submitReservation(ReservationSubmissionRequestInfo resContext,
@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().submitReservation(resContext, hsr);
}
@@ -738,7 +745,7 @@ public Response updateReservation(ReservationUpdateRequestInfo resContext,
@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().updateReservation(resContext, hsr);
}
@@ -751,7 +758,7 @@ public Response deleteReservation(ReservationDeleteRequestInfo resContext,
@Context HttpServletRequest hsr)
throws AuthorizationException, IOException, InterruptedException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().deleteReservation(resContext, hsr);
}
@@ -768,7 +775,7 @@ public Response listReservation(
@QueryParam(RMWSConsts.INCLUDE_RESOURCE) @DefaultValue(DEFAULT_INCLUDE_RESOURCE) boolean includeResourceAllocations,
@Context HttpServletRequest hsr) throws Exception {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().listReservation(queue, reservationId,
startTime, endTime, includeResourceAllocations, hsr);
}
@@ -782,7 +789,7 @@ public AppTimeoutInfo getAppTimeout(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId,
@PathParam(RMWSConsts.TYPE) String type) throws AuthorizationException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppTimeout(hsr, appId, type);
}
@@ -794,7 +801,7 @@ public AppTimeoutInfo getAppTimeout(@Context HttpServletRequest hsr,
public AppTimeoutsInfo getAppTimeouts(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppTimeouts(hsr, appId);
}
@@ -808,7 +815,7 @@ public Response updateApplicationTimeout(AppTimeoutInfo appTimeout,
@PathParam(RMWSConsts.APPID) String appId) throws AuthorizationException,
YarnException, InterruptedException, IOException {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().updateApplicationTimeout(appTimeout,
hsr, appId);
}
@@ -821,7 +828,7 @@ public Response updateApplicationTimeout(AppTimeoutInfo appTimeout,
public AppAttemptsInfo getAppAttempts(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(hsr);
return pipeline.getRootInterceptor().getAppAttempts(hsr, appId);
}
@@ -834,7 +841,7 @@ public AppAttemptsInfo getAppAttempts(@Context HttpServletRequest hsr,
@PathParam(RMWSConsts.APPID) String appId,
@PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(req);
return pipeline.getRootInterceptor().getAppAttempt(req, res, appId,
appAttemptId);
}
@@ -848,7 +855,7 @@ public ContainersInfo getContainers(@Context HttpServletRequest req,
@PathParam(RMWSConsts.APPID) String appId,
@PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(req);
return pipeline.getRootInterceptor().getContainers(req, res, appId,
appAttemptId);
}
@@ -863,7 +870,7 @@ public ContainerInfo getContainer(@Context HttpServletRequest req,
@PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId,
@PathParam(RMWSConsts.CONTAINERID) String containerId) {
init();
- RequestInterceptorChainWrapper pipeline = getInterceptorChain();
+ RequestInterceptorChainWrapper pipeline = getInterceptorChain(req);
return pipeline.getRootInterceptor().getContainer(req, res, appId,
appAttemptId, containerId);
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/BaseRouterWebServicesTest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/BaseRouterWebServicesTest.java
index 7d420844a42..99b2fbc584b 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/BaseRouterWebServicesTest.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/BaseRouterWebServicesTest.java
@@ -20,15 +20,15 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import java.io.IOException;
-import java.security.PrivilegedExceptionAction;
+import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AuthorizationException;
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.YarnException;
@@ -128,487 +128,263 @@ protected RouterWebServices getRouterWebServices() {
protected ClusterInfo get(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ClusterInfo run() throws Exception {
- return routerWebService.get();
- }
- });
+ // HSR is not used here
+ return routerWebService.get();
}
protected ClusterInfo getClusterInfo(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ClusterInfo run() throws Exception {
- return routerWebService.getClusterInfo();
- }
- });
+ // HSR is not used here
+ return routerWebService.getClusterInfo();
}
protected ClusterMetricsInfo getClusterMetricsInfo(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ClusterMetricsInfo run() throws Exception {
- return routerWebService.getClusterMetricsInfo();
- }
- });
+ // HSR is not used here
+ return routerWebService.getClusterMetricsInfo();
}
protected SchedulerTypeInfo getSchedulerInfo(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public SchedulerTypeInfo run() throws Exception {
- return routerWebService.getSchedulerInfo();
- }
- });
+ // HSR is not used here
+ return routerWebService.getSchedulerInfo();
}
protected String dumpSchedulerLogs(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public String run() throws Exception {
- return routerWebService.dumpSchedulerLogs(null, null);
- }
- });
+ return routerWebService.dumpSchedulerLogs(null,
+ createHttpServletRequest(user));
}
protected NodesInfo getNodes(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public NodesInfo run() throws Exception {
- return routerWebService.getNodes(null);
- }
- });
+ return routerWebService.getNodes(null);
}
protected NodeInfo getNode(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public NodeInfo run() throws Exception {
- return routerWebService.getNode(null);
- }
- });
+ return routerWebService.getNode(null);
}
protected AppsInfo getApps(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppsInfo run() throws Exception {
- return routerWebService.getApps(null, null, null, null, null, null,
- null, null, null, null, null, null, null, null);
- }
- });
+ return routerWebService.getApps(createHttpServletRequest(user), null, null,
+ null, null, null, null, null, null, null, null, null, null, null);
}
protected ActivitiesInfo getActivities(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ActivitiesInfo run() throws Exception {
- return routerWebService.getActivities(null, null);
- }
- });
+ return routerWebService.getActivities(
+ createHttpServletRequest(user), null);
}
protected AppActivitiesInfo getAppActivities(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppActivitiesInfo run() throws Exception {
- return routerWebService.getAppActivities(null, null, null);
- }
- });
+ return routerWebService.getAppActivities(createHttpServletRequest(user),
+ null, null);
}
protected ApplicationStatisticsInfo getAppStatistics(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ApplicationStatisticsInfo run() throws Exception {
- return routerWebService.getAppStatistics(null, null, null);
- }
- });
+ return routerWebService.getAppStatistics(createHttpServletRequest(user),
+ null, null);
}
protected AppInfo getApp(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppInfo run() throws Exception {
- return routerWebService.getApp(null, null, null);
- }
- });
+ return routerWebService.getApp(createHttpServletRequest(user), null, null);
}
protected AppState getAppState(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppState run() throws Exception {
- return routerWebService.getAppState(null, null);
- }
- });
+ return routerWebService.getAppState(createHttpServletRequest(user), null);
}
protected Response updateAppState(String user) throws AuthorizationException,
YarnException, InterruptedException, IOException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.updateAppState(null, null, null);
- }
- });
+ return routerWebService.updateAppState(null, createHttpServletRequest(user),
+ null);
}
protected NodeToLabelsInfo getNodeToLabels(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public NodeToLabelsInfo run() throws Exception {
- return routerWebService.getNodeToLabels(null);
- }
- });
+ return routerWebService.getNodeToLabels(createHttpServletRequest(user));
}
protected LabelsToNodesInfo getLabelsToNodes(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public LabelsToNodesInfo run() throws Exception {
- return routerWebService.getLabelsToNodes(null);
- }
- });
+ return routerWebService.getLabelsToNodes(null);
}
protected Response replaceLabelsOnNodes(String user) throws Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.replaceLabelsOnNodes(null, null);
- }
- });
+ return routerWebService.replaceLabelsOnNode(null,
+ createHttpServletRequest(user), null);
}
protected Response replaceLabelsOnNode(String user) throws Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.replaceLabelsOnNode(null, null, null);
- }
- });
+ return routerWebService.replaceLabelsOnNode(null,
+ createHttpServletRequest(user), null);
}
protected NodeLabelsInfo getClusterNodeLabels(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public NodeLabelsInfo run() throws Exception {
- return routerWebService.getClusterNodeLabels(null);
- }
- });
+ return routerWebService
+ .getClusterNodeLabels(createHttpServletRequest(user));
}
protected Response addToClusterNodeLabels(String user) throws Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.addToClusterNodeLabels(null, null);
- }
- });
+ return routerWebService.addToClusterNodeLabels(null,
+ createHttpServletRequest(user));
}
protected Response removeFromCluserNodeLabels(String user) throws Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.removeFromCluserNodeLabels(null, null);
- }
- });
+ return routerWebService.removeFromCluserNodeLabels(null,
+ createHttpServletRequest(user));
}
protected NodeLabelsInfo getLabelsOnNode(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public NodeLabelsInfo run() throws Exception {
- return routerWebService.getLabelsOnNode(null, null);
- }
- });
+ return routerWebService.getLabelsOnNode(createHttpServletRequest(user),
+ null);
}
protected AppPriority getAppPriority(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppPriority run() throws Exception {
- return routerWebService.getAppPriority(null, null);
- }
- });
+ return routerWebService.getAppPriority(createHttpServletRequest(user),
+ null);
}
protected Response updateApplicationPriority(String user)
throws AuthorizationException, YarnException, InterruptedException,
IOException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.updateApplicationPriority(null, null, null);
- }
- });
+ return routerWebService.updateApplicationPriority(null,
+ createHttpServletRequest(user), null);
}
protected AppQueue getAppQueue(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppQueue run() throws Exception {
- return routerWebService.getAppQueue(null, null);
- }
- });
+ return routerWebService.getAppQueue(createHttpServletRequest(user), null);
}
protected Response updateAppQueue(String user) throws AuthorizationException,
YarnException, InterruptedException, IOException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.updateAppQueue(null, null, null);
- }
- });
+ return routerWebService.updateAppQueue(null, createHttpServletRequest(user),
+ null);
}
protected Response createNewApplication(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.createNewApplication(null);
- }
- });
+ return routerWebService
+ .createNewApplication(createHttpServletRequest(user));
}
protected Response submitApplication(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.submitApplication(null, null);
- }
- });
+ return routerWebService.submitApplication(null,
+ createHttpServletRequest(user));
}
protected Response postDelegationToken(String user)
throws AuthorizationException, IOException, InterruptedException,
Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.postDelegationToken(null, null);
- }
- });
+ return routerWebService.postDelegationToken(null,
+ createHttpServletRequest(user));
}
protected Response postDelegationTokenExpiration(String user)
throws AuthorizationException, IOException, Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.postDelegationTokenExpiration(null);
- }
- });
+ return routerWebService
+ .postDelegationTokenExpiration(createHttpServletRequest(user));
}
protected Response cancelDelegationToken(String user)
throws AuthorizationException, IOException, InterruptedException,
Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.cancelDelegationToken(null);
- }
- });
+ return routerWebService
+ .cancelDelegationToken(createHttpServletRequest(user));
}
protected Response createNewReservation(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.createNewReservation(null);
- }
- });
+ return routerWebService
+ .createNewReservation(createHttpServletRequest(user));
}
protected Response submitReservation(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.submitReservation(null, null);
- }
- });
+ return routerWebService.submitReservation(null,
+ createHttpServletRequest(user));
}
protected Response updateReservation(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.updateReservation(null, null);
- }
- });
+ return routerWebService.updateReservation(null,
+ createHttpServletRequest(user));
}
protected Response deleteReservation(String user)
throws AuthorizationException, IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.deleteReservation(null, null);
- }
- });
+ return routerWebService.deleteReservation(null,
+ createHttpServletRequest(user));
}
protected Response listReservation(String user) throws Exception {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.listReservation(null, null, 0, 0, false,
- null);
- }
- });
+ return routerWebService.listReservation(null, null, 0, 0, false,
+ createHttpServletRequest(user));
}
protected AppTimeoutInfo getAppTimeout(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppTimeoutInfo run() throws Exception {
- return routerWebService.getAppTimeout(null, null, null);
- }
- });
+ return routerWebService.getAppTimeout(createHttpServletRequest(user), null,
+ null);
}
protected AppTimeoutsInfo getAppTimeouts(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppTimeoutsInfo run() throws Exception {
- return routerWebService.getAppTimeouts(null, null);
- }
- });
+ return routerWebService.getAppTimeouts(createHttpServletRequest(user),
+ null);
}
protected Response updateApplicationTimeout(String user)
throws AuthorizationException, YarnException, InterruptedException,
IOException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public Response run() throws Exception {
- return routerWebService.updateApplicationTimeout(null, null, null);
- }
- });
+ return routerWebService.updateApplicationTimeout(null,
+ createHttpServletRequest(user), null);
}
protected AppAttemptsInfo getAppAttempts(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppAttemptsInfo run() throws Exception {
- return routerWebService.getAppAttempts(null, null);
- }
- });
+ return routerWebService.getAppAttempts(createHttpServletRequest(user),
+ null);
}
protected AppAttemptInfo getAppAttempt(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public AppAttemptInfo run() throws Exception {
- return routerWebService.getAppAttempt(null, null, null, null);
- }
- });
+ return routerWebService.getAppAttempt(createHttpServletRequest(user), null,
+ null, null);
}
protected ContainersInfo getContainers(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ContainersInfo run() throws Exception {
- return routerWebService.getContainers(null, null, null, null);
- }
- });
+ return routerWebService.getContainers(createHttpServletRequest(user), null,
+ null, null);
}
protected ContainerInfo getContainer(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public ContainerInfo run() throws Exception {
- return routerWebService.getContainer(null, null, null, null, null);
- }
- });
+ return routerWebService.getContainer(createHttpServletRequest(user), null,
+ null, null, null);
}
protected RequestInterceptorChainWrapper getInterceptorChain(String user)
throws IOException, InterruptedException {
- return UserGroupInformation.createRemoteUser(user)
- .doAs(new PrivilegedExceptionAction() {
- @Override
- public RequestInterceptorChainWrapper run() throws Exception {
- return routerWebService.getInterceptorChain();
- }
- });
+ HttpServletRequest request = createHttpServletRequest(user);
+ return routerWebService.getInterceptorChain(request);
}
+ private HttpServletRequest createHttpServletRequest(String user) {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getRemoteUser()).thenReturn(user);
+ return request;
+ }
}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/Federation.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/Federation.md
index 8a6c1371926..ef0f7131fd8 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/Federation.md
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/Federation.md
@@ -59,6 +59,7 @@ URL and redirects the application submission request to the appropriate sub-clus
The Router exposes the ApplicationClientProtocol to the outside world, transparently hiding the presence of multiple RMs. To achieve this the Router also persists the mapping
between the application and its home sub-cluster into the State Store. This allows Routers to be soft-state while supporting user requests cheaply, as any Router can recover
this application to home sub-cluster mapping and direct requests to the right RM without broadcasting them. For performance caching and session stickiness might be advisable.
+The state of the federation (including applications and nodes) is exposed through the Web UI.
###AMRMProxy
The AMRMProxy is a key component to allow the application to scale and run across sub-clusters. The AMRMProxy runs on all the NM machines and acts as a proxy to the
@@ -246,9 +247,9 @@ Optional:
|:---- |:---- |
|`yarn.router.hostname` | `0.0.0.0` | Router host name.
|`yarn.router.clientrm.address` | `0.0.0.0:8050` | Router client address. |
-|`yarn.router.webapp.address` | `0.0.0.0:80` | Webapp address at the router. |
+|`yarn.router.webapp.address` | `0.0.0.0:8089` | Webapp address at the router. |
|`yarn.router.admin.address` | `0.0.0.0:8052` | Admin address at the router. |
-|`yarn.router.webapp.https.address` | `0.0.0.0:443` | Secure webapp address at the router. |
+|`yarn.router.webapp.https.address` | `0.0.0.0:8091` | Secure webapp address at the router. |
|`yarn.router.submit.retry` | `3` | The number of retries in the router before we give up. |
|`yarn.federation.statestore.max-connections` | `10` | This is the maximum number of parallel connections each Router makes to the state-store. |
|`yarn.federation.cache-ttl.secs` | `60` | The Router caches informations, and this is the time to leave before the cache is invalidated. |
@@ -306,4 +307,5 @@ The output from this particular example job should be something like:
Job Finished in 30.586 seconds
Estimated value of Pi is 3.14250000......
+The state of the job can also be tracked on the Router Web UI at `routerhost:8089`.
Note that no change in the code or recompilation of the input jar was required to use federation. Also, the output of this job is the exact same as it would be when run without federation. Also, in order to get the full benefit of federation, use a large enough number of mappers such that more than one cluster is required. That number happens to be 16 in the case of the above example.