1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 
19 package org.apache.hadoop.yarn.server.resourcemanager.webapp;
20 
21 import static org.apache.hadoop.yarn.util.StringHelper.join;
22 
23 import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
24 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
25 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.FifoSchedulerInfo;
26 import org.apache.hadoop.yarn.server.webapp.AppsBlock;
27 import org.apache.hadoop.yarn.webapp.SubView;
28 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
29 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
30 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL;
31 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
32 import org.apache.hadoop.yarn.webapp.view.InfoBlock;
33 
34 import com.google.inject.Inject;
35 
36 class DefaultSchedulerPage extends RmView {
37   static final String _Q = ".ui-state-default.ui-corner-all";
38   static final float WIDTH_F = 0.8f;
39   static final String Q_END = "left:101%";
40   static final String OVER = "font-size:1px;background:rgba(255, 140, 0, 0.8)";
41   static final String UNDER = "font-size:1px;background:rgba(50, 205, 50, 0.8)";
42   static final float EPSILON = 1e-8f;
43 
44   static class QueueInfoBlock extends HtmlBlock {
45     final FifoSchedulerInfo sinfo;
46 
47     @Inject
QueueInfoBlock(ViewContext ctx, ResourceManager rm)48     QueueInfoBlock(ViewContext ctx, ResourceManager rm) {
49       super(ctx);
50       sinfo = new FifoSchedulerInfo(rm);
51     }
52 
render(Block html)53     @Override public void render(Block html) {
54       info("\'" + sinfo.getQueueName() + "\' Queue Status").
55         _("Queue State:" , sinfo.getState()).
56         _("Minimum Queue Memory Capacity:" , Integer.toString(sinfo.getMinQueueMemoryCapacity())).
57         _("Maximum Queue Memory Capacity:" , Integer.toString(sinfo.getMaxQueueMemoryCapacity())).
58         _("Number of Nodes:" , Integer.toString(sinfo.getNumNodes())).
59         _("Used Node Capacity:" , Integer.toString(sinfo.getUsedNodeCapacity())).
60         _("Available Node Capacity:" , Integer.toString(sinfo.getAvailNodeCapacity())).
61         _("Total Node Capacity:" , Integer.toString(sinfo.getTotalNodeCapacity())).
62         _("Number of Node Containers:" , Integer.toString(sinfo.getNumContainers()));
63 
64       html._(InfoBlock.class);
65     }
66   }
67 
68   static class QueuesBlock extends HtmlBlock {
69     final FifoSchedulerInfo sinfo;
70     final FifoScheduler fs;
71 
QueuesBlock(ResourceManager rm)72     @Inject QueuesBlock(ResourceManager rm) {
73       sinfo = new FifoSchedulerInfo(rm);
74       fs = (FifoScheduler) rm.getResourceScheduler();
75     }
76 
77     @Override
render(Block html)78     public void render(Block html) {
79       html._(MetricsOverviewTable.class);
80       UL<DIV<DIV<Hamlet>>> ul = html.
81         div("#cs-wrapper.ui-widget").
82           div(".ui-widget-header.ui-corner-top").
83             _("FifoScheduler Queue")._().
84           div("#cs.ui-widget-content.ui-corner-bottom").
85             ul();
86 
87       if (fs == null) {
88         ul.
89           li().
90             a(_Q).$style(width(WIDTH_F)).
91               span().$style(Q_END)._("100% ")._().
92               span(".q", "default")._()._();
93       } else {
94         float used = sinfo.getUsedCapacity();
95         float set = sinfo.getCapacity();
96         float delta = Math.abs(set - used) + 0.001f;
97         ul.
98           li().
99             a(_Q).$style(width(WIDTH_F)).
100               $title(join("used:", percent(used))).
101               span().$style(Q_END)._("100%")._().
102               span().$style(join(width(delta), ';', used > set ? OVER : UNDER,
103                 ';', used > set ? left(set) : left(used)))._(".")._().
104               span(".q", sinfo.getQueueName())._().
105             _(QueueInfoBlock.class)._();
106       }
107 
108       ul._()._().
109       script().$type("text/javascript").
110           _("$('#cs').hide();")._()._().
111       _(AppsBlock.class);
112     }
113   }
114 
115 
postHead(Page.HTML<_> html)116   @Override protected void postHead(Page.HTML<_> html) {
117     html.
118       style().$type("text/css").
119         _("#cs { padding: 0.5em 0 1em 0; margin-bottom: 1em; position: relative }",
120           "#cs ul { list-style: none }",
121           "#cs a { font-weight: normal; margin: 2px; position: relative }",
122           "#cs a span { font-weight: normal; font-size: 80% }",
123           "#cs-wrapper .ui-widget-header { padding: 0.2em 0.5em }",
124           "table.info tr th {width: 50%}")._(). // to center info table
125       script("/static/jt/jquery.jstree.js").
126       script().$type("text/javascript").
127         _("$(function() {",
128           "  $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');",
129           "  $('#cs').bind('loaded.jstree', function (e, data) {",
130           "    data.inst.open_all(); }).",
131           "    jstree({",
132           "    core: { animation: 188, html_titles: true },",
133           "    plugins: ['themeroller', 'html_data', 'ui'],",
134           "    themeroller: { item_open: 'ui-icon-minus',",
135           "      item_clsd: 'ui-icon-plus', item_leaf: 'ui-icon-gear'",
136           "    }",
137           "  });",
138           "  $('#cs').bind('select_node.jstree', function(e, data) {",
139           "    var q = $('.q', data.rslt.obj).first().text();",
140             "    if (q == 'root') q = '';",
141           "    $('#apps').dataTable().fnFilter(q, 4);",
142           "  });",
143           "  $('#cs').show();",
144           "});")._();
145   }
146 
content()147   @Override protected Class<? extends SubView> content() {
148     return QueuesBlock.class;
149   }
150 
percent(float f)151   static String percent(float f) {
152     return String.format("%.1f%%", f * 100);
153   }
154 
width(float f)155   static String width(float f) {
156     return String.format("width:%.1f%%", f * 100);
157   }
158 
left(float f)159   static String left(float f) {
160     return String.format("left:%.1f%%", f * 100);
161   }
162 }
163