MAPREDUCE-2738. svn merge -c r1179229 --ignore-ancestry ../../trunk/
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1179232 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
763327fd51
commit
90674a233a
|
@ -319,6 +319,9 @@ Release 0.23.0 - Unreleased
|
||||||
the outputs of tasks from a crashed job so as to support MR Application
|
the outputs of tasks from a crashed job so as to support MR Application
|
||||||
Master recovery. (Sharad Agarwal and Arun C Murthy via vinodkv)
|
Master recovery. (Sharad Agarwal and Arun C Murthy via vinodkv)
|
||||||
|
|
||||||
|
MAPREDUCE-2738. Added the missing cluster level statisticss on the RM web
|
||||||
|
UI. (Robert Joseph Evans via vinodkv)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
MAPREDUCE-2026. Make JobTracker.getJobCounters() and
|
MAPREDUCE-2026. Make JobTracker.getJobCounters() and
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class QueueMetrics {
|
||||||
"Metrics for queue: " + queueName, metrics);
|
"Metrics for queue: " + queueName, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized QueueMetrics getUserMetrics(String userName) {
|
public synchronized QueueMetrics getUserMetrics(String userName) {
|
||||||
if (users == null) {
|
if (users == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,8 @@ public interface YarnScheduler extends EventHandler<SchedulerEvent> {
|
||||||
/**
|
/**
|
||||||
* Get node resource usage report.
|
* Get node resource usage report.
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
* @return the {@link SchedulerNodeReport} for the node
|
* @return the {@link SchedulerNodeReport} for the node or null
|
||||||
|
* if nodeId does not point to a defined node.
|
||||||
*/
|
*/
|
||||||
@LimitedPrivate("yarn")
|
@LimitedPrivate("yarn")
|
||||||
@Stable
|
@Stable
|
||||||
|
|
|
@ -173,14 +173,6 @@ public class FifoScheduler implements ResourceScheduler {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public synchronized Resource getUsedResource(NodeId nodeId) {
|
|
||||||
return getNode(nodeId).getUsedResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Resource getAvailableResource(NodeId nodeId) {
|
|
||||||
return getNode(nodeId).getAvailableResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Resource getMinimumResourceCapability() {
|
public Resource getMinimumResourceCapability() {
|
||||||
return minimumAllocation;
|
return minimumAllocation;
|
||||||
|
@ -718,6 +710,9 @@ public class FifoScheduler implements ResourceScheduler {
|
||||||
|
|
||||||
// Inform the node
|
// Inform the node
|
||||||
node.releaseContainer(container);
|
node.releaseContainer(container);
|
||||||
|
|
||||||
|
// Update total usage
|
||||||
|
Resources.subtractFrom(usedResource, container.getResource());
|
||||||
|
|
||||||
LOG.info("Application " + applicationAttemptId +
|
LOG.info("Application " + applicationAttemptId +
|
||||||
" released container " + container.getId() +
|
" released container " + container.getId() +
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import org.apache.hadoop.util.VersionInfo;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
|
import org.apache.hadoop.yarn.util.Times;
|
||||||
|
import org.apache.hadoop.yarn.util.YarnVersionInfo;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
public class AboutBlock extends HtmlBlock {
|
||||||
|
final ResourceManager rm;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AboutBlock(ResourceManager rm, ViewContext ctx) {
|
||||||
|
super(ctx);
|
||||||
|
this.rm = rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(Block html) {
|
||||||
|
html._(MetricsOverviewTable.class);
|
||||||
|
long ts = ResourceManager.clusterTimeStamp;
|
||||||
|
ResourceManager rm = getInstance(ResourceManager.class);
|
||||||
|
info("Cluster overview").
|
||||||
|
_("Cluster ID:", ts).
|
||||||
|
_("ResourceManager state:", rm.getServiceState()).
|
||||||
|
_("ResourceManager started on:", Times.format(ts)).
|
||||||
|
_("ResourceManager version:", YarnVersionInfo.getBuildVersion() +
|
||||||
|
" on " + YarnVersionInfo.getDate()).
|
||||||
|
_("Hadoop version:", VersionInfo.getBuildVersion() +
|
||||||
|
" on " + VersionInfo.getDate());
|
||||||
|
html._(InfoBlock.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,15 +19,14 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.webapp.SubView;
|
import org.apache.hadoop.yarn.webapp.SubView;
|
||||||
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
|
||||||
|
|
||||||
public class InfoPage extends RmView {
|
public class AboutPage extends RmView {
|
||||||
|
|
||||||
@Override protected void preHead(Page.HTML<_> html) {
|
@Override protected void preHead(Page.HTML<_> html) {
|
||||||
commonPreHead(html);
|
commonPreHead(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected Class<? extends SubView> content() {
|
@Override protected Class<? extends SubView> content() {
|
||||||
return InfoBlock.class;
|
return AboutBlock.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a block for the applications with metrics information.
|
||||||
|
*/
|
||||||
|
class AppsBlockWithMetrics extends HtmlBlock {
|
||||||
|
@Override public void render(Block html) {
|
||||||
|
html._(MetricsOverviewTable.class);
|
||||||
|
html._(AppsBlock.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
|
||||||
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.*;
|
import static org.apache.hadoop.yarn.util.StringHelper.*;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
|
|
||||||
|
|
||||||
class CapacitySchedulerPage extends RmView {
|
class CapacitySchedulerPage extends RmView {
|
||||||
static final String _Q = ".ui-state-default.ui-corner-all";
|
static final String _Q = ".ui-state-default.ui-corner-all";
|
||||||
|
@ -96,6 +95,7 @@ class CapacitySchedulerPage extends RmView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Block html) {
|
public void render(Block html) {
|
||||||
|
html._(MetricsOverviewTable.class);
|
||||||
UL<DIV<DIV<Hamlet>>> ul = html.
|
UL<DIV<DIV<Hamlet>>> ul = html.
|
||||||
div("#cs-wrapper.ui-widget").
|
div("#cs-wrapper.ui-widget").
|
||||||
div(".ui-widget-header.ui-corner-top").
|
div(".ui-widget-header.ui-corner-top").
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.servlet.RequestScoped;
|
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
|
||||||
|
@ -35,7 +34,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||||
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.*;
|
import static org.apache.hadoop.yarn.util.StringHelper.*;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
|
|
||||||
|
|
||||||
class DefaultSchedulerPage extends RmView {
|
class DefaultSchedulerPage extends RmView {
|
||||||
static final String _Q = ".ui-state-default.ui-corner-all";
|
static final String _Q = ".ui-state-default.ui-corner-all";
|
||||||
|
@ -76,8 +74,9 @@ class DefaultSchedulerPage extends RmView {
|
||||||
int nodeContainers = 0;
|
int nodeContainers = 0;
|
||||||
|
|
||||||
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
||||||
usedNodeMem += fs.getUsedResource(ni.getNodeID()).getMemory();
|
SchedulerNodeReport report = fs.getNodeReport(ni.getNodeID());
|
||||||
availNodeMem += fs.getAvailableResource(ni.getNodeID()).getMemory();
|
usedNodeMem += report.getUsedResource().getMemory();
|
||||||
|
availNodeMem += report.getAvailableResource().getMemory();
|
||||||
totNodeMem += ni.getTotalCapability().getMemory();
|
totNodeMem += ni.getTotalCapability().getMemory();
|
||||||
nodeContainers += fs.getNodeReport(ni.getNodeID()).getNumContainers();
|
nodeContainers += fs.getNodeReport(ni.getNodeID()).getNumContainers();
|
||||||
}
|
}
|
||||||
|
@ -109,6 +108,7 @@ class DefaultSchedulerPage extends RmView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Block html) {
|
public void render(Block html) {
|
||||||
|
html._(MetricsOverviewTable.class);
|
||||||
UL<DIV<DIV<Hamlet>>> ul = html.
|
UL<DIV<DIV<Hamlet>>> ul = html.
|
||||||
div("#cs-wrapper.ui-widget").
|
div("#cs-wrapper.ui-widget").
|
||||||
div(".ui-widget-header.ui-corner-top").
|
div(".ui-widget-header.ui-corner-top").
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import org.apache.hadoop.util.StringUtils;
|
||||||
|
import org.apache.hadoop.yarn.api.records.NodeId;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||||
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an table with an overview of many cluster wide metrics and if
|
||||||
|
* per user metrics are enabled it will show an overview of what the
|
||||||
|
* current user is using on the cluster.
|
||||||
|
*/
|
||||||
|
public class MetricsOverviewTable extends HtmlBlock {
|
||||||
|
private static final long BYTES_IN_GB = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
|
private final RMContext rmContext;
|
||||||
|
private final ResourceManager rm;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MetricsOverviewTable(RMContext context, ResourceManager rm, ViewContext ctx) {
|
||||||
|
super(ctx);
|
||||||
|
this.rmContext = context;
|
||||||
|
this.rm = rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(Block html) {
|
||||||
|
//Yes this is a hack, but there is no other way to insert
|
||||||
|
//CSS in the correct spot
|
||||||
|
html.style(".metrics {margin-bottom:5px}");
|
||||||
|
|
||||||
|
ResourceScheduler rs = rm.getResourceScheduler();
|
||||||
|
QueueMetrics metrics = rs.getRootQueueMetrics();
|
||||||
|
|
||||||
|
int appsSubmitted = metrics.getAppsSubmitted();
|
||||||
|
int reservedGB = metrics.getReservedGB();
|
||||||
|
int availableGB = metrics.getAvailableGB();
|
||||||
|
int allocatedGB = metrics.getAllocatedGB();
|
||||||
|
int containersAllocated = metrics.getAllocatedContainers();
|
||||||
|
int totalGB = availableGB + reservedGB + allocatedGB;
|
||||||
|
|
||||||
|
ConcurrentMap<NodeId,RMNode> nodes = rmContext.getRMNodes();
|
||||||
|
int totalNodes = nodes.size();
|
||||||
|
int lostNodes = 0;
|
||||||
|
int unhealthyNodes = 0;
|
||||||
|
int decommissionedNodes = 0;
|
||||||
|
for(RMNode node: nodes.values()) {
|
||||||
|
if(node == null || node.getState() == null) {
|
||||||
|
lostNodes++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(node.getState()) {
|
||||||
|
case DECOMMISSIONED:
|
||||||
|
decommissionedNodes++;
|
||||||
|
break;
|
||||||
|
case LOST:
|
||||||
|
lostNodes++;
|
||||||
|
break;
|
||||||
|
case UNHEALTHY:
|
||||||
|
unhealthyNodes++;
|
||||||
|
break;
|
||||||
|
//RUNNING noop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DIV<Hamlet> div = html.div().$class("metrics");
|
||||||
|
|
||||||
|
div.table("#metricsoverview").
|
||||||
|
thead().$class("ui-widget-header").
|
||||||
|
tr().
|
||||||
|
th().$class("ui-state-default")._("Apps Submitted")._().
|
||||||
|
th().$class("ui-state-default")._("Containers Running")._().
|
||||||
|
th().$class("ui-state-default")._("Memory Used")._().
|
||||||
|
th().$class("ui-state-default")._("Memopry Total")._().
|
||||||
|
th().$class("ui-state-default")._("Memory Reserved")._().
|
||||||
|
th().$class("ui-state-default")._("Total Nodes")._().
|
||||||
|
th().$class("ui-state-default")._("Decommissioned Nodes")._().
|
||||||
|
th().$class("ui-state-default")._("Lost Nodes")._().
|
||||||
|
th().$class("ui-state-default")._("Unhealthy Nodes")._().
|
||||||
|
_().
|
||||||
|
_().
|
||||||
|
tbody().$class("ui-widget-content").
|
||||||
|
tr().
|
||||||
|
td(String.valueOf(appsSubmitted)).
|
||||||
|
td(String.valueOf(containersAllocated)).
|
||||||
|
td(StringUtils.byteDesc(allocatedGB * BYTES_IN_GB)).
|
||||||
|
td(StringUtils.byteDesc(totalGB * BYTES_IN_GB)).
|
||||||
|
td(StringUtils.byteDesc(reservedGB * BYTES_IN_GB)).
|
||||||
|
td().a(url("nodes"),String.valueOf(totalNodes))._().
|
||||||
|
td().a(url("nodes/DECOMMISSIONED"),String.valueOf(decommissionedNodes))._().
|
||||||
|
td().a(url("nodes/LOST"),String.valueOf(lostNodes))._().
|
||||||
|
td().a(url("nodes/UNHEALTHY"),String.valueOf(unhealthyNodes))._().
|
||||||
|
_().
|
||||||
|
_()._();
|
||||||
|
|
||||||
|
String user = request().getRemoteUser();
|
||||||
|
if (user != null) {
|
||||||
|
QueueMetrics userMetrics = metrics.getUserMetrics(user);
|
||||||
|
if(userMetrics != null) {
|
||||||
|
int myAppsSubmitted = userMetrics.getAppsSubmitted();
|
||||||
|
int myRunningContainers = userMetrics.getAllocatedContainers();
|
||||||
|
int myPendingContainers = userMetrics.getPendingContainers();
|
||||||
|
int myReservedContainers = userMetrics.getReservedContainers();
|
||||||
|
int myReservedGB = userMetrics.getReservedGB();
|
||||||
|
int myPendingGB = userMetrics.getPendingGB();
|
||||||
|
int myAllocatedGB = userMetrics.getAllocatedGB();
|
||||||
|
div.table("#usermetricsoverview").
|
||||||
|
thead().$class("ui-widget-header").
|
||||||
|
tr().
|
||||||
|
th().$class("ui-state-default")._("Apps Submitted ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Containers Running ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Containers Pending ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Containers Reserved ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Memory Used ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Memory Pending ("+user+")")._().
|
||||||
|
th().$class("ui-state-default")._("Memory Reserved ("+user+")")._().
|
||||||
|
_().
|
||||||
|
_().
|
||||||
|
tbody().$class("ui-widget-content").
|
||||||
|
tr().
|
||||||
|
td(String.valueOf(myAppsSubmitted)).
|
||||||
|
td(String.valueOf(myRunningContainers)).
|
||||||
|
td(String.valueOf(myPendingContainers)).
|
||||||
|
td(String.valueOf(myReservedContainers)).
|
||||||
|
td(StringUtils.byteDesc(myAllocatedGB * BYTES_IN_GB)).
|
||||||
|
td(StringUtils.byteDesc(myPendingGB * BYTES_IN_GB)).
|
||||||
|
td(StringUtils.byteDesc(myReservedGB * BYTES_IN_GB)).
|
||||||
|
_().
|
||||||
|
_()._();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div._();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,21 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.NODE_STATE;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
|
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.DATATABLES_ID;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
|
||||||
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
|
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
|
||||||
|
|
||||||
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
|
import org.apache.hadoop.yarn.api.records.NodeHealthStatus;
|
||||||
|
import org.apache.hadoop.yarn.api.records.NodeId;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeState;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerNodeReport;
|
||||||
import org.apache.hadoop.yarn.util.Times;
|
import org.apache.hadoop.yarn.util.Times;
|
||||||
import org.apache.hadoop.yarn.webapp.SubView;
|
import org.apache.hadoop.yarn.webapp.SubView;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
|
||||||
|
@ -38,45 +45,75 @@ import com.google.inject.Inject;
|
||||||
class NodesPage extends RmView {
|
class NodesPage extends RmView {
|
||||||
|
|
||||||
static class NodesBlock extends HtmlBlock {
|
static class NodesBlock extends HtmlBlock {
|
||||||
|
private static final long BYTES_IN_MB = 1024 * 1024;
|
||||||
final RMContext rmContext;
|
final RMContext rmContext;
|
||||||
|
final ResourceManager rm;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NodesBlock(RMContext context, ViewContext ctx) {
|
NodesBlock(RMContext context, ResourceManager rm, ViewContext ctx) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
this.rmContext = context;
|
this.rmContext = context;
|
||||||
|
this.rm = rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void render(Block html) {
|
protected void render(Block html) {
|
||||||
|
html._(MetricsOverviewTable.class);
|
||||||
|
|
||||||
|
ResourceScheduler sched = rm.getResourceScheduler();
|
||||||
|
String type = $(NODE_STATE);
|
||||||
TBODY<TABLE<Hamlet>> tbody = html.table("#nodes").
|
TBODY<TABLE<Hamlet>> tbody = html.table("#nodes").
|
||||||
thead().
|
thead().
|
||||||
tr().
|
tr().
|
||||||
th(".rack", "Rack").
|
th(".rack", "Rack").
|
||||||
|
th(".state", "Node State").
|
||||||
th(".nodeaddress", "Node Address").
|
th(".nodeaddress", "Node Address").
|
||||||
th(".nodehttpaddress", "Node HTTP Address").
|
th(".nodehttpaddress", "Node HTTP Address").
|
||||||
th(".healthStatus", "Health-status").
|
th(".healthStatus", "Health-status").
|
||||||
th(".lastHealthUpdate", "Last health-update").
|
th(".lastHealthUpdate", "Last health-update").
|
||||||
th(".healthReport", "Health-report").
|
th(".healthReport", "Health-report").
|
||||||
th(".containers", "Containers").
|
th(".containers", "Containers").
|
||||||
// th(".mem", "Mem Used (MB)").
|
th(".mem", "Mem Used").
|
||||||
// th(".mem", "Mem Avail (MB)").
|
th(".mem", "Mem Avail").
|
||||||
_()._().
|
_()._().
|
||||||
tbody();
|
tbody();
|
||||||
|
RMNodeState stateFilter = null;
|
||||||
|
if(type != null && !type.isEmpty()) {
|
||||||
|
stateFilter = RMNodeState.valueOf(type.toUpperCase());
|
||||||
|
}
|
||||||
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
for (RMNode ni : this.rmContext.getRMNodes().values()) {
|
||||||
|
if(stateFilter != null) {
|
||||||
|
RMNodeState state = ni.getState();
|
||||||
|
if(!stateFilter.equals(state)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NodeId id = ni.getNodeID();
|
||||||
|
SchedulerNodeReport report = sched.getNodeReport(id);
|
||||||
|
int numContainers = 0;
|
||||||
|
int usedMemory = 0;
|
||||||
|
int availableMemory = 0;
|
||||||
|
if(report != null) {
|
||||||
|
numContainers = report.getNumContainers();
|
||||||
|
usedMemory = report.getUsedResource().getMemory();
|
||||||
|
availableMemory = report.getAvailableResource().getMemory();
|
||||||
|
}
|
||||||
|
|
||||||
NodeHealthStatus health = ni.getNodeHealthStatus();
|
NodeHealthStatus health = ni.getNodeHealthStatus();
|
||||||
tbody.tr().
|
tbody.tr().
|
||||||
td(ni.getRackName()).
|
td(ni.getRackName()).
|
||||||
|
td(String.valueOf(ni.getState())).
|
||||||
td(String.valueOf(ni.getNodeID().toString())).
|
td(String.valueOf(ni.getNodeID().toString())).
|
||||||
td().a("http://" + ni.getHttpAddress(), ni.getHttpAddress())._().
|
td().a("http://" + ni.getHttpAddress(), ni.getHttpAddress())._().
|
||||||
td(health.getIsNodeHealthy() ? "Healthy" : "Unhealthy").
|
td(health.getIsNodeHealthy() ? "Healthy" : "Unhealthy").
|
||||||
td(Times.format(health.getLastHealthReportTime())).
|
td(Times.format(health.getLastHealthReportTime())).
|
||||||
td(String.valueOf(health.getHealthReport())).
|
td(String.valueOf(health.getHealthReport())).
|
||||||
// TODO: acm: refactor2 FIXME
|
td(String.valueOf(numContainers)).
|
||||||
//td(String.valueOf(ni.getNumContainers())).
|
td().br().$title(String.valueOf(usedMemory))._().
|
||||||
// TODO: FIXME Vinodkv
|
_(StringUtils.byteDesc(usedMemory * BYTES_IN_MB))._().
|
||||||
// td(String.valueOf(ni.getUsedResource().getMemory())).
|
td().br().$title(String.valueOf(usedMemory))._().
|
||||||
// td(String.valueOf(ni.getAvailableResource().getMemory())).
|
_(StringUtils.byteDesc(availableMemory * BYTES_IN_MB))._().
|
||||||
td("n/a")._();
|
_();
|
||||||
}
|
}
|
||||||
tbody._()._();
|
tbody._()._();
|
||||||
}
|
}
|
||||||
|
@ -84,7 +121,12 @@ class NodesPage extends RmView {
|
||||||
|
|
||||||
@Override protected void preHead(Page.HTML<_> html) {
|
@Override protected void preHead(Page.HTML<_> html) {
|
||||||
commonPreHead(html);
|
commonPreHead(html);
|
||||||
setTitle("Nodes of the cluster");
|
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(DATATABLES_ID, "nodes");
|
||||||
set(initID(DATATABLES, "nodes"), nodesTableInit());
|
set(initID(DATATABLES, "nodes"), nodesTableInit());
|
||||||
setTableStyles(html, "nodes", ".healthStatus {width:10em}",
|
setTableStyles(html, "nodes", ".healthStatus {width:10em}",
|
||||||
|
@ -96,11 +138,10 @@ class NodesPage extends RmView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String nodesTableInit() {
|
private String nodesTableInit() {
|
||||||
return tableInit().
|
StringBuilder b = tableInit().append(",aoColumnDefs:[");
|
||||||
// rack, nodeid, host, healthStatus, health update ts, health report,
|
b.append("{'bSearchable':false, 'aTargets': [7]} ,");
|
||||||
// containers, memused, memavail
|
b.append("{'sType':'title-numeric', 'bSearchable':false, " +
|
||||||
append(", aoColumns:[null, null, null, null, null, null, ").
|
"'aTargets': [ 8, 9] }]}");
|
||||||
append("{sType:'title-numeric', bSearchable:false}]}").
|
return b.toString();
|
||||||
toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.hadoop.yarn.webapp.WebApp;
|
||||||
public class RMWebApp extends WebApp {
|
public class RMWebApp extends WebApp {
|
||||||
static final String APP_ID = "app.id";
|
static final String APP_ID = "app.id";
|
||||||
static final String QUEUE_NAME = "queue.name";
|
static final String QUEUE_NAME = "queue.name";
|
||||||
|
static final String NODE_STATE = "node.state";
|
||||||
|
|
||||||
private final ResourceManager rm;
|
private final ResourceManager rm;
|
||||||
|
|
||||||
|
@ -44,9 +45,9 @@ public class RMWebApp extends WebApp {
|
||||||
bind(RMContext.class).toInstance(rm.getRMContext());
|
bind(RMContext.class).toInstance(rm.getRMContext());
|
||||||
}
|
}
|
||||||
route("/", RmController.class);
|
route("/", RmController.class);
|
||||||
route("/nodes", RmController.class, "nodes");
|
route(pajoin("/nodes", NODE_STATE), RmController.class, "nodes");
|
||||||
route("/apps", RmController.class);
|
route("/apps", RmController.class);
|
||||||
route("/cluster", RmController.class, "info");
|
route("/cluster", RmController.class, "about");
|
||||||
route(pajoin("/app", APP_ID), RmController.class, "app");
|
route(pajoin("/app", APP_ID), RmController.class, "app");
|
||||||
route("/scheduler", RmController.class, "scheduler");
|
route("/scheduler", RmController.class, "scheduler");
|
||||||
route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue");
|
route(pajoin("/queue", QUEUE_NAME), RmController.class, "queue");
|
||||||
|
|
|
@ -22,8 +22,9 @@ import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.APP_
|
||||||
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.QUEUE_NAME;
|
import static org.apache.hadoop.yarn.server.resourcemanager.webapp.RMWebApp.QUEUE_NAME;
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.apache.hadoop.util.VersionInfo;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.Container;
|
import org.apache.hadoop.yarn.api.records.Container;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
|
@ -35,7 +36,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.Capacity
|
||||||
import org.apache.hadoop.yarn.util.Apps;
|
import org.apache.hadoop.yarn.util.Apps;
|
||||||
import org.apache.hadoop.yarn.util.ConverterUtils;
|
import org.apache.hadoop.yarn.util.ConverterUtils;
|
||||||
import org.apache.hadoop.yarn.util.Times;
|
import org.apache.hadoop.yarn.util.Times;
|
||||||
import org.apache.hadoop.yarn.util.YarnVersionInfo;
|
|
||||||
import org.apache.hadoop.yarn.webapp.Controller;
|
import org.apache.hadoop.yarn.webapp.Controller;
|
||||||
import org.apache.hadoop.yarn.webapp.ResponseInfo;
|
import org.apache.hadoop.yarn.webapp.ResponseInfo;
|
||||||
|
|
||||||
|
@ -50,25 +50,15 @@ public class RmController extends Controller {
|
||||||
setTitle("Applications");
|
setTitle("Applications");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void info() {
|
public void about() {
|
||||||
setTitle("About the Cluster");
|
setTitle("About the Cluster");
|
||||||
long ts = ResourceManager.clusterTimeStamp;
|
render(AboutPage.class);
|
||||||
ResourceManager rm = getInstance(ResourceManager.class);
|
|
||||||
info("Cluster overview").
|
|
||||||
_("Cluster ID:", ts).
|
|
||||||
_("ResourceManager state:", rm.getServiceState()).
|
|
||||||
_("ResourceManager started on:", Times.format(ts)).
|
|
||||||
_("ResourceManager version:", YarnVersionInfo.getBuildVersion() +
|
|
||||||
" on " + YarnVersionInfo.getDate()).
|
|
||||||
_("Hadoop version:", VersionInfo.getBuildVersion() +
|
|
||||||
" on " + VersionInfo.getDate());
|
|
||||||
render(InfoPage.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void app() {
|
public void app() {
|
||||||
String aid = $(APP_ID);
|
String aid = $(APP_ID);
|
||||||
if (aid.isEmpty()) {
|
if (aid.isEmpty()) {
|
||||||
setStatus(response().SC_BAD_REQUEST);
|
setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
setTitle("Bad request: requires application ID");
|
setTitle("Bad request: requires application ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +67,7 @@ public class RmController extends Controller {
|
||||||
RMApp app = context.getRMApps().get(appID);
|
RMApp app = context.getRMApps().get(appID);
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
// TODO: handle redirect to jobhistory server
|
// TODO: handle redirect to jobhistory server
|
||||||
setStatus(response().SC_NOT_FOUND);
|
setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
setTitle("Application not found: "+ aid);
|
setTitle("Application not found: "+ aid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +97,7 @@ public class RmController extends Controller {
|
||||||
} else {
|
} else {
|
||||||
info._("AM container logs:", "AM not yet registered with RM");
|
info._("AM container logs:", "AM not yet registered with RM");
|
||||||
}
|
}
|
||||||
render(InfoPage.class);
|
render(AboutPage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void nodes() {
|
public void nodes() {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class RmView extends TwoColumnLayout {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<? extends SubView> content() {
|
protected Class<? extends SubView> content() {
|
||||||
return AppsBlock.class;
|
return AppsBlockWithMetrics.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String appsTableInit() {
|
private String appsTableInit() {
|
||||||
|
@ -60,7 +60,7 @@ public class RmView extends TwoColumnLayout {
|
||||||
// id, user, name, queue, state, progress, ui, note
|
// id, user, name, queue, state, progress, ui, note
|
||||||
StringBuilder init = tableInit().
|
StringBuilder init = tableInit().
|
||||||
append(", aoColumns:[{sType:'title-numeric'}, null, null, null, null,").
|
append(", aoColumns:[{sType:'title-numeric'}, null, null, null, null,").
|
||||||
append("{sType:'title-numeric', bSearchable:false}, null, null]");
|
append("null,{sType:'title-numeric', bSearchable:false}, null, null]");
|
||||||
String rows = $("rowlimit");
|
String rows = $("rowlimit");
|
||||||
int rowLimit = rows.isEmpty() ? MAX_DISPLAY_ROWS : Integer.parseInt(rows);
|
int rowLimit = rows.isEmpty() ? MAX_DISPLAY_ROWS : Integer.parseInt(rows);
|
||||||
if (list.apps.size() < rowLimit) {
|
if (list.apps.size() < rowLimit) {
|
||||||
|
|
|
@ -17,14 +17,20 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
import org.apache.hadoop.yarn.server.resourcemanager.RMContext;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.webapp.NodesPage.NodesBlock;
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.NodesPage.NodesBlock;
|
||||||
import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import com.google.inject.Binder;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This tests the NodesPage block table that it should contain the table body
|
* This tests the NodesPage block table that it should contain the table body
|
||||||
* data for all the columns in the table as specified in the header.
|
* data for all the columns in the table as specified in the header.
|
||||||
|
@ -33,23 +39,36 @@ public class TestNodesPage {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNodesBlockRender() throws Exception {
|
public void testNodesBlockRender() throws Exception {
|
||||||
int numberOfRacks = 2;
|
final int numberOfRacks = 2;
|
||||||
int numberOfNodesPerRack = 2;
|
final int numberOfNodesPerRack = 2;
|
||||||
// Number of Actual Table Headers for NodesPage.NodesBlock might change in
|
// Number of Actual Table Headers for NodesPage.NodesBlock might change in
|
||||||
// future. In that case this value should be adjusted to the new value.
|
// future. In that case this value should be adjusted to the new value.
|
||||||
int numberOfActualTableHeaders = 7;
|
final int numberOfThInMetricsTable = 9;
|
||||||
|
final int numberOfActualTableHeaders = 10;
|
||||||
|
|
||||||
PrintWriter writer = WebAppTests.testBlock(
|
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
||||||
NodesBlock.class,
|
TestRMWebApp.mockRMContext(3, numberOfRacks, numberOfNodesPerRack, 8*TestRMWebApp.GiB),
|
||||||
RMContext.class,
|
new Module() {
|
||||||
TestRMWebApp.mockRMContext(3, numberOfRacks, numberOfNodesPerRack,
|
@Override
|
||||||
8 * TestRMWebApp.GiB)).getInstance(PrintWriter.class);
|
public void configure(Binder binder) {
|
||||||
|
try {
|
||||||
|
binder.bind(ResourceManager.class).toInstance(TestRMWebApp.mockRm(3,
|
||||||
|
numberOfRacks, numberOfNodesPerRack, 8*TestRMWebApp.GiB));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
injector.getInstance(NodesBlock.class).render();
|
||||||
|
PrintWriter writer = injector.getInstance(PrintWriter.class);
|
||||||
|
WebAppTests.flushOutput(injector);
|
||||||
|
|
||||||
Mockito.verify(writer, Mockito.times(numberOfActualTableHeaders)).print(
|
Mockito.verify(writer, Mockito.times(numberOfActualTableHeaders +
|
||||||
|
numberOfThInMetricsTable)).print(
|
||||||
"<th");
|
"<th");
|
||||||
Mockito.verify(
|
Mockito.verify(
|
||||||
writer,
|
writer,
|
||||||
Mockito.times(numberOfRacks * numberOfNodesPerRack
|
Mockito.times(numberOfRacks * numberOfNodesPerRack
|
||||||
* numberOfActualTableHeaders)).print("<td");
|
* numberOfActualTableHeaders + numberOfThInMetricsTable)).print("<td");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,10 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.NodeId;
|
import org.apache.hadoop.yarn.api.records.NodeId;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.MockNodes;
|
import org.apache.hadoop.yarn.server.resourcemanager.MockNodes;
|
||||||
|
@ -37,7 +37,6 @@ import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.applicationsmanager.MockAsm;
|
import org.apache.hadoop.yarn.server.resourcemanager.applicationsmanager.MockAsm;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.recovery.MemStore;
|
import org.apache.hadoop.yarn.server.resourcemanager.recovery.MemStore;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
||||||
|
@ -48,7 +47,9 @@ import org.apache.hadoop.yarn.webapp.test.WebAppTests;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.inject.Binder;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
public class TestRMWebApp {
|
public class TestRMWebApp {
|
||||||
static final int GiB = 1024; // MiB
|
static final int GiB = 1024; // MiB
|
||||||
|
@ -62,14 +63,36 @@ public class TestRMWebApp {
|
||||||
|
|
||||||
@Test public void testView() {
|
@Test public void testView() {
|
||||||
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
||||||
mockRMContext(3, 1, 2, 8*GiB));
|
mockRMContext(3, 1, 2, 8*GiB),
|
||||||
|
new Module() {
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder) {
|
||||||
|
try {
|
||||||
|
binder.bind(ResourceManager.class).toInstance(mockRm(3, 1, 2, 8*GiB));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
injector.getInstance(RmView.class).render();
|
injector.getInstance(RmView.class).render();
|
||||||
WebAppTests.flushOutput(injector);
|
WebAppTests.flushOutput(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testNodesPage() {
|
@Test public void testNodesPage() {
|
||||||
WebAppTests.testPage(NodesPage.class, RMContext.class,
|
Injector injector = WebAppTests.createMockInjector(RMContext.class,
|
||||||
mockRMContext(3, 1, 2, 8*GiB));
|
mockRMContext(3, 1, 2, 8*GiB),
|
||||||
|
new Module() {
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder) {
|
||||||
|
try {
|
||||||
|
binder.bind(ResourceManager.class).toInstance(mockRm(3, 1, 2, 8*GiB));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
injector.getInstance(NodesPage.class).render();
|
||||||
|
WebAppTests.flushOutput(injector);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RMContext mockRMContext(int numApps, int racks, int numNodes,
|
public static RMContext mockRMContext(int numApps, int racks, int numNodes,
|
||||||
|
@ -99,8 +122,7 @@ public class TestRMWebApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceManager mockRm(int apps, int racks, int nodes,
|
public static ResourceManager mockRm(int apps, int racks, int nodes,
|
||||||
int mbsPerNode)
|
int mbsPerNode) throws IOException {
|
||||||
throws Exception {
|
|
||||||
ResourceManager rm = mock(ResourceManager.class);
|
ResourceManager rm = mock(ResourceManager.class);
|
||||||
RMContext rmContext = mockRMContext(apps, racks, nodes,
|
RMContext rmContext = mockRMContext(apps, racks, nodes,
|
||||||
mbsPerNode);
|
mbsPerNode);
|
||||||
|
@ -110,7 +132,7 @@ public class TestRMWebApp {
|
||||||
return rm;
|
return rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CapacityScheduler mockCapacityScheduler() throws Exception {
|
public static CapacityScheduler mockCapacityScheduler() throws IOException {
|
||||||
// stolen from TestCapacityScheduler
|
// stolen from TestCapacityScheduler
|
||||||
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
CapacitySchedulerConfiguration conf = new CapacitySchedulerConfiguration();
|
||||||
setupQueueConfiguration(conf);
|
setupQueueConfiguration(conf);
|
||||||
|
|
Loading…
Reference in New Issue