Merge -c 1227788 from trunk to branch-0.23 to fix MAPREDUCE-3326. Added detailed information about queue's to the CapacityScheduler web-ui.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1227794 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a7f8694d59
commit
1828be291a
|
@ -360,6 +360,9 @@ Release 0.23.1 - Unreleased
|
||||||
MAPREDUCE-1744. DistributedCache creates its own FileSytem instance when
|
MAPREDUCE-1744. DistributedCache creates its own FileSytem instance when
|
||||||
adding a file/archive to the path. (Dick King via tucu)
|
adding a file/archive to the path. (Dick King via tucu)
|
||||||
|
|
||||||
|
MAPREDUCE-3326. Added detailed information about queue's to the
|
||||||
|
CapacityScheduler web-ui. (Jason Lowe via acmurthy)
|
||||||
|
|
||||||
Release 0.23.0 - 2011-11-01
|
Release 0.23.0 - 2011-11-01
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -80,6 +80,10 @@ public class ResponseInfo implements Iterable<ResponseInfo.Item> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
items.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Item> iterator() {
|
public Iterator<Item> iterator() {
|
||||||
return items.iterator();
|
return items.iterator();
|
||||||
|
|
|
@ -20,18 +20,22 @@ package org.apache.hadoop.yarn.server.resourcemanager.webapp;
|
||||||
|
|
||||||
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
import static org.apache.hadoop.yarn.util.StringHelper.join;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.ParentQueue;
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerInfo;
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerInfo;
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerLeafQueueInfo;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerQueueInfo;
|
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.CapacitySchedulerQueueInfo;
|
||||||
|
import org.apache.hadoop.yarn.webapp.ResponseInfo;
|
||||||
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;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.LI;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.LI;
|
||||||
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL;
|
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL;
|
||||||
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
|
||||||
|
import org.apache.hadoop.yarn.webapp.view.InfoBlock;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.servlet.RequestScoped;
|
import com.google.inject.servlet.RequestScoped;
|
||||||
|
@ -45,23 +49,61 @@ class CapacitySchedulerPage extends RmView {
|
||||||
static final float EPSILON = 1e-8f;
|
static final float EPSILON = 1e-8f;
|
||||||
|
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
static class Parent {
|
static class CSQInfo {
|
||||||
CSQueue queue;
|
CapacitySchedulerInfo csinfo;
|
||||||
|
CapacitySchedulerQueueInfo qinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class LeafQueueInfoBlock extends HtmlBlock {
|
||||||
|
final CapacitySchedulerLeafQueueInfo lqinfo;
|
||||||
|
|
||||||
|
@Inject LeafQueueInfoBlock(ViewContext ctx, CSQInfo info) {
|
||||||
|
super(ctx);
|
||||||
|
lqinfo = (CapacitySchedulerLeafQueueInfo) info.qinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(Block html) {
|
||||||
|
ResponseInfo ri = info("\'" + lqinfo.getQueuePath().substring(5) + "\' Queue Status").
|
||||||
|
_("Queue State:", lqinfo.getQueueState()).
|
||||||
|
_("Capacity:", percent(lqinfo.getCapacity() / 100)).
|
||||||
|
_("Max Capacity:", percent(lqinfo.getMaxCapacity() / 100)).
|
||||||
|
_("Used Capacity:", percent(lqinfo.getUsedCapacity() / 100)).
|
||||||
|
_("Absolute Capacity:", percent(lqinfo.getAbsoluteCapacity() / 100)).
|
||||||
|
_("Absolute Max Capacity:", percent(lqinfo.getAbsoluteMaxCapacity() / 100)).
|
||||||
|
_("Utilization:", percent(lqinfo.getUtilization() / 100)).
|
||||||
|
_("Used Resources:", lqinfo.getUsedResources().toString()).
|
||||||
|
_("Num Active Applications:", Integer.toString(lqinfo.getNumActiveApplications())).
|
||||||
|
_("Num Pending Applications:", Integer.toString(lqinfo.getNumPendingApplications())).
|
||||||
|
_("Num Containers:", Integer.toString(lqinfo.getNumContainers())).
|
||||||
|
_("Max Applications:", Integer.toString(lqinfo.getMaxApplications())).
|
||||||
|
_("Max Applications Per User:", Integer.toString(lqinfo.getMaxApplicationsPerUser())).
|
||||||
|
_("Max Active Applications:", Integer.toString(lqinfo.getMaxActiveApplications())).
|
||||||
|
_("Max Active Applications Per User:", Integer.toString(lqinfo.getMaxActiveApplicationsPerUser())).
|
||||||
|
_("User Limit:", Integer.toString(lqinfo.getUserLimit()) + "%").
|
||||||
|
_("User Limit Factor:", String.format("%.1f", lqinfo.getUserLimitFactor()));
|
||||||
|
|
||||||
|
html._(InfoBlock.class);
|
||||||
|
|
||||||
|
// clear the info contents so this queue's info doesn't accumulate into another queue's info
|
||||||
|
ri.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class QueueBlock extends HtmlBlock {
|
public static class QueueBlock extends HtmlBlock {
|
||||||
final Parent parent;
|
final CSQInfo csqinfo;
|
||||||
final CapacitySchedulerInfo sinfo;
|
|
||||||
|
|
||||||
@Inject QueueBlock(Parent parent) {
|
@Inject QueueBlock(CSQInfo info) {
|
||||||
this.parent = parent;
|
csqinfo = info;
|
||||||
sinfo = new CapacitySchedulerInfo(parent.queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Block html) {
|
public void render(Block html) {
|
||||||
|
ArrayList<CapacitySchedulerQueueInfo> subQueues =
|
||||||
|
(csqinfo.qinfo == null) ? csqinfo.csinfo.getSubQueues()
|
||||||
|
: csqinfo.qinfo.getSubQueues();
|
||||||
UL<Hamlet> ul = html.ul();
|
UL<Hamlet> ul = html.ul();
|
||||||
for (CapacitySchedulerQueueInfo info : sinfo.getSubQueues()) {
|
for (CapacitySchedulerQueueInfo info : subQueues) {
|
||||||
float used = info.getUsedCapacity() / 100;
|
float used = info.getUsedCapacity() / 100;
|
||||||
float set = info.getCapacity() / 100;
|
float set = info.getCapacity() / 100;
|
||||||
float delta = Math.abs(set - used) + 0.001f;
|
float delta = Math.abs(set - used) + 0.001f;
|
||||||
|
@ -76,11 +118,12 @@ class CapacitySchedulerPage extends RmView {
|
||||||
used > set ? OVER : UNDER, ';',
|
used > set ? OVER : UNDER, ';',
|
||||||
used > set ? left(set/max) : left(used/max)))._('.')._().
|
used > set ? left(set/max) : left(used/max)))._('.')._().
|
||||||
span(".q", info.getQueuePath().substring(5))._();
|
span(".q", info.getQueuePath().substring(5))._();
|
||||||
if (info.getQueue() instanceof ParentQueue) {
|
|
||||||
// this could be optimized better
|
csqinfo.qinfo = info;
|
||||||
parent.queue = info.getQueue();
|
if (info.getSubQueues() == null) {
|
||||||
li.
|
li.ul("#lq").li()._(LeafQueueInfoBlock.class)._()._();
|
||||||
_(QueueBlock.class);
|
} else {
|
||||||
|
li._(QueueBlock.class);
|
||||||
}
|
}
|
||||||
li._();
|
li._();
|
||||||
}
|
}
|
||||||
|
@ -91,11 +134,11 @@ class CapacitySchedulerPage extends RmView {
|
||||||
|
|
||||||
static class QueuesBlock extends HtmlBlock {
|
static class QueuesBlock extends HtmlBlock {
|
||||||
final CapacityScheduler cs;
|
final CapacityScheduler cs;
|
||||||
final Parent parent;
|
final CSQInfo csqinfo;
|
||||||
|
|
||||||
@Inject QueuesBlock(ResourceManager rm, Parent parent) {
|
@Inject QueuesBlock(ResourceManager rm, CSQInfo info) {
|
||||||
cs = (CapacityScheduler) rm.getResourceScheduler();
|
cs = (CapacityScheduler) rm.getResourceScheduler();
|
||||||
this.parent = parent;
|
csqinfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,8 +158,10 @@ class CapacitySchedulerPage extends RmView {
|
||||||
span(".q", "default")._()._();
|
span(".q", "default")._()._();
|
||||||
} else {
|
} else {
|
||||||
CSQueue root = cs.getRootQueue();
|
CSQueue root = cs.getRootQueue();
|
||||||
parent.queue = root;
|
CapacitySchedulerInfo sinfo = new CapacitySchedulerInfo(root);
|
||||||
CapacitySchedulerInfo sinfo = new CapacitySchedulerInfo(parent.queue);
|
csqinfo.csinfo = sinfo;
|
||||||
|
csqinfo.qinfo = null;
|
||||||
|
|
||||||
float used = sinfo.getUsedCapacity() / 100;
|
float used = sinfo.getUsedCapacity() / 100;
|
||||||
float set = sinfo.getCapacity() / 100;
|
float set = sinfo.getCapacity() / 100;
|
||||||
float delta = Math.abs(set - used) + 0.001f;
|
float delta = Math.abs(set - used) + 0.001f;
|
||||||
|
@ -144,13 +189,16 @@ class CapacitySchedulerPage extends RmView {
|
||||||
"#cs ul { list-style: none }",
|
"#cs ul { list-style: none }",
|
||||||
"#cs a { font-weight: normal; margin: 2px; position: relative }",
|
"#cs a { font-weight: normal; margin: 2px; position: relative }",
|
||||||
"#cs a span { font-weight: normal; font-size: 80% }",
|
"#cs a span { font-weight: normal; font-size: 80% }",
|
||||||
"#cs-wrapper .ui-widget-header { padding: 0.2em 0.5em }")._().
|
"#cs-wrapper .ui-widget-header { padding: 0.2em 0.5em }",
|
||||||
|
"table.info tr th {width: 50%}")._(). // to center info table
|
||||||
script("/static/jt/jquery.jstree.js").
|
script("/static/jt/jquery.jstree.js").
|
||||||
script().$type("text/javascript").
|
script().$type("text/javascript").
|
||||||
_("$(function() {",
|
_("$(function() {",
|
||||||
" $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');",
|
" $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');",
|
||||||
" $('#cs').bind('loaded.jstree', function (e, data) {",
|
" $('#cs').bind('loaded.jstree', function (e, data) {",
|
||||||
" data.inst.open_all(); }).",
|
" data.inst.open_all();",
|
||||||
|
" data.inst.close_node('#lq', true);",
|
||||||
|
" }).",
|
||||||
" jstree({",
|
" jstree({",
|
||||||
" core: { animation: 188, html_titles: true },",
|
" core: { animation: 188, html_titles: true },",
|
||||||
" plugins: ['themeroller', 'html_data', 'ui'],",
|
" plugins: ['themeroller', 'html_data', 'ui'],",
|
||||||
|
@ -160,8 +208,9 @@ class CapacitySchedulerPage extends RmView {
|
||||||
" });",
|
" });",
|
||||||
" $('#cs').bind('select_node.jstree', function(e, data) {",
|
" $('#cs').bind('select_node.jstree', function(e, data) {",
|
||||||
" var q = $('.q', data.rslt.obj).first().text();",
|
" var q = $('.q', data.rslt.obj).first().text();",
|
||||||
" if (q == 'root') q = '';",
|
" if (q == 'root') q = '';",
|
||||||
" $('#apps').dataTable().fnFilter(q, 3);",
|
" else q = '^' + q.substr(q.lastIndexOf('.') + 1) + '$';",
|
||||||
|
" $('#apps').dataTable().fnFilter(q, 3, true);",
|
||||||
" });",
|
" });",
|
||||||
" $('#cs').show();",
|
" $('#cs').show();",
|
||||||
"});")._();
|
"});")._();
|
||||||
|
|
|
@ -26,9 +26,8 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.XmlTransient;
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.api.records.QueueState;
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.ParentQueue;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.LeafQueue;
|
||||||
|
|
||||||
@XmlRootElement(name = "capacityScheduler")
|
@XmlRootElement(name = "capacityScheduler")
|
||||||
@XmlType(name = "capacityScheduler")
|
@XmlType(name = "capacityScheduler")
|
||||||
|
@ -83,21 +82,11 @@ public class CapacitySchedulerInfo extends SchedulerInfo {
|
||||||
CSQueue parentQueue = parent;
|
CSQueue parentQueue = parent;
|
||||||
ArrayList<CapacitySchedulerQueueInfo> queuesInfo = new ArrayList<CapacitySchedulerQueueInfo>();
|
ArrayList<CapacitySchedulerQueueInfo> queuesInfo = new ArrayList<CapacitySchedulerQueueInfo>();
|
||||||
for (CSQueue queue : parentQueue.getChildQueues()) {
|
for (CSQueue queue : parentQueue.getChildQueues()) {
|
||||||
float usedCapacity = queue.getUsedCapacity() * 100;
|
CapacitySchedulerQueueInfo info;
|
||||||
float capacity = queue.getCapacity() * 100;
|
if (queue instanceof LeafQueue) {
|
||||||
String queueName = queue.getQueueName();
|
info = new CapacitySchedulerLeafQueueInfo((LeafQueue)queue);
|
||||||
String queuePath = queue.getQueuePath();
|
} else {
|
||||||
float max = queue.getMaximumCapacity();
|
info = new CapacitySchedulerQueueInfo(queue);
|
||||||
if (max < EPSILON || max > 1f)
|
|
||||||
max = 1f;
|
|
||||||
float maxCapacity = max * 100;
|
|
||||||
QueueState state = queue.getState();
|
|
||||||
CapacitySchedulerQueueInfo info = new CapacitySchedulerQueueInfo(
|
|
||||||
capacity, usedCapacity, maxCapacity, queueName, state, queuePath);
|
|
||||||
|
|
||||||
if (queue instanceof ParentQueue) {
|
|
||||||
info.isParent = true;
|
|
||||||
info.queue = queue;
|
|
||||||
info.subQueues = getQueues(queue);
|
info.subQueues = getQueues(queue);
|
||||||
}
|
}
|
||||||
queuesInfo.add(info);
|
queuesInfo.add(info);
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* 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.dao;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.LeafQueue;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class CapacitySchedulerLeafQueueInfo extends CapacitySchedulerQueueInfo {
|
||||||
|
|
||||||
|
protected int numActiveApplications;
|
||||||
|
protected int numPendingApplications;
|
||||||
|
protected int numContainers;
|
||||||
|
protected int maxApplications;
|
||||||
|
protected int maxApplicationsPerUser;
|
||||||
|
protected int maxActiveApplications;
|
||||||
|
protected int maxActiveApplicationsPerUser;
|
||||||
|
protected int userLimit;
|
||||||
|
protected float userLimitFactor;
|
||||||
|
|
||||||
|
CapacitySchedulerLeafQueueInfo() {
|
||||||
|
};
|
||||||
|
|
||||||
|
CapacitySchedulerLeafQueueInfo(LeafQueue q) {
|
||||||
|
super(q);
|
||||||
|
numActiveApplications = q.getNumActiveApplications();
|
||||||
|
numPendingApplications = q.getNumPendingApplications();
|
||||||
|
numContainers = q.getNumContainers();
|
||||||
|
maxApplications = q.getMaxApplications();
|
||||||
|
maxApplicationsPerUser = q.getMaxApplicationsPerUser();
|
||||||
|
maxActiveApplications = q.getMaximumActiveApplications();
|
||||||
|
maxActiveApplicationsPerUser = q.getMaximumActiveApplicationsPerUser();
|
||||||
|
userLimit = q.getUserLimit();
|
||||||
|
userLimitFactor = q.getUserLimitFactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumActiveApplications() {
|
||||||
|
return numActiveApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumPendingApplications() {
|
||||||
|
return numPendingApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumContainers() {
|
||||||
|
return numContainers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxApplications() {
|
||||||
|
return maxApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxApplicationsPerUser() {
|
||||||
|
return maxApplicationsPerUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxActiveApplications() {
|
||||||
|
return maxActiveApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxActiveApplicationsPerUser() {
|
||||||
|
return maxActiveApplicationsPerUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserLimit() {
|
||||||
|
return userLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getUserLimitFactor() {
|
||||||
|
return userLimitFactor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,50 +22,54 @@ import java.util.ArrayList;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||||
import javax.xml.bind.annotation.XmlTransient;
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
import org.apache.hadoop.yarn.api.records.QueueState;
|
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CSQueue;
|
||||||
|
|
||||||
@XmlRootElement
|
@XmlRootElement
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlSeeAlso({CapacitySchedulerLeafQueueInfo.class})
|
||||||
public class CapacitySchedulerQueueInfo {
|
public class CapacitySchedulerQueueInfo {
|
||||||
|
|
||||||
@XmlTransient
|
@XmlTransient
|
||||||
protected String queuePath;
|
static final float EPSILON = 1e-8f;
|
||||||
@XmlTransient
|
|
||||||
protected Boolean isParent = false;
|
|
||||||
|
|
||||||
// bit odd to store this but makes html easier for now
|
|
||||||
@XmlTransient
|
@XmlTransient
|
||||||
protected CSQueue queue;
|
protected String queuePath;
|
||||||
|
|
||||||
protected float capacity;
|
protected float capacity;
|
||||||
protected float usedCapacity;
|
protected float usedCapacity;
|
||||||
protected float maxCapacity;
|
protected float maxCapacity;
|
||||||
|
protected float absoluteCapacity;
|
||||||
|
protected float absoluteMaxCapacity;
|
||||||
|
protected float utilization;
|
||||||
|
protected int numApplications;
|
||||||
|
protected String usedResources;
|
||||||
protected String queueName;
|
protected String queueName;
|
||||||
protected QueueState state;
|
protected String state;
|
||||||
protected ArrayList<CapacitySchedulerQueueInfo> subQueues;
|
protected ArrayList<CapacitySchedulerQueueInfo> subQueues;
|
||||||
|
|
||||||
CapacitySchedulerQueueInfo() {
|
CapacitySchedulerQueueInfo() {
|
||||||
};
|
};
|
||||||
|
|
||||||
CapacitySchedulerQueueInfo(float cap, float used, float max, String name,
|
CapacitySchedulerQueueInfo(CSQueue q) {
|
||||||
QueueState state, String path) {
|
queuePath = q.getQueuePath();
|
||||||
this.capacity = cap;
|
capacity = q.getCapacity() * 100;
|
||||||
this.usedCapacity = used;
|
usedCapacity = q.getUsedCapacity() * 100;
|
||||||
this.maxCapacity = max;
|
|
||||||
this.queueName = name;
|
|
||||||
this.state = state;
|
|
||||||
this.queuePath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isParent() {
|
maxCapacity = q.getMaximumCapacity();
|
||||||
return this.isParent;
|
if (maxCapacity < EPSILON || maxCapacity > 1f)
|
||||||
}
|
maxCapacity = 1f;
|
||||||
|
maxCapacity *= 100;
|
||||||
|
|
||||||
public CSQueue getQueue() {
|
absoluteCapacity = cap(q.getAbsoluteCapacity(), 0f, 1f) * 100;
|
||||||
return this.queue;
|
absoluteMaxCapacity = cap(q.getAbsoluteMaximumCapacity(), 0f, 1f) * 100;
|
||||||
|
utilization = q.getUtilization() * 100;
|
||||||
|
numApplications = q.getNumApplications();
|
||||||
|
usedResources = q.getUsedResources().toString();
|
||||||
|
queueName = q.getQueueName();
|
||||||
|
state = q.getState().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCapacity() {
|
public float getCapacity() {
|
||||||
|
@ -80,12 +84,32 @@ public class CapacitySchedulerQueueInfo {
|
||||||
return this.maxCapacity;
|
return this.maxCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getAbsoluteCapacity() {
|
||||||
|
return absoluteCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAbsoluteMaxCapacity() {
|
||||||
|
return absoluteMaxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getUtilization() {
|
||||||
|
return utilization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumApplications() {
|
||||||
|
return numApplications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsedResources() {
|
||||||
|
return usedResources;
|
||||||
|
}
|
||||||
|
|
||||||
public String getQueueName() {
|
public String getQueueName() {
|
||||||
return this.queueName;
|
return this.queueName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQueueState() {
|
public String getQueueState() {
|
||||||
return this.state.toString();
|
return this.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQueuePath() {
|
public String getQueuePath() {
|
||||||
|
@ -96,4 +120,14 @@ public class CapacitySchedulerQueueInfo {
|
||||||
return this.subQueues;
|
return this.subQueues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit a value to a specified range.
|
||||||
|
* @param val the value to be capped
|
||||||
|
* @param low the lower bound of the range (inclusive)
|
||||||
|
* @param hi the upper bound of the range (inclusive)
|
||||||
|
* @return the capped value
|
||||||
|
*/
|
||||||
|
static float cap(float val, float low, float hi) {
|
||||||
|
return Math.min(Math.max(val, low), hi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,17 +210,21 @@ public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||||
Element qElem = (Element) queues.item(j);
|
Element qElem = (Element) queues.item(j);
|
||||||
String qName = WebServicesTestUtils.getXmlString(qElem, "queueName");
|
String qName = WebServicesTestUtils.getXmlString(qElem, "queueName");
|
||||||
String q = CapacitySchedulerConfiguration.ROOT + "." + qName;
|
String q = CapacitySchedulerConfiguration.ROOT + "." + qName;
|
||||||
verifySubQueueXML(qElem, q);
|
verifySubQueueXML(qElem, q, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifySubQueueXML(Element qElem, String q) throws Exception {
|
public void verifySubQueueXML(Element qElem, String q, float parentAbsCapacity)
|
||||||
|
throws Exception {
|
||||||
|
float absCapacity = WebServicesTestUtils.getXmlFloat(qElem, "absoluteCapacity");
|
||||||
verifySubQueueGeneric(q,
|
verifySubQueueGeneric(q,
|
||||||
WebServicesTestUtils.getXmlFloat(qElem, "usedCapacity"),
|
WebServicesTestUtils.getXmlFloat(qElem, "usedCapacity"),
|
||||||
WebServicesTestUtils.getXmlFloat(qElem, "capacity"),
|
WebServicesTestUtils.getXmlFloat(qElem, "capacity"),
|
||||||
WebServicesTestUtils.getXmlFloat(qElem, "maxCapacity"),
|
WebServicesTestUtils.getXmlFloat(qElem, "maxCapacity"),
|
||||||
|
absCapacity,
|
||||||
|
WebServicesTestUtils.getXmlFloat(qElem, "absoluteMaxCapacity"),
|
||||||
|
parentAbsCapacity,
|
||||||
WebServicesTestUtils.getXmlString(qElem, "queueName"),
|
WebServicesTestUtils.getXmlString(qElem, "queueName"),
|
||||||
WebServicesTestUtils.getXmlString(qElem, "state"));
|
WebServicesTestUtils.getXmlString(qElem, "state"));
|
||||||
|
|
||||||
|
@ -230,8 +234,12 @@ public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||||
Element subqElem = (Element) queues.item(j);
|
Element subqElem = (Element) queues.item(j);
|
||||||
String qName = WebServicesTestUtils.getXmlString(subqElem, "queueName");
|
String qName = WebServicesTestUtils.getXmlString(subqElem, "queueName");
|
||||||
String q2 = q + "." + qName;
|
String q2 = q + "." + qName;
|
||||||
verifySubQueueXML(subqElem, q2);
|
verifySubQueueXML(subqElem, q2, absCapacity);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
verifyLeafQueueGeneric(q,
|
||||||
|
WebServicesTestUtils.getXmlInt(qElem, "userLimit"),
|
||||||
|
WebServicesTestUtils.getXmlFloat(qElem, "userLimitFactor"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +262,7 @@ public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||||
for (int i = 0; i < arr.length(); i++) {
|
for (int i = 0; i < arr.length(); i++) {
|
||||||
JSONObject obj = arr.getJSONObject(i);
|
JSONObject obj = arr.getJSONObject(i);
|
||||||
String q = CapacitySchedulerConfiguration.ROOT + "." + obj.getString("queueName");
|
String q = CapacitySchedulerConfiguration.ROOT + "." + obj.getString("queueName");
|
||||||
verifySubQueue(obj, q);
|
verifySubQueue(obj, q, 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,31 +276,46 @@ public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||||
assertTrue("queueName doesn't match", "root".matches(queueName));
|
assertTrue("queueName doesn't match", "root".matches(queueName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifySubQueue(JSONObject info, String q) throws JSONException,
|
private void verifySubQueue(JSONObject info, String q, float parentAbsCapacity)
|
||||||
Exception {
|
throws JSONException, Exception {
|
||||||
if (info.has("subQueues")) {
|
int numExpectedElements = 11;
|
||||||
assertEquals("incorrect number of elements", 6, info.length());
|
boolean isParentQueue = true;
|
||||||
} else {
|
if (!info.has("subQueues")) {
|
||||||
assertEquals("incorrect number of elements", 5, info.length());
|
numExpectedElements = 20;
|
||||||
|
isParentQueue = false;
|
||||||
}
|
}
|
||||||
|
assertEquals("incorrect number of elements", numExpectedElements, info.length());
|
||||||
|
|
||||||
|
float absCapacity = (float) info.getDouble("absoluteCapacity");
|
||||||
|
|
||||||
verifySubQueueGeneric(q, (float) info.getDouble("usedCapacity"),
|
verifySubQueueGeneric(q, (float) info.getDouble("usedCapacity"),
|
||||||
(float) info.getDouble("capacity"),
|
(float) info.getDouble("capacity"),
|
||||||
(float) info.getDouble("maxCapacity"), info.getString("queueName"),
|
(float) info.getDouble("maxCapacity"),
|
||||||
|
absCapacity,
|
||||||
|
(float) info.getDouble("absoluteMaxCapacity"),
|
||||||
|
parentAbsCapacity,
|
||||||
|
info.getString("queueName"),
|
||||||
info.getString("state"));
|
info.getString("state"));
|
||||||
|
|
||||||
if (info.has("subQueues")) {
|
if (isParentQueue) {
|
||||||
JSONArray arr = info.getJSONArray("subQueues");
|
JSONArray arr = info.getJSONArray("subQueues");
|
||||||
// test subqueues
|
// test subqueues
|
||||||
for (int i = 0; i < arr.length(); i++) {
|
for (int i = 0; i < arr.length(); i++) {
|
||||||
JSONObject obj = arr.getJSONObject(i);
|
JSONObject obj = arr.getJSONObject(i);
|
||||||
String q2 = q + "." + obj.getString("queueName");
|
String q2 = q + "." + obj.getString("queueName");
|
||||||
verifySubQueue(obj, q2);
|
verifySubQueue(obj, q2, absCapacity);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
verifyLeafQueueGeneric(q, info.getInt("userLimit"),
|
||||||
|
(float) info.getDouble("userLimitFactor"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifySubQueueGeneric(String q, float usedCapacity,
|
private void verifySubQueueGeneric(String q, float usedCapacity,
|
||||||
float capacity, float maxCapacity, String qname, String state)
|
float capacity, float maxCapacity,
|
||||||
|
float absCapacity, float absMaxCapacity,
|
||||||
|
float parentAbsCapacity,
|
||||||
|
String qname, String state)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
String[] qArr = q.split("\\.");
|
String[] qArr = q.split("\\.");
|
||||||
assertTrue("q name invalid: " + q, qArr.length > 1);
|
assertTrue("q name invalid: " + q, qArr.length > 1);
|
||||||
|
@ -302,15 +325,28 @@ public class TestRMWebServicesCapacitySched extends JerseyTest {
|
||||||
assertEquals("capacity doesn't match", csConf.getCapacity(q), capacity,
|
assertEquals("capacity doesn't match", csConf.getCapacity(q), capacity,
|
||||||
1e-3f);
|
1e-3f);
|
||||||
float expectCapacity = csConf.getMaximumCapacity(q);
|
float expectCapacity = csConf.getMaximumCapacity(q);
|
||||||
|
float expectAbsMaxCapacity = parentAbsCapacity * (maxCapacity/100);
|
||||||
if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
|
if (CapacitySchedulerConfiguration.UNDEFINED == expectCapacity) {
|
||||||
expectCapacity = 100;
|
expectCapacity = 100;
|
||||||
|
expectAbsMaxCapacity = 100;
|
||||||
}
|
}
|
||||||
assertEquals("maxCapacity doesn't match", expectCapacity, maxCapacity,
|
assertEquals("maxCapacity doesn't match", expectCapacity, maxCapacity,
|
||||||
1e-3f);
|
1e-3f);
|
||||||
|
assertEquals("absoluteCapacity doesn't match",
|
||||||
|
parentAbsCapacity * (capacity/100), absCapacity, 1e-3f);
|
||||||
|
assertEquals("absoluteMaxCapacity doesn't match",
|
||||||
|
expectAbsMaxCapacity, absMaxCapacity, 1e-3f);
|
||||||
assertTrue("queueName doesn't match, got: " + qname + " expected: " + q,
|
assertTrue("queueName doesn't match, got: " + qname + " expected: " + q,
|
||||||
qshortName.matches(qname));
|
qshortName.matches(qname));
|
||||||
assertTrue("state doesn't match",
|
assertTrue("state doesn't match",
|
||||||
(csConf.getState(q).toString()).matches(state));
|
(csConf.getState(q).toString()).matches(state));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyLeafQueueGeneric(String q, int userLimit,
|
||||||
|
float userLimitFactor) throws Exception {
|
||||||
|
assertEquals("userLimit doesn't match", csConf.getUserLimit(q), userLimit);
|
||||||
|
assertEquals("userLimitFactor doesn't match",
|
||||||
|
csConf.getUserLimitFactor(q), userLimitFactor, 1e-3f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue