ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nc...@apache.org
Subject [02/14] AMBARI-2677. Merge from branch-1.4.0 (ncole)
Date Fri, 19 Jul 2013 16:31:35 GMT
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index ef0f109..d84ff0e 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -406,6 +406,26 @@ var urls = {
       };
     }
   },
+  'service.metrics.yarn.gc': {
+    'real': '/clusters/{clusterName}/hosts/{resourceManager}/host_components/RESOURCEMANAGER?fields=metrics/jvm/gcTimeMillis[{fromSeconds},{toSeconds},{stepSeconds}]',
+    'mock': '/data/services/metrics/yarn/gc.json',
+    'testInProduction': true
+  },
+  'service.metrics.yarn.jobs_threads': {
+    'real': '/clusters/{clusterName}/hosts/{resourceManager}/host_components/RESOURCEMANAGER?fields=metrics/jvm/threadsRunnable[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/threadsBlocked[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/threadsWaiting[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/threadsTimedWaiting[{fromSeconds},{toSeconds},{stepSeconds}]',
+    'mock': '/data/services/metrics/yarn/jvm_threads.json',
+    'testInProduction': true
+  },
+  'service.metrics.yarn.rpc': {
+    'real': '/clusters/{clusterName}/hosts/{resourceManager}/host_components/RESOURCEMANAGER?fields=metrics/rpc/RpcQueueTime_avg_time[{fromSeconds},{toSeconds},{stepSeconds}]',
+    'mock': '/data/services/metrics/yarn/rpc.json',
+    'testInProduction': true
+  },
+  'service.metrics.yarn.jobs_heap': {
+    'real': '/clusters/{clusterName}/hosts/{resourceManager}/host_components/RESOURCEMANAGER?fields=metrics/jvm/memNonHeapUsedM[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/memNonHeapCommittedM[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/memHeapUsedM[{fromSeconds},{toSeconds},{stepSeconds}],metrics/jvm/memHeapCommittedM[{fromSeconds},{toSeconds},{stepSeconds}]',
+    'mock': '/data/services/metrics/yarn/jvm_heap.json',
+    'testInProduction': true
+  },
   'dashboard.cluster_metrics.cpu': {
     'real': '/clusters/{clusterName}/?fields=metrics/cpu[{fromSeconds},{toSeconds},{stepSeconds}]',
     'mock': '/data/cluster_metrics/cpu_1hr.json',

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/utils/app_graph.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/app_graph.js b/ambari-web/app/utils/app_graph.js
new file mode 100644
index 0000000..0cb6f53
--- /dev/null
+++ b/ambari-web/app/utils/app_graph.js
@@ -0,0 +1,441 @@
+/**
+ * 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.
+ */
+
+
+module.exports = {
+  create:function(domId, wfData, jobData, svgw, svgh, nodeHeight, labelFontSize, maxLabelWidth, axisPadding, stageFontSize) {
+    // initialize variables
+    var nodes = new Array();
+    var links = new Array();
+    var numNodes = 0;
+    var id = domId;
+    var formatDuration = this.formatDuration;
+
+    // create map from entity names to nodes
+    var existingNodes = new Array();
+    var jobData = (jobData) ? jobData : new Array();
+    var minStartTime = 0;
+    if (jobData.length > 0)
+      minStartTime = jobData[0].submitTime;
+    var maxFinishTime = 0;
+    // iterate through job data
+    for (var i = 0; i < jobData.length; i++) {
+      jobData[i].info = "jobId:"+jobData[i].name+"  \n"+
+        "nodeName:"+jobData[i].entityName+"  \n"+
+        "status:"+jobData[i].status+"  \n"+
+        "startTime:"+(new Date(jobData[i].submitTime).toUTCString())+"  \n"+
+        "duration:"+formatDuration(jobData[i].finishTime - jobData[i].submitTime);
+      jobData[i].state = jobData[i].status==="FINISHED";
+      minStartTime = Math.min(minStartTime, jobData[i].submitTime);
+      maxFinishTime = Math.max(maxFinishTime, jobData[i].finishTime);
+      // add a node to the nodes array and to a provided map of entity names to nodes
+      existingNodes[jobData[i].entityName] = jobData[i];
+      nodes.push(jobData[i]);
+      numNodes++;
+    }
+    var dag = eval('(' + wfData + ')').dag;
+    var sourceMarker = new Array();
+    var targetMarker = new Array();
+    var sourceMap = new Array();
+    // for each source node in the context, create links between it and its target nodes
+    for (var source in dag) {
+      var sourceNode = null;
+      if (source in existingNodes)
+        sourceNode = existingNodes[source];
+      for (var i = 0; i < dag[source].length; i++) {
+        var targetNode = null;
+        if (dag[source][i] in existingNodes)
+          targetNode = existingNodes[dag[source][i]];
+        // add a link between sourceNode and targetNode
+        // if source or target is null, add marker indicating unsubmitted job and return
+        if (sourceNode==null) {
+          if (targetNode==null)
+            continue;
+          sourceMarker.push(targetNode);
+          continue;
+        }
+        if (targetNode==null) {
+          targetMarker.push(sourceNode);
+          continue;
+        }
+        // add link between nodes
+        var state = false;
+        if (sourceNode.state && targetNode.state)
+          state = true;
+        links.push({"source":sourceNode, "target":targetNode, "state":state, "value":sourceNode.output});
+        // add source to map of targets to sources
+        if (!(targetNode.name in sourceMap))
+          sourceMap[targetNode.name] = new Array();
+        sourceMap[targetNode.name].push(sourceNode);
+      }
+    }
+  
+    // display the graph
+    // rules of thumb: nodeHeight = 20, labelFontSize = 14, maxLabelWidth = 180
+    //                 nodeHeight = 15, labelFontSize = 10, maxLabelWidth = 120
+    //                 nodeHeight = 40, labelFontSize = 20, maxLabelWidth = 260
+    //                 nodeHeight = 30, labelFontSize = 16
+    var nodeHeight = nodeHeight || 26;
+    var labelFontSize = labelFontSize || 12;
+    var maxLabelWidth = maxLabelWidth || 180;
+    var axisPadding = axisPadding || 30;
+    var stageFontSize = stageFontSize || 16;
+
+    // draw timeline graph
+    var margin = {"vertical":10, "horizontal":50};
+    var w = svgw - 2*margin.horizontal;
+
+    var startTime = minStartTime;
+    var elapsedTime = maxFinishTime - minStartTime;
+    var x = d3.time.scale.utc()
+      .domain([startTime, startTime+elapsedTime])
+      .range([0, w]);
+    var xrel = d3.time.scale()
+      .domain([0, elapsedTime])
+      .range([0, w]);
+
+    // process nodes and determine their x and y positions, width and height
+    var minNodeSpacing = nodeHeight/2;
+    var ends = new Array();
+    var maxIndex = 0;
+    nodes.sort(function(a,b){return a.name.localeCompare(b.name);});
+    for (var i = 0; i < numNodes; i++) {
+      var d = nodes[i];
+      d.x = x(d.submitTime);
+      d.w = x(d.finishTime) - x(d.submitTime);
+      if (d.w < d.stages.length*(nodeHeight-4)) {
+        d.w = d.stages.length*(nodeHeight-4);
+        if (d.x + d.w > w)
+          d.x = w - d.w;
+      }
+      var effectiveX = d.x
+      var effectiveWidth = d.w;
+      if (d.w < maxLabelWidth) {
+        effectiveWidth = maxLabelWidth;
+        if (d.x + effectiveWidth > w)
+          effectiveX = w - effectiveWidth;
+        else if (d.x > 0)
+          effectiveX = d.x+(d.w-maxLabelWidth)/2;
+      }
+      // select "lane" (slot for y-position) for this node
+      // starting at the slot above the node's closest source node (or 0, if none exists)
+      // and moving down until a slot is found that has no nodes within minNodeSpacing of this node
+      // excluding slots that contain more than one source of this node
+      var index = 0;
+      var rejectIndices = new Array();
+      if (d.name in sourceMap) {
+        var sources = sourceMap[d.name];
+        var closestSource = sources[0];
+        var indices = new Array();
+        for (var j = 0; j < sources.length; j++) {
+          if (sources[j].index in indices)
+            rejectIndices[sources[j].index] = true;
+          indices[sources[j].index] = true;
+          if (sources[j].submitTime + sources[j].elapsedTime > closestSource.submitTime + closestSource.elapsedTime)
+            closestSource = sources[j];
+        }
+        index = Math.max(0, closestSource.index-1);
+      }
+      while ((index in ends) && ((index in rejectIndices) || (ends[index]+minNodeSpacing >= effectiveX))) {
+        index++
+      }
+      ends[index] = Math.max(effectiveX + effectiveWidth);
+      maxIndex = Math.max(maxIndex, index);
+      d.y = index*2*nodeHeight + axisPadding;
+      d.h = nodeHeight;
+      d.index = index;
+    }
+
+    var h = 2*axisPadding + 2*nodeHeight*(maxIndex+1);
+    var realh = svgh - 2*margin.vertical;
+    var scale = 1;
+    if (h > realh)
+      scale = realh / h;
+    svgh = Math.min(svgh, h + 2*margin.vertical);
+    var svg = d3.select("div#" + id).append("svg:svg")
+      .attr("width", svgw+"px")
+      .attr("height", svgh+"px");
+    
+    var svgg = svg.append("g")
+      .attr("transform", "translate("+margin.horizontal+","+margin.vertical+") scale("+scale+")");
+
+    // add an untranslated white rectangle below everything
+    // so mouse doesn't have to be over nodes for panning/zooming
+    svgg.append("svg:rect")
+      .attr("x", 0)
+      .attr("y", 0)
+      .attr("width", svgw)
+      .attr("height", svgh/scale)
+      .attr("style", "fill:white;stroke:none");
+ 
+    // create axes
+    var topAxis = d3.svg.axis()
+      .scale(x)
+      .orient("bottom");
+    var bottomAxis = d3.svg.axis()
+      .scale(xrel)
+      .orient("top")
+      .tickFormat(function(x) { return formatDuration(x.getTime()); });
+    var topg = svgg.append("g")
+      .attr("class", "x axis top")
+      .call(topAxis);
+    topg.append("svg:text")
+      .attr("class", "axislabel")
+      .attr("x", -9)
+      .attr("y", 13)
+      .text("Time");
+    var botg = svgg.append("g")
+      .attr("class", "x axis bottom")
+      .call(bottomAxis)
+      .attr("transform", "translate(0,"+h+")")
+    botg.append("svg:text")
+      .attr("class", "axislabel")
+      .attr("x", -9)
+      .attr("y", -19)
+      .text("Elapsed");
+    botg.append("svg:text")
+      .attr("class", "axislabel")
+      .attr("x", -9)
+      .attr("y", -4)
+      .text("Time");
+
+  
+    // create a rectangle for each node
+    var boxes = svgg.append("svg:g").selectAll("rect")
+      .data(nodes)
+      .enter().append("svg:rect")
+      .attr("x", function(d) { return d.x; } )
+      .attr("y", function(d) { return d.y; } )
+      .attr("width", function(d) { return d.w; } )
+      .attr("height", function(d) { return d.h; } )
+      .attr("class", function (d) {
+        return "node " + (d.state ? " finished" : "");
+      })
+      .attr("id", function (d) {
+        return d.name;
+      })
+      .append("title")
+      .text(function(d) { return d.info; });
+  
+    // defs for arrowheads marked as to whether they link finished jobs or not
+    svgg.append("svg:defs").selectAll("arrowmarker")
+      .data(["finished", "unfinished", "stage"])
+      .enter().append("svg:marker")
+      .attr("id", String)
+      .attr("viewBox", "0 -5 10 10")
+      .attr("markerWidth", 6)
+      .attr("markerHeight", 6)
+      .attr("refX", function(d) { return (d==="stage") ? 5 : 3 })
+      .attr("orient", "auto")
+      .append("svg:path")
+      .attr("d", function(d) { return (d==="stage") ? "M0,-2L6,0L0,2" : "M0,-3L8,0L0,3" });
+    // defs for unsubmitted node marker
+    svgg.append("svg:defs").selectAll("circlemarker")
+      .data(["circle"])
+      .enter().append("svg:marker")
+      .attr("id", String)
+      .attr("viewBox", "-2 -2 18 18")
+      .attr("markerWidth", 10)
+      .attr("markerHeight", 10)
+      .attr("refX", 10)
+      .attr("refY", 5)
+      .attr("orient", "auto")
+      .append("svg:circle")
+      .attr("cx", 5)
+      .attr("cy", 5)
+      .attr("r", 5);
+
+    // create dangling links representing unsubmitted jobs
+    var markerWidth = nodeHeight/2;
+    var sourceMarker = svgg.append("svg:g").selectAll("line")
+      .data(sourceMarker)
+      .enter().append("svg:line")
+      .attr("x1", function(d) { return d.x - markerWidth; } )
+      .attr("x2", function(d) { return d.x; } )
+      .attr("y1", function(d) { return d.y; } )
+      .attr("y2", function(d) { return d.y + 3; } )
+      .attr("class", "source mark")
+      .attr("marker-start", "url(#circle)");
+    var targetMarker = svgg.append("svg:g").selectAll("line")
+      .data(targetMarker)
+      .enter().append("svg:line")
+      .attr("x1", function(d) { return d.x + d.w + markerWidth; } )
+      .attr("x2", function(d) { return d.x + d.w; } )
+      .attr("y1", function(d) { return d.y + d.h; } )
+      .attr("y2", function(d) { return d.y + d.h - 3; } )
+      .attr("class", "target mark")
+      .attr("marker-start", "url(#circle)");
+
+    // create links between the nodes
+    var lines = svgg.append("svg:g").selectAll("path")
+      .data(links)
+      .enter().append("svg:path")
+      .attr("d", function(d) {
+        var s = d.source;
+        var t = d.target;
+        var x1 = s.x + s.w;
+        var x2 = t.x;
+        var y1 = s.y;
+        var y2 = t.y;
+        if (y1==y2) {
+          y1 += s.h/2;
+          y2 += t.h/2;
+        } else if (y1 < y2) {
+          y1 += s.h;
+        } else {
+          y2 += t.h;
+        }
+        return "M "+x1+" "+y1+" L "+((x2+x1)/2)+" "+((y2+y1)/2)+" L "+x2+" "+y2;
+      } )
+      .attr("class", function (d) {
+        return "link" + (d.state ? " finished" : "");
+      })
+      .attr("marker-mid", function (d) {
+        return "url(#" + (d.state ? "finished" : "unfinished") + ")";
+      });
+  
+    // create text group for each node label
+    var text = svgg.append("svg:g").selectAll("g")
+      .data(nodes)
+      .enter().append("svg:g");
+  
+    // add a shadow copy of the node label (will have a lighter color and thicker
+    // stroke for legibility)
+    text.append("svg:text")
+      .attr("x", function(d) {
+        var goal = d.x + d.w/2;
+        var halfLabel = maxLabelWidth/2;
+        if (goal < halfLabel) return halfLabel;
+        else if (goal > w-halfLabel) return w-halfLabel;
+        return goal;
+      } )
+      .attr("y", function(d) { return d.y + d.h + labelFontSize; } )
+      .attr("class", "joblabel shadow")
+      .attr("style", "font: "+labelFontSize+"px sans-serif")
+      .text(function (d) {
+        return d.name;
+      });
+  
+    // add the main node label
+    text.append("svg:text")
+      .attr("x", function(d) {
+        var goal = d.x + d.w/2;
+        var halfLabel = maxLabelWidth/2;
+        if (goal < halfLabel) return halfLabel;
+        else if (goal > w-halfLabel) return w-halfLabel;
+        return goal;
+      } )
+      .attr("y", function(d) { return d.y + d.h + labelFontSize; } )
+      .attr("class", "joblabel")
+      .attr("style", "font: "+labelFontSize+"px sans-serif")
+      .text(function (d) {
+        return d.name;
+      });
+
+    // add node stage information
+    var topstageg = svgg.append("svg:g");
+    for (var i = 0; i < numNodes; i++) {
+      var parentg = topstageg.append("svg:g")
+        .attr("class", "parent");
+      var d = nodes[i];
+      var cr = d.h / 2 - 2;
+      var cy = d.y + cr + 2;
+      var cxSpacing = d.w / d.stages.length;
+      if (cxSpacing < 2*cr)
+        cxSpacing = 2*cr;
+      var cxBase = d.x + cxSpacing / 2;
+
+      for (var j = 0; j < d.stages.length; j++) {
+        var data = d.stages[j];
+        var stageg = parentg.append("svg:g")
+          .attr("id", "child"+j);
+        var cx = cxBase + j*cxSpacing;
+        var x1 = cx + cr;
+        var x2 = cx + cxSpacing - cr;
+        if (cxSpacing!=2*cr && j!=d.stages.length-1) {
+          var path = stageg.append("svg:path")
+            .attr("class", "link stage")
+            .attr("d", "M "+x1+" "+cy+" L "+((x1+x2)/2)+" "+cy+" L "+x2+" "+cy)
+            .attr("marker-end", "url(#stage)");
+        }
+        if (j==0) {
+          stageg.append("svg:rect")
+            .attr("class", "stage")
+            .attr("x", cx - cr)
+            .attr("y", cy - cr)
+            .attr("width", 2*cr)
+            .attr("height", 2*cr)
+            .append("title")
+            .text("Map stage with "+data+" task"+(data != 1 ? "s" : ""));
+        } else {
+          stageg.append("svg:circle")
+            .attr("class", "stage")
+            .attr("r", cr)
+            .attr("cx", cx)
+            .attr("cy", cy)
+            .append("title")
+            .text("Reduce stage with "+data+" task"+(data != 1 ? "s" : ""));
+        }
+        var fontSize = stageFontSize;
+        if (data > 9) fontSize = fontSize - 2;
+        if (data > 99) fontSize = fontSize - 4;
+        if (data > 999) fontSize = fontSize - 2;
+        if (data > 9999) fontSize = fontSize - 1;
+        stageg.append("svg:text")
+          .attr("class", "stagelabel")
+          .attr("x", cx)
+          .attr("y", cy)
+          .text(data)
+          .attr("style", "font: "+fontSize+"px sans-serif");
+      }
+    }
+
+    svg.call(d3.behavior.zoom().on("zoom", function() {
+      var left = Math.min(Math.max(d3.event.translate[0]+margin.horizontal, margin.horizontal-w*d3.event.scale*scale), margin.horizontal+w);
+      var top = Math.min(Math.max(d3.event.translate[1]+margin.vertical, margin.vertical-h*d3.event.scale*scale), margin.vertical+h);
+      svgg.attr("transform", "translate("+left+","+top+") scale("+(d3.event.scale*scale)+")");
+    }));
+  },
+  formatDuration:function(d) {
+    if (d==0) { return "0" }
+    var subseconds = parseInt(d) / 1000;
+    if (subseconds < 1)
+      return subseconds + "s";
+    var seconds = Math.floor(subseconds);
+    if ( seconds < 60 )
+      return seconds + "s";
+    var minutes = Math.floor(seconds / 60);
+    if ( minutes < 60 ) {
+      var x = seconds - 60*minutes;
+      return minutes + "m" + (x==0 ? "" : " " + x + "s");
+    }
+    var hours = Math.floor(minutes / 60);
+    if ( hours < 24 ) {
+      var x = minutes - 60*hours;
+      return hours + "h" + (x==0 ? "" : " " + x + "m");
+    }
+    var days = Math.floor(hours / 24);
+    if ( days < 7 ) {
+      var x = hours - 24*days;
+      return days + "d " + (x==0 ? "" : " " + x + "h");
+    }
+    var weeks = Math.floor(days / 7);
+    var x = days - 7*weeks;
+    return weeks + "w " + (x==0 ? "" : " " + x + "d");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index c7c1b5f..93cc25e 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -25,6 +25,10 @@ var globalPropertyToServicesMap = null;
 
 App.config = Em.Object.create({
 
+  isHDP2: function(){
+    return (stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === 1 ||
+      stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === 0)
+  }.property('App.currentStackVersionNumber'),
   preDefinedServiceConfigs: function(){
     var configs = this.get('preDefinedConfigProperties');
     var services = [];
@@ -42,23 +46,30 @@ App.config = Em.Object.create({
     return require('data/config_mapping');
   }.property('App.currentStackVersionNumber'),
   preDefinedConfigProperties: function() {
-    if (stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === 1 ||
-      stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === 0) {
+    if (this.get('isHDP2')) {
       return require('data/HDP2/config_properties').configProperties;
     }
     return require('data/config_properties').configProperties;
-  }.property('App.currentStackVersionNumber'),
-  preDefinedCustomConfigs: require('data/custom_configs'),
+  }.property('isHDP2'),
+  preDefinedCustomConfigs: function () {
+    if (this.get('isHDP2')) {
+      return require('data/HDP2/custom_configs');
+    }
+    return require('data/custom_configs');
+  }.property('isHDP2'),
   //categories which contain custom configs
   categoriesWithCustom: ['CapacityScheduler'],
   //configs with these filenames go to appropriate category not in Advanced
   customFileNames: function() {
     if (App.supports.capacitySchedulerUi) {
+      if(this.get('isHDP2')){
+        return ['capacity-scheduler.xml'];
+      }
       return ['capacity-scheduler.xml', 'mapred-queue-acls.xml'];
     } else {
       return [];
     }
-  }.property(''),
+  }.property('isHDP2'),
   /**
    * Cache of loaded configurations. This is useful in not loading
    * same configuration multiple times. It is populated in multiple
@@ -127,6 +138,20 @@ App.config = Em.Object.create({
       config.isRequired = true;
     }
   },
+  capacitySchedulerFilter: function () {
+    var yarnRegex = /^yarn\.scheduler\.capacity\.root\.(?!unfunded)([a-z]([\_\-a-z0-9]{0,50}))\.(acl_administer_jobs|acl_submit_jobs|state|user-limit-factor|maximum-capacity|capacity)$/i;
+    var self = this;
+    if(this.get('isHDP2')){
+      return function (_config) {
+        return (yarnRegex.test(_config.name));
+      }
+    } else {
+      return function (_config) {
+        return (_config.name.indexOf('mapred.capacity-scheduler.queue.') !== -1) ||
+          (/^mapred\.queue\.[a-z]([\_\-a-z0-9]{0,50})\.(acl-administer-jobs|acl-submit-job)$/i.test(_config.name));
+      }
+    }
+  }.property('isHDP2'),
   /**
    * return:
    *   configs,
@@ -311,64 +336,11 @@ App.config = Em.Object.create({
   addCustomConfigs: function (configs) {
     var preDefinedCustomConfigs = $.extend(true, [], this.get('preDefinedCustomConfigs'));
     var stored = configs.filter(function (_config) {
-      if (this.get('categoriesWithCustom').contains(_config.category)) return true;
+      return this.get('categoriesWithCustom').contains(_config.category);
     }, this);
-    var queueProperties = stored.filter(function (_config) {
-      if ((_config.name.indexOf('mapred.capacity-scheduler.queue.') !== -1) ||
-        (/mapred.queue.[a-z]([\_\-a-z0-9]{0,50}).acl-administer-jobs/i.test(_config.name)) ||
-        (/mapred.queue.[a-z]([\_\-a-z0-9]{0,50}).acl-submit-job/i.test(_config.name))) {
-        return true;
-      }
-    });
+    var queueProperties = stored.filter(this.get('capacitySchedulerFilter'));
     if (queueProperties.length) {
       queueProperties.setEach('isQueue', true);
-    } else {
-      queueProperties = preDefinedCustomConfigs.filterProperty('isQueue');
-      queueProperties.forEach(function (customConfig) {
-        this.setDefaultQueue(customConfig, 'default');
-        configs.push(customConfig);
-      }, this);
-    }
-  },
-  /**
-   * set values to properties of queue
-   * @param customConfig
-   * @param queueName
-   */
-  setDefaultQueue: function (customConfig, queueName) {
-    customConfig.name = customConfig.name.replace(/<queue-name>/, queueName);
-    //default values of queue
-    switch (customConfig.name) {
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.capacity':
-        customConfig.value = '100';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-capacity':
-        customConfig.value = '100';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.minimum-user-limit-percent':
-        customConfig.value = '100';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.user-limit-factor':
-        customConfig.value = '1';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-initialized-active-tasks':
-        customConfig.value = '200000';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.maximum-initialized-active-tasks-per-user':
-        customConfig.value = '100000';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.init-accept-jobs-factor':
-        customConfig.value = '10';
-        break;
-      case 'mapred.capacity-scheduler.queue.' + queueName + '.supports-priority':
-        customConfig.value = 'false';
-        break;
-      case 'mapred.queue.' + queueName + '.acl-submit-job':
-        customConfig.value = '*';
-        break;
-      case 'mapred.queue.' + queueName + '.acl-administer-jobs':
-        customConfig.value = '*';
-        break;
     }
   },
 
@@ -799,4 +771,4 @@ App.config = Em.Object.create({
     }
   }
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/utils/date.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/date.js b/ambari-web/app/utils/date.js
index 8716aa2..a5f7c83 100644
--- a/ambari-web/app/utils/date.js
+++ b/ambari-web/app/utils/date.js
@@ -38,6 +38,24 @@ module.exports = {
     return days[date.getDay()] + ', ' + months[date.getMonth()] + ' ' + this.dateFormatZeroFirst(date.getDate()) + ', ' + date.getFullYear() + ' ' + this.dateFormatZeroFirst(date.getHours()) + ':' + this.dateFormatZeroFirst(date.getMinutes());
   },
   /**
+   * Convert date-string 'DAY_OF_THE_WEEK, MONTH DAY, YEAR HOURS:MINUTES' to timestamp
+   * @param date_string
+   * @return {String}
+   */
+  dateUnformat: function(date_string) {
+    var date = date_string.substring(4);
+    var month = date.substring(1, 4);
+    var day = date.substring(5, 7);
+    var year = date.substring(9, 13);
+    var hours = date.substring(14, 16);
+    var minutes = date.substring(17, 19);
+
+    var months = this.dateMonths;
+    month = months.indexOf(month) + 1;
+    if (month < 10) month = '0' + month;
+    return year + month + day + hours + minutes;
+  },
+  /**
    * Convert timestamp to date-string 'DAY_OF_THE_WEEK MONTH DAY YEAR'
    * @param timestamp
    * @return {*}
@@ -53,6 +71,60 @@ module.exports = {
     return date.toDateString();
   },
   /**
+   * Convert date-string 'DAY_OF_THE_WEEK MONTH DAY YEAR' to the timestamp
+   * @param date_string
+   * @return {Number}
+   */
+  dateUnformatShort: function(date_string) {
+    var date = new Date(date_string);
+    return date.getTime();
+  },
+  /**
+   * Convert time in mseconds to 'HOURS:MINUTES:SECONDS'
+   * @param ms_interval
+   * @return string formatted date
+   */
+  dateFormatInterval:function (ms_interval) {
+    if (!validator.isValidInt(ms_interval)) return ms_interval;
+    var hours = Math.floor(ms_interval / (60 * 60000));
+    var divisor_for_minutes = ms_interval % (60 * 60000);
+    var minutes = Math.floor(divisor_for_minutes / 60000);
+    var divisor_for_seconds = divisor_for_minutes % 60000;
+    var seconds = (divisor_for_seconds / 1000).toFixed(2);
+
+    return (hours < 10 ? '0' : '') + hours + ':' + (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
+  },
+  /**
+   * Convert 'HOURS:MINUTES:SECONDS' to time in mseconds
+   * @param formattedDate date string
+   * @return time in mseconds
+   */
+  dateUnformatInterval: function(formattedDate) {
+    var formattedDateArray = formattedDate.split(' ');
+
+    if (Object.prototype.toString.call( formattedDateArray ) === '[object Array]' && formattedDateArray.length == 2) {
+      var oneMinMs = 60000;
+      var oneHourMs = 3600000;
+      var oneDayMs = 86400000;
+
+      if (formattedDateArray['1'] == 'ms') {
+        return formattedDateArray['0'];
+      } else if (formattedDateArray['1'] == 'secs') {
+        return formattedDateArray['0'] * 1000;
+      } else if (formattedDateArray['1'] == 'mins') {
+        return formattedDateArray['0'] * oneMinMs;
+      } else if (formattedDateArray['1'] == 'hours') {
+        return formattedDateArray['0'] * oneHourMs;
+      } else if (formattedDateArray['1'] == 'days') {
+        return formattedDateArray['0'] * oneDayMs;
+      } else {
+        console.warn('function dateUnformatInterval: Undefined format');
+      }
+    } else {
+      console.warn('function dateUnformatInterval: formattedDateArray');
+    }
+  },
+  /**
    * Convert time in mseconds to
    * 30 ms = 30 ms
    * 300 ms = 300 ms
@@ -69,7 +141,6 @@ module.exports = {
    */
   timingFormat:function (time) {
     var intTime  = parseInt(time);
-    if (!intTime) return null;
     var timeStr = intTime.toString();
     var lengthOfNumber = timeStr.length;
     var oneMinMs = 60000;

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index cb45cad..59922c2 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -203,8 +203,6 @@ Number.prototype.long2ip = function () {
  * @param {String} testUrl  URL to be used if app is not in test mode (!App.testMode)
  * @return {String} Formatted URL
  */
-App = require('app');
-
 App.formatUrl = function (urlTemplate, substitutes, testUrl) {
   var formatted = urlTemplate;
   if (urlTemplate) {
@@ -326,6 +324,10 @@ App.format = {
         return 'Pig';
       case 'PIG_SERVICE_CHECK':
         return 'Pig Check';
+      case 'MAPREDUCE2_SERVICE_CHECK':
+        return 'MapReduce2 Check';
+      case 'YARN_SERVICE_CHECK':
+        return 'YARN Check';
       case 'SQOOP':
         return 'Sqoop';
       case 'SQOOP_SERVICE_CHECK':
@@ -370,3 +372,11 @@ App.format = {
     return _taskStatus.toLowerCase();
   }
 };
+
+Array.prototype.removeAll = function(array){
+  var temp = array;
+  for(var i = 0 ; i < array.length ; i++ ){
+    temp = temp.without(array[i]);
+  }
+  return temp;
+};

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 83c1dbd..45664c8 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -75,6 +75,7 @@ require('views/main/admin/security/add/step4');
 require('views/main/dashboard');
 require('views/main/dashboard/service');
 require('views/main/dashboard/service/hdfs');
+require('views/main/dashboard/service/yarn');
 require('views/main/dashboard/service/mapreduce');
 require('views/main/dashboard/service/mapreduce2');
 require('views/main/dashboard/service/hbase');
@@ -127,6 +128,14 @@ require('views/main/service/info/metrics/hdfs/file_operations');
 require('views/main/service/info/metrics/hdfs/gc');
 require('views/main/service/info/metrics/hdfs/space_utilization');
 require('views/main/service/info/metrics/hdfs/block_status');
+require('views/main/service/info/metrics/yarn/gc');
+require('views/main/service/info/metrics/yarn/jvm_threads');
+require('views/main/service/info/metrics/yarn/jvm_heap');
+require('views/main/service/info/metrics/yarn/rpc');
+require('views/main/service/info/metrics/yarn/tasks_running_waiting');
+require('views/main/service/info/metrics/yarn/jobs_status');
+require('views/main/service/info/metrics/yarn/map_slots');
+require('views/main/service/info/metrics/yarn/reduce_slots');
 require('views/main/service/info/metrics/mapreduce/gc');
 require('views/main/service/info/metrics/mapreduce/jvm_threads');
 require('views/main/service/info/metrics/mapreduce/jvm_heap');
@@ -161,6 +170,7 @@ require('views/main/apps_view');
 require('views/main/apps/item_view');
 require('views/main/apps/item/bar_view');
 require('views/main/apps/item/dag_view');
+require('views/main/apps/item/app_view');
 require('views/main/mirroring_view');
 require('views/main/mirroring/dropdown_view');
 require('views/main/mirroring/dataset_view');

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/common/chart/linear_time.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js
index 0806474..c7afa8e 100644
--- a/ambari-web/app/views/common/chart/linear_time.js
+++ b/ambari-web/app/views/common/chart/linear_time.js
@@ -159,6 +159,8 @@ App.ChartLinearTimeView = Ember.View.extend({
     var nameNodeName = HDFSService ? HDFSService.get('nameNode.hostName') : "";
     var MapReduceService = App.MapReduceService.find().objectAt(0);
     var jobTrackerNode = MapReduceService ? MapReduceService.get('jobTracker.hostName') : "";
+    var YARNService = App.YARNService.find().objectAt(0);
+    var resourceManager = YARNService ? YARNService.get('resourceManagerNode.hostName') : "";
     var timeUnit = this.get('timeUnitSeconds');
     return {
       toSeconds: toSeconds,
@@ -166,7 +168,8 @@ App.ChartLinearTimeView = Ember.View.extend({
       stepSeconds: 15,
       hostName: hostName,
       nameNodeName: nameNodeName,
-      jobTrackerNode: jobTrackerNode
+      jobTrackerNode: jobTrackerNode,
+      resourceManager: resourceManager
     };
   },
   loadDataErrorCallback: function(xhr, textStatus, errorThrown){

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/common/configs/services_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/services_config.js b/ambari-web/app/views/common/configs/services_config.js
index 27b5fbe..97305fb 100644
--- a/ambari-web/app/views/common/configs/services_config.js
+++ b/ambari-web/app/views/common/configs/services_config.js
@@ -675,7 +675,9 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
   category: null,
   service: null,
   serviceConfigs: null,
-  customConfigs: require('data/custom_configs'),
+  customConfigs: function(){
+    return App.config.get('preDefinedCustomConfigs');
+  }.property('App.config.preDefinedCustomConfigs'),
   /**
    * configs filtered by capacity-scheduler category
    */
@@ -696,14 +698,20 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
     this.createEmptyQueue(this.get('customConfigs').filterProperty('isQueue'));
   },
   //list of fields which will be populated by default in a new queue
-  fieldsToPopulate: [
-    "mapred.capacity-scheduler.queue.<queue-name>.minimum-user-limit-percent",
-    "mapred.capacity-scheduler.queue.<queue-name>.user-limit-factor",
-    "mapred.capacity-scheduler.queue.<queue-name>.supports-priority",
-    "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks",
-    "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks-per-user",
-    "mapred.capacity-scheduler.queue.<queue-name>.init-accept-jobs-factor"
-  ],
+  fieldsToPopulate: function(){
+    if(App.config.get('isHDP2')){
+      return ["yarn.scheduler.capacity.root.<queue-name>.user-limit-factor",
+      "yarn.scheduler.capacity.root.<queue-name>.state"];
+    }
+    return [
+      "mapred.capacity-scheduler.queue.<queue-name>.minimum-user-limit-percent",
+      "mapred.capacity-scheduler.queue.<queue-name>.user-limit-factor",
+      "mapred.capacity-scheduler.queue.<queue-name>.supports-priority",
+      "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks",
+      "mapred.capacity-scheduler.queue.<queue-name>.maximum-initialized-active-tasks-per-user",
+      "mapred.capacity-scheduler.queue.<queue-name>.init-accept-jobs-factor"
+    ];
+  }.property('App.config.isHDP2'),
   /**
    * create empty queue
    * take some queue then copy it and set all config values to null
@@ -741,33 +749,36 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       queues.push({
         name: queueName,
         color: this.generateColor(queueName),
-        configs: this.filterConfigsByQueue(queueName, configs)
+        configs: this.groupConfigsByQueue(queueName, configs)
       })
     }, this);
     return queues;
   }.property('queueObserver'),
   /**
-   * filter configs by queue
+   * group configs by queue
    * @param queueName
    * @param configs
    */
-  filterConfigsByQueue: function (queueName, configs) {
-    var customConfigs = this.get('customConfigs');
+  groupConfigsByQueue: function (queueName, configs) {
+    var customConfigs = [];
     var queue = [];
+    this.get('customConfigs').forEach(function(_config){
+      var copy = $.extend({}, _config);
+      copy.name = _config.name.replace('<queue-name>', queueName);
+      customConfigs.push(copy);
+    });
     configs.forEach(function (config) {
-      var customConfig = customConfigs.findProperty('name', config.name.replace('queue.' + queueName, 'queue.<queue-name>'));
-      if ((config.name.indexOf('mapred.capacity-scheduler.queue.' + queueName) !== -1) ||
-        (config.name.indexOf('mapred.queue.' + queueName) !== -1)) {
-        if (customConfig) {
-          config.set('description', customConfig.description);
-          config.set('displayName', customConfig.displayName);
-          config.set('isRequired', customConfig.isRequired);
-          config.set('unit', customConfig.unit);
-          config.set('displayType', customConfig.displayType);
-          config.set('valueRange', customConfig.valueRange);
-          config.set('isVisible', customConfig.isVisible);
-          config.set('index', customConfig.index);
-        }
+      var customConfig = customConfigs.findProperty('name', config.get('name'));
+      if (customConfig) {
+        config.set('description', customConfig.description);
+        config.set('displayName', customConfig.displayName);
+        config.set('isRequired', customConfig.isRequired);
+        config.set('unit', customConfig.unit);
+        config.set('displayType', customConfig.displayType);
+        config.set('valueRange', customConfig.valueRange);
+        config.set('isVisible', customConfig.isVisible);
+        config.set('inTable', customConfig.inTable);
+        config.set('index', customConfig.index);
         queue.push(config);
       }
     });
@@ -778,9 +789,9 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
     return queue;
   },
   /**
-   * add missing properties to queue
+   * add missing properties to queue when they don't come from server
    * @param queue
-   * @param queueName
+   * @param customConfigs
    */
   addMissingProperties: function (queue, queueName) {
     var customConfigs = this.get('customConfigs');
@@ -796,7 +807,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
     }, this);
   },
   /**
-   * format table content from queues
+   * convert queues to table content
    */
   tableContent: function () {
     var result = [];
@@ -809,18 +820,35 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       var queueObject = {
         name: queue.name,
         color: 'background-color:' + queue.color + ';',
-        users: usersAndGroups[0],
-        groups: usersAndGroups[1],
-        capacity: queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.capacity').get('value'),
-        maxCapacity: queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.maximum-capacity').get('value'),
-        minUserLimit: queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.minimum-user-limit-percent').get('value'),
-        userLimitFactor: queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.user-limit-factor').get('value'),
-        supportsPriority: queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.supports-priority').get('value')
+        configs: this.sortByIndex(queue.configs.filterProperty('inTable'))
       };
+      //push acl_submit_jobs users
+      queueObject.configs.unshift({
+        value: usersAndGroups[1],
+        inTable: true,
+        displayName: Em.I18n.t('common.users')
+      });
+      //push acl_submit_jobs groups
+      queueObject.configs.unshift({
+        value: usersAndGroups[0],
+        inTable: true,
+        displayName: Em.I18n.t('services.mapReduce.config.queue.groups')
+      });
       result.push(queueObject);
     }, this);
     return result;
   }.property('queues'),
+  /**
+   * create headers depending on existed properties in queue
+   */
+  tableHeaders: function(){
+    var headers = [
+      Em.I18n.t('services.mapReduce.config.queue.name')
+    ];
+    return (this.get('tableContent').length) ?
+      headers.concat(this.get('tableContent').objectAt(0).configs.filterProperty('inTable').mapProperty('displayName')):
+      headers;
+  }.property('tableContent'),
   queueObserver: null,
   /**
    * uses as template for adding new queue
@@ -873,7 +901,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       if (config.isQueue) {
         serviceConfigs.push(config);
       }
-    });
+    }, this);
     adminConfig.set('value', admin.join(' '));
     submitConfig.set('value', submit.join(' '));
     this.set('queueObserver', new Date().getTime());
@@ -919,10 +947,9 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
         } else {
           _config.set('value', queue.configs.findProperty('name', _config.get('name')).get('value').toString());
         }
-        //comparison executes including 'queue.<queue-name>' to avoid false matches
-        _config.set('name', configName.replace('queue.' + queue.name, 'queue.' + queue.configs.findProperty('name', 'queueName').get('value')));
+        _config.set('name', configName.replace(queueNamePrefix + queue.name, queueNamePrefix + queue.configs.findProperty('name', 'queueName').get('value')));
       }
-    });
+    }, this);
     this.set('queueObserver', new Date().getTime());
   },
   pieChart: App.ChartPieView.extend({
@@ -943,7 +970,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       queues.forEach(function (queue) {
         data.push({
           label: queue.name,
-          value: parseInt(queue.configs.findProperty('name', 'mapred.capacity-scheduler.queue.' + queue.name + '.capacity').get('value')),
+          value: value,
           color: queue.color
         })
       });
@@ -1060,10 +1087,10 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       content: function () {
         var content = (queueName) ? self.get('queues').findProperty('name', queueName) : self.get('emptyQueue');
         var configs = [];
-        var tableContent = self.get('tableContent');
         // copy of queue configs
         content.configs.forEach(function (config, index) {
-          if (config.name == 'mapred.capacity-scheduler.queue.' + content.name + '.capacity') {
+          if(config.get('name').substr(-9, 9) === '.capacity') {
+            //added validation function for capacity property
             config.reopen({
               validate: function () {
                 var value = this.get('value');
@@ -1112,6 +1139,19 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
               config.set('value', false);
             }
           }
+          if(config.name === 'yarn.scheduler.capacity.root.' + content.name + '.state'){
+            config.reopen({
+              validate: function(){
+                var value = this.get('value');
+                this._super();
+                if(!this.get('errorMessage')){
+                  if(!(value === 'STOPPED' || value === 'RUNNING')){
+                    this.set('errorMessage', 'State value should be RUNNING or STOPPED');
+                  }
+                }
+              }.observes('value')
+            })
+          }
           configs[index] = App.ServiceConfigProperty.create(config);
         });
         content = {
@@ -1167,8 +1207,8 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
        */
       insertExtraConfigs: function (content) {
         var that = this;
-        var admin = content.configs.findProperty('name', 'mapred.queue.' + content.name + '.acl-administer-jobs').get('value');
-        var submit = content.configs.findProperty('name', 'mapred.queue.' + content.name + '.acl-submit-job').get('value');
+        var admin = content.configs.findProperty('name', self.getUserAndGroupNames(content.name)[1]).get('value');
+        var submit = content.configs.findProperty('name', self.getUserAndGroupNames(content.name)[0]).get('value');
         admin = (admin) ? admin.split(' ') : [''];
         submit = (submit) ? submit.split(' ') : [''];
         if (admin.length < 2) {
@@ -1177,7 +1217,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
         if (submit.length < 2) {
           submit.push('');
         }
-        var newField = App.ServiceConfigProperty.create({
+        var nameField = App.ServiceConfigProperty.create({
           name: 'queueName',
           displayName: Em.I18n.t('services.mapReduce.extraConfig.queue.name'),
           description: Em.I18n.t('services.mapReduce.description.queue.name'),
@@ -1216,11 +1256,11 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
           isEditable: self.get('canEdit'),
           index: 0
         });
-        newField.validate();
-        content.configs.unshift(newField);
+        nameField.validate();
+        content.configs.unshift(nameField);
 
         var submitUser = App.ServiceConfigProperty.create({
-          name: 'mapred.queue.' + content.name + '.acl-submit-job',
+          name: self.getUserAndGroupNames(content.name)[0],
           displayName: Em.I18n.t('common.users'),
           value: submit[0],
           description: Em.I18n.t('services.mapReduce.description.queue.submit.user'),
@@ -1233,7 +1273,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
         });
 
         var submitGroup = App.ServiceConfigProperty.create({
-          name: 'mapred.queue.' + content.name + '.acl-submit-job',
+          name: self.getUserAndGroupNames(content.name)[0],
           displayName: Em.I18n.t('services.mapReduce.config.queue.groups'),
           description: Em.I18n.t('services.mapReduce.description.queue.submit.group'),
           value: submit[1],
@@ -1246,7 +1286,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
         });
 
         var adminUser = App.ServiceConfigProperty.create({
-          name: 'mapred.queue.' + content.name + '.acl-administer-jobs',
+          name: self.getUserAndGroupNames(content.name)[1],
           displayName: Em.I18n.t('services.mapReduce.config.queue.adminUsers'),
           description: Em.I18n.t('services.mapReduce.description.queue.admin.user'),
           value: admin[0],
@@ -1259,7 +1299,7 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
         });
 
         var adminGroup = App.ServiceConfigProperty.create({
-          name: 'mapred.queue.' + content.name + '.acl-administer-jobs',
+          name: self.getUserAndGroupNames(content.name)[1],
           displayName: Em.I18n.t('services.mapReduce.config.queue.adminGroups'),
           value: admin[1],
           description: Em.I18n.t('services.mapReduce.description.queue.admin.group'),
@@ -1303,8 +1343,8 @@ App.ServiceConfigCapacityScheduler = App.ServiceConfigsByCategoryView.extend({
       },
       /**
        * Validate by follow rules:
-       * Users can be blank. If this is blank, Groups must not be blank.
-       * Groups can be blank. If this is blank, Users must not be blank.
+       * Users can be blank. If it is blank, Groups must not be blank.
+       * Groups can be blank. If it is blank, Users must not be blank.
        * @param context
        * @param boundConfig
        */

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/common/quick_view_link_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/quick_view_link_view.js b/ambari-web/app/views/common/quick_view_link_view.js
index 7c14cdf..624d40a 100644
--- a/ambari-web/app/views/common/quick_view_link_view.js
+++ b/ambari-web/app/views/common/quick_view_link_view.js
@@ -54,7 +54,14 @@ App.QuickViewLinks = Em.View.extend({
           }
         }
         break;
+      case "YARN":
+        host = App.singleNodeInstall ? App.singleNodeAlias : components.findProperty('componentName', 'RESOURCEMANAGER').get('host.publicHostName');
+        break;
+      case "MAPREDUCE2":
+        host = App.singleNodeInstall ? App.singleNodeAlias : components.findProperty('componentName', 'HISTORYSERVER').get('host.publicHostName');
+        break;
     }
+
     if (!host) {
       return [
         {
@@ -74,6 +81,8 @@ App.QuickViewLinks = Em.View.extend({
   linkTarget: function () {
     switch (this.get('content.serviceName').toLowerCase()) {
       case "hdfs":
+      case "yarn":
+      case "mapreduce2":
       case "mapreduce":
       case "hbase":
       case "oozie":

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/common/table_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/table_view.js b/ambari-web/app/views/common/table_view.js
index d092980..df574ce 100644
--- a/ambari-web/app/views/common/table_view.js
+++ b/ambari-web/app/views/common/table_view.js
@@ -191,8 +191,8 @@ App.TableView = Em.View.extend({
       this.get('filterConditions').push(filterCondition);
     }
     this.saveFilterConditions();
+
     this.filtersUsedCalc();
-    this.filter();
   },
 
   saveFilterConditions: function() {

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/apps/item/app_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/apps/item/app_view.js b/ambari-web/app/views/main/apps/item/app_view.js
new file mode 100644
index 0000000..b279d28
--- /dev/null
+++ b/ambari-web/app/views/main/apps/item/app_view.js
@@ -0,0 +1,136 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var sort = require('views/common/sort_view');
+var appGraph = require('utils/app_graph');
+
+App.MainAppsItemAppView = Em.View.extend({
+  templateName: require('templates/main/apps/item/app'),
+  elementId : 'jobs',
+  content:function(){
+    return this.get('controller.content.jobs');
+  }.property('controller.content.jobs'),
+
+  classNames:['table','dataTable'],
+  /**
+   * convert content to special jobs object
+   */
+  jobs: function(){
+    var c = this.get('content');
+    var result = [];
+    c.forEach(function(item, index){
+      result[index] = new Object({
+        'name' : item.get('id'),
+        'type' : item.get('app_type'),
+        'entityName' : item.get('workflow_entity_name'),
+        'status' : item.get('status'),
+        'submitTime' : item.get('submit_time'),
+        'finishTime' : item.get('finish_time'),
+        'elapsedTime' : appGraph.formatDuration(item.get('elapsed_time')),
+        'numStages' : item.get('num_stages'),
+        'stages' : item.get('stages')
+      })
+    });
+    return result;
+  }.property('content'),
+
+  loaded : false,
+
+  hasManyJobs: function(){
+    return (this.get('content') && this.get('content').length > 1);
+  }.property('content'),
+
+  onLoad:function (){
+    if(!this.get('controller.content.loadAllJobs') || this.get('loaded')){
+      return;
+    }
+
+    this.set('loaded', true);
+
+    var self = this;
+
+    Ember.run.next(function(){
+      self.draw();
+    });
+
+  }.observes('controller.content.loadAllJobs'),
+
+  resizeModal: function () {
+    var modal = $('.modal');
+    var body = $('body');
+    modal.find('.modal-body').first().css('max-height', 'none');
+    var modalHeight = modal.height() + 300;
+    var bodyHeight = body.height();
+    if (modalHeight > bodyHeight) {
+      modal.css('top', '20px');
+      $('.modal-body').height(bodyHeight - 180);
+    } else {
+      modal.css('top', (bodyHeight - modalHeight) / 2 + 'px');
+    }
+
+    var modalWidth = modal.width();
+    var bodyWidth = body.width();
+    if (modalWidth > bodyWidth) {
+      modal.css('left', '10px');
+      modal.width(bodyWidth - 20);
+    } else {
+      modal.css('left', (bodyWidth - modalWidth) / 2 + 'px');
+    }
+  },
+
+  didInsertElement: function(){
+    this.onLoad();
+  },
+
+  draw: function(){
+    var dagSchema = this.get('controller.content.workflowContext');
+    var jobs = this.get('jobs');
+    this.resizeModal();
+    appGraph.create('app_graph', dagSchema, jobs, this.$().width(), 300);
+  },
+  sortView: sort.wrapperView,
+  nameSort: sort.fieldView.extend({
+    name:'workflow_entity_name',
+    displayName: Em.I18n.t('apps.item.dag.job')
+  }),
+  idSort: sort.fieldView.extend({
+    name:'id',
+    displayName: Em.I18n.t('apps.item.dag.jobId')
+  }),
+  typeSort: sort.fieldView.extend({
+    name:'app_type',
+    displayName: Em.I18n.t('apps.item.dag.type')
+  }),
+  statusSort: sort.fieldView.extend({
+    name:'status',
+    displayName: Em.I18n.t('apps.item.dag.status')
+  }),
+  numStagesSort: sort.fieldView.extend({
+    name:'num_stages',
+    displayName: Em.I18n.t('apps.item.dag.num_stages')
+  }),
+  stagesSort: sort.fieldView.extend({
+    name:'stages',
+    displayName: Em.I18n.t('apps.item.dag.stages')
+  }),
+  durationSort: sort.fieldView.extend({
+    name:'elapsed_time',
+    displayName: Em.I18n.t('apps.item.dag.duration')
+  })
+});

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/apps/item_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/apps/item_view.js b/ambari-web/app/views/main/apps/item_view.js
index 29300d1..b9acd61 100644
--- a/ambari-web/app/views/main/apps/item_view.js
+++ b/ambari-web/app/views/main/apps/item_view.js
@@ -17,23 +17,13 @@
  */
 
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 App.MainAppsItemView = Em.View.extend({
   tagName: 'tr',
   classNames : ['containerRow'],
   templateName:require('templates/main/apps/item'),
-  menuTabs:[
-    Em.Object.create({
-      label:Em.I18n.t('apps.dagCharts.popup.dag'),
-      active:'active',
-      content:'App.MainAppsItemDagView'
-    }),
-    Em.Object.create({
-      label:Em.I18n.t('apps.dagCharts.popup.tasks'),
-      active:'',
-      content:'App.MainAppsItemBarView'
-    })
-  ],
+  menuTabs:[],
   activeTab:null,
   switchTab:function(event){
     var tabs = this.get('menuTabs');
@@ -48,10 +38,30 @@ App.MainAppsItemView = Em.View.extend({
     this.set('activeTab', event.context);
   },
   didInsertElement: function(){
-    var tabs = this.get('menuTabs');
-    tabs[0].set('active', 'active');
-    tabs[1].set('active', '');
-    this.set('activeTab', tabs[0]);
+    if (!App.testMode && stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === -1) {
+      var tabs = [
+        Em.Object.create({
+          label:Em.I18n.t('apps.dagCharts.popup.dag'),
+          active:'active',
+          content:'App.MainAppsItemDagView'
+        }),
+        Em.Object.create({
+          label:Em.I18n.t('apps.dagCharts.popup.tasks'),
+          active:'',
+          content:'App.MainAppsItemBarView'
+        })];
+      this.set('menuTabs', tabs);
+      this.set('activeTab', tabs[0]);
+    } else {
+      var tabs = [
+        Em.Object.create({
+          label:Em.I18n.t('apps.dagCharts.popup.dag'),
+          active:'active',
+          content:'App.MainAppsItemAppView'
+        })];
+      this.set('menuTabs', tabs);
+      this.set('activeTab', tabs[0]);
+    }
   },
   containerView: Em.ContainerView.extend({
     onchange:function(){

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/apps_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/apps_view.js b/ambari-web/app/views/main/apps_view.js
index a644667..9d8f110 100644
--- a/ambari-web/app/views/main/apps_view.js
+++ b/ambari-web/app/views/main/apps_view.js
@@ -102,7 +102,7 @@ App.MainAppsView = Em.View.extend({
     class: "sorting",
     widthClass: "",
     content: null,
-    defaultColumn: 8,
+    defaultColumn: 9,
 
     didInsertElement: function () {
       this.set("widthClass", "col" + this.get('content.index'));
@@ -160,13 +160,21 @@ App.MainAppsView = Em.View.extend({
     fieldType: 'input-small'
   }),
   /**
+   * Filter-field for tags.
+   * Based on <code>filters</code> library
+   */
+  tagFilterView: filters.createTextView({
+    valueBinding: "controller.filterObject.tagSearch",
+    fieldType: 'input-super-mini'
+  }),
+  /**
    * Filter-field for type.
    * Based on <code>filters</code> library
    */
   typeFilterView: filters.createSelectView({
     fieldType: 'input-small',
     valueBinding: "controller.filterObject.runType",
-    content: ['Any', 'Pig', 'Hive', 'MapReduce']
+    content: ['Any', 'Pig', 'Hive', 'MapReduce', 'Yarn']
   }),
 
   /**
@@ -216,22 +224,6 @@ App.MainAppsView = Em.View.extend({
     valueBinding: "controller.filterObject.jobs"
   }),
   /**
-   * Filter-field for Input.
-   * Based on <code>filters</code> library
-   */
-  inputFilterView: filters.createTextView({
-    fieldType: 'input-super-mini',
-    valueBinding: "controller.filterObject.input"
-  }),
-  /**
-   * Filter-field for Output.
-   * Based on <code>filters</code> library
-   */
-  outputFilterView: filters.createTextView({
-    fieldType: 'input-super-mini',
-    valueBinding: "controller.filterObject.output"
-  }),
-  /**
    * Filter-field for Duration.
    * Based on <code>filters</code> library
    */
@@ -354,4 +346,4 @@ App.MainAppsView = Em.View.extend({
 
   })
 
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/dashboard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard.js b/ambari-web/app/views/main/dashboard.js
index 36d4f83..d0e5c58 100644
--- a/ambari-web/app/views/main/dashboard.js
+++ b/ambari-web/app/views/main/dashboard.js
@@ -395,6 +395,10 @@ App.MainDashboardView = Em.View.extend({
           vName = App.MainDashboardServiceHdfsView;
           item2 = App.HDFSService.find(item.get('id'));
           break;
+        case "YARN":
+          vName = App.MainDashboardServiceYARNView;
+          item2 = App.YARNService.find(item.get('id'));
+          break;
         case "MAPREDUCE":
           vName = App.MainDashboardServiceMapreduceView;
           item2 = App.MapReduceService.find(item.get('id'));

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/dashboard/service/mapreduce.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/service/mapreduce.js b/ambari-web/app/views/main/dashboard/service/mapreduce.js
index fadb29c..11b9044 100644
--- a/ambari-web/app/views/main/dashboard/service/mapreduce.js
+++ b/ambari-web/app/views/main/dashboard/service/mapreduce.js
@@ -123,4 +123,4 @@ App.MainDashboardServiceMapreduceView = App.MainDashboardServiceView.extend({
   taskTrackerComponent: function () {
     return App.HostComponent.find().findProperty('componentName', 'TASKTRACKER');
   }.property()
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/dashboard/service/yarn.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/dashboard/service/yarn.js b/ambari-web/app/views/main/dashboard/service/yarn.js
new file mode 100644
index 0000000..a0bf78b
--- /dev/null
+++ b/ambari-web/app/views/main/dashboard/service/yarn.js
@@ -0,0 +1,106 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var date = require('utils/date');
+
+App.MainDashboardServiceYARNView = App.MainDashboardServiceView.extend({
+  templateName: require('templates/main/dashboard/service/yarn'),
+  serviceName: 'YARN',
+
+  nodeWebUrl: function () {
+    var hostName = this.get('service.resourceManagerNode').get('publicHostName');
+    return "http://" + (App.singleNodeInstall ? App.singleNodeAlias : hostName)  + ":8088";
+  }.property('service.resourceManagerNode'),
+
+  nodeHeap: function () {
+    var memUsed = this.get('service').get('jvmMemoryHeapUsed') * 1000000;
+    var memCommitted = this.get('service').get('jvmMemoryHeapCommitted') * 1000000;
+    var percent = memCommitted > 0 ? ((100 * memUsed) / memCommitted) : 0;
+    return this.t('dashboard.services.hdfs.nodes.heapUsed').format(memUsed.bytesToSize(1, 'parseFloat'), memCommitted.bytesToSize(1, 'parseFloat'), percent.toFixed(1));
+
+  }.property('service.jvmMemoryHeapUsed', 'service.jvmMemoryHeapCommitted'),
+
+  summaryHeader: function () {
+    var text = this.t("dashboard.services.yarn.summary");
+    var svc = this.get('service');
+    var totalCount = svc.get('nodeManagerNodes').get('length');
+    return text.format(totalCount, totalCount);
+  }.property('service.nodeManagerNodes'),
+  
+  nodeManagerComponent: function () {
+    return App.HostComponent.find().findProperty('componentName', 'NODEMANAGER');
+  }.property(),
+  
+  yarnClientComponent: function () {
+    return App.HostComponent.find().findProperty('componentName', 'YARN_CLIENT');
+  }.property(),
+  
+  nodeUptime: function () {
+    var uptime = this.get('service').get('resourceManagerStartTime');
+    if (uptime && uptime > 0){
+      var diff = (new Date()).getTime() - uptime;
+      if (diff < 0) {
+        diff = 0;
+      }
+      var formatted = date.timingFormat(diff);
+      return this.t('dashboard.services.uptime').format(formatted);
+    }
+    return this.t('services.service.summary.notRunning');
+  }.property("service.resourceManagerStartTime"),
+
+  nodeHeap: function () {
+    var memUsed = this.get('service').get('jvmMemoryHeapUsed') * 1000000;
+    var memCommitted = this.get('service').get('jvmMemoryHeapCommitted') * 1000000;
+    var percent = memCommitted > 0 ? ((100 * memUsed) / memCommitted) : 0;
+    return this.t('dashboard.services.hdfs.nodes.heapUsed').format(memUsed.bytesToSize(1, 'parseFloat'), memCommitted.bytesToSize(1, 'parseFloat'), percent.toFixed(1));
+  }.property('service.jvmMemoryHeapUsed', 'service.jvmMemoryHeapCommitted'),
+
+  nodeManagersLive: function () {
+    var nodeManagers = this.get('service.nodeManagerNodes.length');
+    var nodeManagersLive = this.get('service.nodeManagerLiveNodes.length');
+    return this.t('dashboard.services.yarn.nodeManagers.live.msg').format(nodeManagersLive, nodeManagers);
+  }.property('service.nodeManagerNodes', 'service.nodeManagerLiveNodes'),
+
+  nodeManagersStatus: function () {
+    var nmActive = this.get('service.nodeManagersCountActive');
+    var nmLost = this.get('service.nodeManagersCountLost');
+    var nmUnhealthy = this.get('service.nodeManagersCountUnhealthy');
+    var nmRebooted = this.get('service.nodeManagersCountRebooted');
+    var nmDecom = this.get('service.nodeManagersCountDecommissioned');
+    return this.t('dashboard.services.yarn.nodeManagers.status.msg').format(nmActive, nmLost, nmUnhealthy, nmRebooted, nmDecom);
+  }.property('service.nodeManagersCountActive', 'service.nodeManagersCountLost', 
+      'service.nodeManagersCountUnhealthy', 'service.nodeManagersCountRebooted', 'service.nodeManagersCountDecommissioned'),
+
+  containers: function () {
+    var allocated = this.get('service.containersAllocated');
+    var pending = this.get('service.containersPending');
+    var reserved = this.get('service.containersReserved');
+    return this.t('dashboard.services.yarn.containers.msg').format(allocated, pending, reserved);
+  }.property('service.containersAllocated', 'service.containersPending', 'service.containersReserved'),
+
+  apps: function () {
+    var appsSubmitted = this.get('service.appsSubmitted');
+    var appsRunning = this.get('service.appsRunning');
+    var appsPending = this.get('service.appsPending');
+    var appsCompleted = this.get('service.appsCompleted');
+    var appsKilled = this.get('service.appsKilled');
+    var appsFailed = this.get('service.appsFailed');
+    return this.t('dashboard.services.yarn.apps.msg').format(appsSubmitted, appsRunning, appsPending, appsCompleted, appsKilled, appsFailed);
+  }.property('service.appsSubmitted', 'service.appsRunning', 'service.appsPending', 'service.appsCompleted', 'service.appsKilled', 'service.appsFailed'),
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/menu.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js
index 6f61429..0ca08d6 100644
--- a/ambari-web/app/views/main/menu.js
+++ b/ambari-web/app/views/main/menu.js
@@ -31,17 +31,14 @@ App.MainMenuView = Em.CollectionView.extend({
       { label:Em.I18n.t('menu.item.dashboard'), routing:'dashboard', active:'active'},
       { label:Em.I18n.t('menu.item.heatmaps'), routing:'charts'},
       { label:Em.I18n.t('menu.item.services'), routing:'services'},
-      { label:Em.I18n.t('menu.item.hosts'), routing:'hosts'}
+      { label:Em.I18n.t('menu.item.hosts'), routing:'hosts'},
+      { label:Em.I18n.t('menu.item.jobs'), routing:'apps'}
     ];
 
     if (App.supports.mirroring) {
       result.push({ label:Em.I18n.t('menu.item.mirroring'), routing:'mirroring'});
     }
 
-    if (stringUtils.compareVersions(App.get('currentStackVersionNumber'), "2.0") === -1) {
-      result.push({ label:Em.I18n.t('menu.item.jobs'), routing:'apps'});
-    }
-
     if (App.get('isAdmin')) {
       result.push({ label:Em.I18n.t('menu.item.admin'), routing:'admin'});
     }
@@ -84,4 +81,4 @@ App.MainMenuView = Em.CollectionView.extend({
 
     templateName: require('templates/main/menu_item')
   })
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/gc.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/gc.js b/ambari-web/app/views/main/service/info/metrics/yarn/gc.js
new file mode 100644
index 0000000..265a56d
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/gc.js
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_GC = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-gc",
+  title: Em.I18n.t('services.service.info.metrics.yarn.gc'),
+  yAxisFormatter: App.ChartLinearTimeView.TimeElapsedFormatter,
+
+  ajaxIndex: 'service.metrics.yarn.gc',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.jvm) {
+      for ( var name in jsonData.metrics.jvm) {
+        var displayName;
+        var seriesData = jsonData.metrics.jvm[name];
+        switch (name) {
+          case "gcTimeMillis":
+            displayName = Em.I18n.t('services.service.info.metrics.yarn.gc.displayNames.gcTimeMillis');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/jobs_status.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/jobs_status.js b/ambari-web/app/views/main/service/info/metrics/yarn/jobs_status.js
new file mode 100644
index 0000000..87d2a72
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/jobs_status.js
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_JobsStatus = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-jobs-status",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus'),
+  renderer: 'line',
+
+  ajaxIndex: 'service.metrics.mapreduce.jobs_status',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.mapred && jsonData.metrics.mapred.jobtracker) {
+      for ( var name in jsonData.metrics.mapred.jobtracker) {
+        var displayName;
+        var seriesData = jsonData.metrics.mapred.jobtracker[name];
+        switch (name) {
+          case "jobs_running":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus.displayNames.jobsRunning');
+            break;
+          case "jobs_failed":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus.displayNames.jobsFailed');
+            break;
+          case "jobs_completed":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus.displayNames.jobsCompleted');
+            break;
+          case "jobs_preparing":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus.displayNames.jobsPreparing');
+            break;
+          case "jobs_submitted":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jobsStatus.displayNames.jobsSubmitted');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/jvm_heap.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/jvm_heap.js b/ambari-web/app/views/main/service/info/metrics/yarn/jvm_heap.js
new file mode 100644
index 0000000..9ce2d1d
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/jvm_heap.js
@@ -0,0 +1,71 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_JVMHeap = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-jvm-heap",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.jvmHeap'),
+  yAxisFormatter: App.ChartLinearTimeView.BytesFormatter,
+  renderer: 'line',
+
+  ajaxIndex: 'service.metrics.yarn.jobs_heap',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    var MB = Math.pow(2, 20);
+    if (jsonData && jsonData.metrics && jsonData.metrics.jvm) {
+      for ( var name in jsonData.metrics.jvm) {
+        var displayName;
+        var seriesData = jsonData.metrics.jvm[name];
+        switch (name) {
+          case "memHeapCommittedM":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmHeap.displayNames.memHeapCommittedM');
+            break;
+          case "memNonHeapUsedM":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmHeap.displayNames.memNonHeapUsedM');
+            break;
+          case "memHeapUsedM":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmHeap.displayNames.memHeapUsedM');
+            break;
+          case "memNonHeapCommittedM":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmHeap.displayNames.memNonHeapCommittedM');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          var s = this.transformData(seriesData, displayName);
+          for (var i = 0; i < s.data.length; i++) {
+            s.data[i].y *= MB;
+          }
+          seriesArray.push(s);
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/jvm_threads.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/jvm_threads.js b/ambari-web/app/views/main/service/info/metrics/yarn/jvm_threads.js
new file mode 100644
index 0000000..445ecc7
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/jvm_threads.js
@@ -0,0 +1,66 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_JVMThreads = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-jvm-threads",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.jvmThreads'),
+  renderer: 'line',
+
+  ajaxIndex: 'service.metrics.yarn.jobs_threads',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.jvm) {
+      for ( var name in jsonData.metrics.jvm) {
+        var displayName;
+        var seriesData = jsonData.metrics.jvm[name];
+        switch (name) {
+          case "threadsBlocked":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmThreads.displayNames.threadsBlocked');
+            break;
+          case "threadsWaiting":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmThreads.displayNames.threadsWaiting');
+            break;
+          case "threadsTimedWaiting":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmThreads.displayNames.threadsTimedWaiting');
+            break;
+          case "threadsRunnable":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.jvmThreads.displayNames.threadsRunnable');
+            break;
+          default:
+            break;
+        }
+
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/map_slots.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/map_slots.js b/ambari-web/app/views/main/service/info/metrics/yarn/map_slots.js
new file mode 100644
index 0000000..291a0ce
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/map_slots.js
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_MapSlots = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-map-slots",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.mapSlots'),
+  renderer: 'line',
+
+  ajaxIndex: 'service.metrics.mapreduce.map_slots',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.mapred && jsonData.metrics.mapred.jobtracker) {
+      for ( var name in jsonData.metrics.mapred.jobtracker) {
+        var displayName;
+        var seriesData = jsonData.metrics.mapred.jobtracker[name];
+        switch (name) {
+          case "reserved_map_slots":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.mapSlots.displayNames.reservedMapSlots');
+            break;
+          case "occupied_map_slots":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.mapSlots.displayNames.occupiedMapSlots');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/reduce_slots.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/reduce_slots.js b/ambari-web/app/views/main/service/info/metrics/yarn/reduce_slots.js
new file mode 100644
index 0000000..f6a9b02
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/reduce_slots.js
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_ReduceSlots = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-reduce-slots",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.reduceSlots'),
+  renderer: 'line',
+
+  ajaxIndex: 'service.metrics.mapreduce.reduce_slots',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.mapred && jsonData.metrics.mapred.jobtracker) {
+      for ( var name in jsonData.metrics.mapred.jobtracker) {
+        var displayName;
+        var seriesData = jsonData.metrics.mapred.jobtracker[name];
+        switch (name) {
+          case "reserved_reduce_slots":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.reduceSlots.displayNames.reservedReduceSlots');
+            break;
+          case "occupied_reduce_slots":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.reduceSlots.displayNames.occupiedReduceSlots');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/a718fc45/ambari-web/app/views/main/service/info/metrics/yarn/rpc.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/rpc.js b/ambari-web/app/views/main/service/info/metrics/yarn/rpc.js
new file mode 100644
index 0000000..cdbb8ec
--- /dev/null
+++ b/ambari-web/app/views/main/service/info/metrics/yarn/rpc.js
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * @class
+ * 
+ * This is a view for showing cluster CPU metrics
+ * 
+ * @extends App.ChartLinearTimeView
+ * @extends Ember.Object
+ * @extends Ember.View
+ */
+App.ChartServiceMetricsYARN_RPC = App.ChartLinearTimeView.extend({
+  id: "service-metrics-yarn-rpc",
+  title: Em.I18n.t('services.service.info.metrics.mapreduce.rpc'),
+  yAxisFormatter: App.ChartLinearTimeView.TimeElapsedFormatter,
+
+  ajaxIndex: 'service.metrics.yarn.rpc',
+
+  transformToSeries: function (jsonData) {
+    var seriesArray = [];
+    if (jsonData && jsonData.metrics && jsonData.metrics.rpc) {
+      for ( var name in jsonData.metrics.rpc) {
+        var displayName;
+        var seriesData = jsonData.metrics.rpc[name];
+        switch (name) {
+          case "RpcQueueTime_avg_time":
+            displayName = Em.I18n.t('services.service.info.metrics.mapreduce.rpc.displayNames.RpcQueueTimeAvgTime');
+            break;
+          default:
+            break;
+        }
+        if (seriesData) {
+          seriesArray.push(this.transformData(seriesData, displayName));
+        }
+      }
+    }
+    return seriesArray;
+  }
+});
\ No newline at end of file


Mime
View raw message