Repository: ambari
Updated Branches:
  refs/heads/trunk 11ef5ca16 -> cd6398a1d


http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyGraphView.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyGraphView.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyGraphView.js
new file mode 100644
index 0000000..01fccc9
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologyGraphView.js
@@ -0,0 +1,423 @@
+/**
+* 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.
+*/
+
+define(['require', 'utils/Globals'], function(require, Globals) {
+  'use strict'
+
+  var topologyGraphView = Marionette.LayoutView.extend({
+    template: _.template('<div><canvas id="topoGraph" width="844" 
height="260"></div>'),
+
+    initialize: function(options) {
+      this.topologyId = options.id;
+    },
+    onRender: function() {
+      var topology_data,
+        that = this;
+      var sys = arbor.ParticleSystem(20, 1000, 0.15, true, 55, 0.02, 0.6);
+      sys.renderer = this.renderGraph('#topoGraph');
+      sys.stop();
+
+      Backbone.ajax({
+        url: Globals.baseURL + "/api/v1/topology/" + this.topologyId + 
"/visualization",
+        success: function(data, status, jqXHR) {
+          if(_.isString(data)){
+            data = JSON.parse(data);
+          }
+          topology_data = data;
+          that.update_data(topology_data, sys);
+          sys.renderer.signal_update();
+          sys.renderer.redraw();
+          that.rechoose(topology_data, sys, 'default')
+        }
+      });
+
+    },
+
+    renderGraph: function(elem) {
+      var canvas = this.$(elem).get(0);
+      var ctx = canvas.getContext("2d");
+      var gfx = arbor.Graphics(canvas);
+      var psys;
+
+      var totaltrans = 0;
+      var weights = {};
+      var texts = {};
+      var update = false;
+      var that = this;
+      var myRenderer = {
+        init: function(system) {
+          psys = system;
+          psys.screenSize(canvas.width, canvas.height)
+          psys.screenPadding(20);
+          myRenderer.initMouseHandling();
+        },
+
+        signal_update: function() {
+          update = true;
+        },
+
+        redraw: function() {
+          if (!psys)
+            return;
+
+          if (update) {
+            totaltrans = that.calculate_total_transmitted(psys);
+            weights = that.calculate_weights(psys, totaltrans);
+            texts = that.calculate_texts(psys, totaltrans);
+            update = false;
+          }
+
+
+
+          ctx.fillStyle = "white";
+          ctx.fillRect(0, 0, canvas.width, canvas.height);
+          var x = 0;
+
+
+          psys.eachEdge(function(edge, pt1, pt2) {
+
+            var len = Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - 
pt1.y, 2));
+            var sublen = len - (Math.max(50, 20 + 
gfx.textWidth(edge.target.name)) / 2);
+            var thirdlen = len / 3;
+            var theta = Math.atan2(pt2.y - pt1.y, pt2.x - pt1.x);
+
+            var newpt2 = {
+              x: pt1.x + (Math.cos(theta) * sublen),
+              y: pt1.y + (Math.sin(theta) * sublen)
+            };
+
+            var thirdpt = {
+              x: pt1.x + (Math.cos(theta) * thirdlen),
+              y: pt1.y + (Math.sin(theta) * thirdlen)
+            }
+
+            var weight = weights[edge.source.name + edge.target.name];
+
+            if (!weights[edge.source.name + edge.target.name]) {
+              totaltrans = that.calculate_total_transmitted(psys);
+              weights = that.calculate_weights(psys, totaltrans);
+            }
+
+            ctx.strokeStyle = "rgba(0,0,0, .333)";
+            ctx.lineWidth = 25 * weight + 5;
+            ctx.beginPath();
+
+            var arrlen = 15;
+            ctx.moveTo(pt1.x, pt1.y);
+            ctx.lineTo(newpt2.x, newpt2.y);
+            ctx.lineTo(newpt2.x - arrlen * Math.cos(theta - Math.PI / 6), 
newpt2.y - arrlen * Math.sin(theta - Math.PI / 6));
+            ctx.moveTo(newpt2.x, newpt2.y);
+            ctx.lineTo(newpt2.x - arrlen * Math.cos(theta + Math.PI / 6), 
newpt2.y - arrlen * Math.sin(theta + Math.PI / 6));
+
+
+            if (texts[edge.source.name + edge.target.name] == null) {
+              totaltrans = calculate_total_transmitted(psys);
+              texts = calculate_texts(psys, totaltrans);
+            }
+
+            gfx.text(texts[edge.source.name + edge.target.name], thirdpt.x, 
thirdpt.y + 10, {
+              color: "black",
+              align: "center",
+              font: "Arial",
+              size: 10
+            })
+            ctx.stroke();
+          });
+
+          psys.eachNode(function(node, pt) {
+            var col;
+
+            var real_trans = that.gather_stream_count(node.data[":stats"], 
"default", "600");
+
+            if (node.data[":type"] === "bolt") {
+              var cap = Math.min(node.data[":capacity"], 1);
+              var red = Math.floor(cap * 225) + 30;
+              var green = Math.floor(255 - red);
+              var blue = Math.floor(green / 5);
+              col = arbor.colors.encode({
+                r: red,
+                g: green,
+                b: blue,
+                a: 1
+              });
+            } else {
+              col = "#0000FF";
+            }
+
+            var w = Math.max(55, 25 + gfx.textWidth(node.name));
+
+            gfx.oval(pt.x - w / 2, pt.y - w / 2, w, w, {
+              fill: col
+            });
+            gfx.text(node.name, pt.x, pt.y + 3, {
+              color: "white",
+              align: "center",
+              font: "Arial",
+              size: 12
+            });
+            gfx.text(node.name, pt.x, pt.y + 3, {
+              color: "white",
+              align: "center",
+              font: "Arial",
+              size: 12
+            });
+
+            gfx.text(_.isEqual(parseFloat(node.data[":latency"]).toFixed(2), 
'NaN') ? "0.00 ms" : parseFloat(node.data[":latency"]).toFixed(2) + " ms", 
pt.x, pt.y + 17, {
+              color: "white",
+              align: "center",
+              font: "Arial",
+              size: 12
+            });
+
+          });
+
+          // Draw heatmap
+          var rect_x = canvas.width - 250,
+            rect_y = canvas.height - 30,
+            colorArr = ['#ff0000', '#F7BF43', '#F4EA47', '#A4CC45', '#1EE12D'];
+          ctx.fillStyle = "grey";
+          ctx.fillText("Heatmap", rect_x, rect_y - 5)
+          ctx.rect(rect_x, rect_y, 245, canvas.height - 50);
+          var grd = ctx.createLinearGradient(rect_x, rect_y, canvas.width - 5, 
rect_y);
+          grd.addColorStop(0.000, colorArr[0]);
+          grd.addColorStop(0.250, colorArr[1]);
+          grd.addColorStop(0.500, colorArr[2]);
+          grd.addColorStop(0.750, colorArr[3]);
+          grd.addColorStop(1.000, colorArr[4]);
+          ctx.fillStyle = grd;
+          ctx.fillRect(rect_x, rect_y, 245, canvas.height - 50);
+
+          //Draw legends
+          var legendX = canvas.width - 140,
+            legendY = canvas.height - 170,
+            legendWidth = 30,
+            legendY1 = canvas.height - 240,
+            legendTextX = canvas.width - 105,
+            legendTextY = canvas.height - 160,
+            legendTextArr = ['0% - 20%', '21% - 40%', '41% - 60%', '61% - 
80%', '81% - 100%'];
+
+          for (var i = 0; i < colorArr.length; i++) {
+            ctx.rect(legendX, legendY + (i * 25), legendWidth, legendY1);
+            ctx.fillStyle = colorArr[4 - i];
+            ctx.fillRect(legendX, legendY + (i * 25), legendWidth, legendY1);
+            ctx.fillStyle = "black";
+            ctx.fillText(legendTextArr[i], legendTextX, legendTextY + (i * 
25));
+          }
+
+        },
+
+        initMouseHandling: function() {
+          var dragged = null;
+          var clicked = false;
+          var _mouseP;
+
+          var handler = {
+            clicked: function(e) {
+              var pos = $(canvas).offset();
+              _mouseP = arbor.Point(e.pageX - pos.left, e.pageY - pos.top);
+              dragged = psys.nearest(_mouseP);
+
+              if (dragged && dragged.node !== null) {
+                dragged.node.fixed = true;
+              }
+
+              clicked = true;
+              setTimeout(function() {
+                clicked = false;
+              }, 50);
+
+              $(canvas).bind('mousemove', handler.dragged);
+              $(window).bind('mouseup', handler.dropped);
+
+              return false;
+            },
+
+            dragged: function(e) {
+
+              var pos = $(canvas).offset();
+              var s = arbor.Point(e.pageX - pos.left, e.pageY - pos.top);
+
+              if (dragged && dragged.node != null) {
+                var p = psys.fromScreen(s);
+                dragged.node.p = p;
+              }
+
+              return false;
+
+            },
+
+            dropped: function(e) {
+              // if (clicked) {
+              //   if (dragged.distance < 50) {
+              //     if (dragged && dragged.node != null) {
+              //       window.location = dragged.node.data[":link"];
+              //     }
+              //   }
+              // }
+
+              if (dragged === null || dragged.node === undefined) return;
+              if (dragged.node !== null) dragged.node.fixed = false;
+              dragged.node.tempMass = 1000;
+              dragged = null;
+              $(canvas).unbind('mousemove', handler.dragged);
+              $(window).unbind('mouseup', handler.dropped);
+              _mouseP = null;
+              return false;
+            }
+
+          }
+
+          $(canvas).mousedown(handler.clicked);
+        }
+      };
+
+      this.calculate_texts = function(psys, totaltrans) {
+        var texts = {};
+        psys.eachEdge(function(edge, pt1, pt2) {
+          var text = "";
+          for (var i = 0; i < edge.target.data[":inputs"].length; i++) {
+            var stream = edge.target.data[":inputs"][i][":stream"];
+            var sani_stream = edge.target.data[":inputs"][i][":sani-stream"];
+            if (edge.target.data[":inputs"][i][":component"] === 
edge.source.name) {
+              var stream_transfered = 
that.gather_stream_count(edge.source.data[":stats"], sani_stream, "600");
+              text += stream + ": " + stream_transfered + ": " + (totaltrans > 
0 ? Math.round((stream_transfered / totaltrans) * 100) : 0) + "%\n";
+
+            }
+          }
+
+          texts[edge.source.name + edge.target.name] = text;
+        });
+
+        return texts;
+      };
+
+      this.calculate_weights = function(psys, totaltrans) {
+        var weights = {};
+
+        psys.eachEdge(function(edge, pt1, pt2) {
+          var trans = 0;
+          for (var i = 0; i < edge.target.data[":inputs"].length; i++) {
+            var stream = edge.target.data[":inputs"][i][":sani-stream"];
+            if (edge.target.data[":inputs"][i][":component"] === 
edge.source.name)
+              trans += that.gather_stream_count(edge.source.data[":stats"], 
stream, "600");
+          }
+          weights[edge.source.name + edge.target.name] = (totaltrans > 0 ? 
trans / totaltrans : 0);
+        });
+        return weights;
+      };
+
+      this.calculate_total_transmitted = function(psys) {
+        var totaltrans = 0;
+        var countedmap = {}
+        psys.eachEdge(function(node, pt, pt2) {
+          if (!countedmap[node.source.name])
+            countedmap[node.source.name] = {};
+
+          for (var i = 0; i < node.target.data[":inputs"].length; i++) {
+            var stream = node.target.data[":inputs"][i][":stream"];
+            if 
(that.stream_checked(node.target.data[":inputs"][i][":sani-stream"])) {
+              if (!countedmap[node.source.name][stream]) {
+                if (node.source.data[":stats"]) {
+                  var toadd = 
that.gather_stream_count(node.source.data[":stats"], 
node.target.data[":inputs"][i][":sani-stream"], "600");
+                  totaltrans += toadd;
+                }
+                countedmap[node.source.name][stream] = true;
+              }
+            }
+          }
+
+        });
+
+        return totaltrans;
+      };
+
+      this.stream_checked = function(stream) {
+        // var checked = $("#" + stream).is(":checked");
+        var checked = _.isEqual(stream.substr(0, 7), 'default');
+        return checked;
+      };
+
+      this.gather_stream_count = function(stats, stream, time) {
+        var transferred = 0;
+        if (stats)
+          for (var i = 0; i < stats.length; i++) {
+            if (stats[i][":transferred"] != null) {
+              var stream_trans = stats[i][":transferred"][time][stream];
+              if (stream_trans != null)
+                transferred += stream_trans;
+            }
+          }
+        return transferred;
+      };
+
+      return myRenderer;
+    },
+    update_data: function(jdat, sys) {
+      _.each(jdat, function(k, v) {
+        if (sys.getNode(k))
+          sys.getNode(k).data = v;
+      });
+    },
+
+    has_checked_stream_input: function(inputs) {
+      for (var i = 0; i < inputs.length; i++) {
+        var x = this.stream_checked(inputs[i][":sani-stream"]);
+        if (x)
+          return true;
+      }
+      return false;
+    },
+
+    has_checked_stream_output: function(jdat, component) {
+      var that = this;
+      var ret = false;
+      $.each(jdat, function(k, v) {
+        for (var i = 0; i < v[":inputs"].length; i++) {
+          if (that.stream_checked(v[":inputs"][i][":sani-stream"]) && 
v[":inputs"][i][":component"] == component)
+            ret = true;
+        }
+      });
+      return ret;
+    },
+
+    rechoose: function(jdat, sys, box) {
+      var that = this;
+      //Check each node in our json data to see if it has inputs from or 
outputs to selected streams. If it does, add a node for it.
+      $.each(jdat, function(k, v) {
+        if (that.has_checked_stream_input(v[":inputs"]) || 
that.has_checked_stream_output(jdat, k))
+          sys.addNode(k, v);
+      });
+
+      //Check each node in our json data and add necessary edges based on 
selected components.
+      $.each(jdat, function(k, v) {
+        for (var i = 0; i < v[":inputs"].length; i++)
+          if (_.isEqual(v[":inputs"][i][":sani-stream"].substr(0, 7), 
'default')) {
+            sys.addEdge(v[":inputs"][i][":component"], k, v);
+          }
+      });
+
+      //Tell the particle system's renderer that it needs to update its 
labels, colors, widths, etc.
+      sys.renderer.signal_update();
+      sys.renderer.redraw();
+
+    }
+
+  });
+
+  return topologyGraphView;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologySummary.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologySummary.js
 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologySummary.js
new file mode 100644
index 0000000..ba17fc5
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/scripts/views/Topology/TopologySummary.js
@@ -0,0 +1,300 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'modules/Vent',
+  'models/VTopology',
+  'collection/VTopologyList',
+  'utils/TableLayout',
+  'utils/LangSupport',
+  'bootbox',
+  'utils/Utils',
+  'utils/Globals',
+  'hbs!tmpl/topology/topologySummary',
+  'bootstrap'
+], function(require, vent, mTopology, cTopologyList, TableLayout, 
localization, bootbox, Utils, Globals, tmpl) {
+  'use strict';
+
+  var TopologySummaryTableLayout = Marionette.LayoutView.extend({
+
+    template: tmpl,
+
+    templateHelpers: function() {},
+
+    events: {
+      'click [data-id="deployBtn"]': 'evDeployTopology'
+    },
+
+    ui: {
+      summaryDetails: '[data-id="summary"]'
+    },
+
+    regions: {
+      'rTableList': '#summaryTable',
+    },
+
+    initialize: function() {
+      this.collection = new cTopologyList();
+      vent.trigger('Breadcrumb:Hide');
+    },
+
+    fetchSummary: function(flag) {
+      var that = this;
+      this.collection.fetch({
+        success: function(collection, response, options) {
+          if (collection && collection.length) {
+            var arr = [];
+            _.each(collection.models[0].get('topologies'), function(object){
+              arr.push(new mTopology(object));
+            });
+            that.countActive = 0;
+            that.collection.reset(arr);
+            that.showSummaryDetail();
+            that.startPollingAction();
+          }
+        },
+        error: function(collection, response, options){
+          that.startPollingAction();
+          Utils.notifyError(response.statusText);
+        }
+      })
+    },
+
+    onRender: function() {
+      this.showSummaryTable(this.collection);
+      $('.loading').hide();
+      this.fetchSummary();
+      this.showSummaryDetail();
+    },
+
+    showSummaryDetail: function() {
+      var totalTopologies = 0,
+        activeTopologies = 0,
+        inactiveTopologies = 0;
+      if (this.collection && this.collection.length) {
+        totalTopologies = this.collection.length;
+        activeTopologies = this.countActive;
+        inactiveTopologies = this.collection.length - this.countActive;
+      }
+      var template = _.template('<label style="margin-right:10px">' + 
localization.tt('lbl.topologySummary') + ' </label>' +
+        '<span class="topology-summary-stats"><%- total%> ' + 
localization.tt('lbl.total') + '</span> | ' +
+        '<span class="topology-summary-stats"><%- active%> ' + 
localization.tt('lbl.active') + '</span> | ' +
+        '<span class="topology-summary-stats"><%- inactive%> ' + 
localization.tt('lbl.inactive') + '</span>');
+      this.ui.summaryDetails.html(template({
+        total: totalTopologies,
+        active: activeTopologies,
+        inactive: inactiveTopologies
+      }));
+    },
+
+    showSummaryTable: function(collection) {
+      this.rTableList.show(new TableLayout({
+        columns: this.getColumns(),
+        collection: this.collection,
+        gridOpts: {
+          emptyText: localization.tt('msg.noTopologyFound')
+        }
+      }));
+      
this.rTableList.$el.find('[data-id="r_tableList"]').attr("style","height:655px");
+    },
+
+    getColumns: function() {
+      var that = this;
+      var cols = [{
+        name: "name",
+        cell: "uri",
+        href: function(model) {
+          if(_.isEqual(model.get('status'),'ACTIVE')){
+            that.countActive++;
+          }
+          return '#!/topology/' + model.get('id');
+        },
+        label: localization.tt("lbl.name"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryName")
+      }, {
+        name: "id",
+        cell: "string",
+        label: localization.tt("lbl.id"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryId")
+      }, {
+        name: "owner",
+        cell: "string",
+        label: localization.tt("lbl.owner"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryOwner")
+      }, {
+        name: "status",
+        cell: "string",
+        label: localization.tt("lbl.status"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryStatus")
+      }, {
+        name: "uptime",
+        cell: "string",
+        label: localization.tt("lbl.uptime"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryUptime")
+      }, {
+        name: "workersTotal",
+        cell: "string",
+        label: localization.tt("lbl.workers"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryWorkers")
+      }, {
+        name: "executorsTotal",
+        cell: "string",
+        label: localization.tt("lbl.executors"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryExecutors")
+      }, {
+        name: "tasksTotal",
+        cell: "string",
+        label: localization.tt("lbl.tasks"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryTasks")
+      }, {
+        name: "schedulerInfo",
+        cell: "string",
+        label: localization.tt("lbl.schedulerInfo"),
+        sortable: true,
+        editable: false,
+        hasTooltip: true,
+        tooltipText: localization.tt("msg.topologySummaryScheduler")
+      }];
+      return cols;
+    },
+
+    evDeployTopology: function(e) {
+      var that = this;
+
+      if (that.view) {
+        that.onDialogClosed();
+      }
+
+      require(['views/Topology/TopologyForm'], function(TopologyFormView) {
+        that.view = new TopologyFormView();
+        that.view.render();
+
+        bootbox.dialog({
+          message: that.view.el,
+          title: localization.tt('btn.deployNewTopology'),
+          className: "topology-modal",
+          buttons: {
+            cancel: {
+              label: localization.tt('btn.cancel'),
+              className: "btn-default",
+              callback: function() {
+                that.onDialogClosed();
+              }
+            },
+            success: {
+              label: localization.tt('btn.save'),
+              className: "btn-success",
+              callback: function() {
+                var errs = that.view.validate();
+                 if(_.isEmpty(errs)){
+                  that.submitTopology();
+                } else return false;
+              }
+            }
+          }
+        });
+      });
+    },
+
+    submitTopology: function() {
+      Utils.notifyInfo(localization.tt("dialogMsg.topologyBeingDeployed"));
+      var attrs = this.view.getData(),
+          formData = new FormData(),
+          obj = {},
+          url = Globals.baseURL + '/api/v1/uploadTopology',
+          that = this;
+
+      if(!_.isEqual(attrs.jar.name.split('.').pop().toLowerCase(),'jar')){
+        Utils.notifyError(localization.tt("dialogMsg.invalidFile"));
+        return false;
+      }
+      formData.append('topologyJar', attrs.jar);
+      obj.topologyMainClass = attrs.topologyClass;
+      obj.topologyMainClassArgs = [];
+      obj.topologyMainClassArgs.push(attrs.name);
+
+      if(!_.isEmpty(attrs.arguments)){
+        
Array.prototype.push.apply(obj.topologyMainClassArgs,attrs.arguments.split(' 
'));
+      }
+
+      formData.append("topologyConfig", JSON.stringify(obj));
+
+      var successCallback = function(response){
+        if(_.isString(response)){
+          response = JSON.parse(response);
+        }
+        if(_.isEqual(response.status, 'failed')){
+          Utils.notifyError(response.error);
+        } else {
+          
Utils.notifySuccess(localization.tt("dialogMsg.topologyDeployedSuccessfully"));
+          that.fetchSummary(true);
+        }
+      };
+
+      var errorCallback = function(){
+        Utils.notifyError(localization.tt("dialogMsg.topologyDeployFailed"));
+      };
+
+      Utils.uploadFile(url,formData,successCallback, errorCallback);
+    },
+
+    onDialogClosed: function() {
+      if (this.view) {
+        this.view.close();
+        this.view.remove();
+        this.view = null;
+      }
+    },
+
+    startPollingAction: function(){
+      var that = this;
+      setTimeout(function() {
+        if(_.isEqual(typeof that.ui.summaryDetails, "object")){
+          that.fetchSummary();
+        }
+      }, Globals.settings.refreshInterval);
+
+    }
+
+  });
+  return TopologySummaryTableLayout;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/scripts/views/site/Header.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/scripts/views/site/Header.js 
b/contrib/views/storm/src/main/resources/scripts/views/site/Header.js
new file mode 100644
index 0000000..966fe2f
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/scripts/views/site/Header.js
@@ -0,0 +1,79 @@
+/**
+* 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.
+*/
+
+define(['require',
+  'modules/Vent',
+  'utils/LangSupport',
+  'hbs!tmpl/site/header'], function(require, vent, localization, headerTmpl){
+  'use strict';
+
+  var HeaderView = Marionette.LayoutView.extend({
+    _viewNmae: 'Header',
+
+    template: headerTmpl,
+
+    templateHelpers: function() {},
+
+    regions: {
+
+    },
+
+    ui: {
+      toplogyLink: '[data-id="topology"]',
+      clusterLink: '[data-id="cluster"]'
+    },
+
+    events: {
+      'click [data-id="topology"]': 'showTopologySection',
+      'click [data-id="cluster"]': 'showClusterSection'
+    },
+
+    initialize: function (options) {
+      this.clusterTabFlag = false;
+      this.bindEvent();
+    },
+
+    bindEvent: function() {
+      var that = this;
+      vent.on('Breadcrumb:Show', function(name){
+        that.$('.breadcrumb').removeClass('displayNone');
+        that.$('#breadcrumbName').html(name);
+      });
+      vent.on('Breadcrumb:Hide', function(){
+        that.$('.breadcrumb').addClass('displayNone');
+      });
+    },
+
+    onRender: function () {},
+
+    showTopologySection: function () {
+      this.ui.clusterLink.parent().removeClass('active');
+      this.ui.toplogyLink.parent().addClass('active');
+      vent.trigger('Region:showTopologySection');
+    },
+
+    showClusterSection: function () {
+      this.ui.toplogyLink.parent().removeClass('active');
+      this.ui.clusterLink.parent().addClass('active');
+      vent.trigger('Region:showClusterSection');
+    }
+
+  });
+
+  return HeaderView;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/styles/default.css
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/styles/default.css 
b/contrib/views/storm/src/main/resources/styles/default.css
new file mode 100644
index 0000000..9a08d82
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/styles/default.css
@@ -0,0 +1,298 @@
+/**
+ * CSS Goes here
+ */
+
+/* Generic */
+/*body {
+  color:#555;
+}*/
+select {
+  padding: 3px 6px;
+  border: 2px #53c749 solid;
+  background-color: #fff;
+}
+
+a:hover, a:focus {
+  text-decoration: none;
+}
+
+[data-error]{
+  color: red;
+}
+
+.loading{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: url('../images/loading.gif') no-repeat center center;
+  background-size: 4%;
+  background-color: rgba(255,255,255,0.7);
+  z-index: 99;
+}
+
+/* Bootsrap Extended */
+.table-borderless > thead > tr > th,
+.table-borderless > tbody > tr > th,
+.table-borderless > tfoot > tr > th,
+.table-borderless > thead > tr > td,
+.table-borderless > tbody > tr > td,
+.table-borderless > tfoot > tr > td {
+  border:none;
+}
+
+.backgrid .ascending .sort-caret {
+  vertical-align: baseline;
+  border-top: 0;
+  border-right: 4px solid transparent;
+  border-bottom: 4px solid;
+  border-left: 4px solid transparent;
+}
+
+.backgrid .descending .sort-caret {
+  vertical-align: super;
+  border-top: 4px solid;
+  border-right: 4px solid transparent;
+  border-bottom: 0;
+  border-left: 4px solid transparent;
+}
+
+/*.tab-content>.tab-pane {
+  padding: 0 20px;
+}*/
+.row-margin-bottom {
+  margin-bottom: 20px;
+}
+.sview-tabs .nav-tabs {
+  border-bottom: 2px #53c749 solid;
+  margin-bottom: 20px;
+}
+.sview-tabs .nav-tabs>li {
+  margin-bottom:0;
+  padding:10px 0;
+}
+.sview-tabs .nav-tabs>li>a {
+  color:#aaa;
+  font-size: 20px;
+  line-height:0.6;
+  border:none;
+  border-radius:0;
+  border-left:1px #BBB solid;
+}
+.sview-tabs .nav>li>a:hover {
+    background-color: transparent;
+    cursor: pointer;
+}
+.sview-tabs .nav-tabs>li:first-child>a {
+    border-left:none !important;
+}
+.sview-tabs .nav-tabs>li.active>a {
+  color:#333;
+  font-weight:bold;
+  border:none;
+  border-left:1px #BBB solid;
+}
+.topology-summary-stats {
+  color:#53c749;
+  margin-left: 5px;
+  margin-right: 5px;
+}
+.ui-widget-header {
+  border: 1px solid green;
+  background: green 50% 50% repeat-x;
+}
+
+.topology-modal .modal-header {
+  color:#53c749;
+}
+
+#topology .table-hover > thead > tr > th {
+  background-color: grey;
+}
+
+#topology .table-hover > thead > tr > th > div > a{
+  color: white;
+}
+
+h3.topology-title {
+color: #53c749;
+margin-top: 0;
+margin-bottom: 0;
+}
+
+#topology .table-hover > tbody > tr:hover {
+  background-color: #C4ECC1;
+}
+.topology-tabs table tr.recent > td {
+  background-color: #3FC846;
+  color: #fff;
+  cursor: pointer;
+}
+
+.topology-summary {
+  border: 2px #888 solid;
+  padding-left: 15px;
+  padding-left: 10px;
+}
+.topology-summary h4 {
+  color: #777;
+  font-weight: bold;
+  margin-bottom: 25px;
+}
+.topology-summary .table > tbody > tr > th,
+.topology-summary .table > tbody > tr > td {
+  padding-top: 3px;
+  padding-bottom: 3px;
+}
+.topology-summary .table > tbody > tr > th {
+  font-weight: normal;
+  color: #999;
+  text-align: right;
+}
+.topology-summary .table > tbody > tr > td {
+  color:#53c749;
+}
+
+.topology-graph {
+  border: 2px #53c749 solid;
+}
+
+.statistics {
+  background-color: #F3F3F3;
+}
+.statistics h3 {
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+.topology-time-frame label {
+  font-weight: normal;
+}
+
+.statistics-accordion .panel {
+  border-radius:0;
+  border: 2px #53c749 solid;
+}
+.statistics-accordion .panel-default > .panel-heading {
+  border-radius:0;
+  background:#fff;
+  color:#777;
+}
+.statistics-accordion .panel-heading + .panel-collapse > .panel-body {
+  border-top: 2px #53c749 solid;
+}
+.statistics-row {
+  border-bottom: 1px #53c749 solid;
+  margin-left: 20px;
+}
+.statistics-row:last-child {
+border-bottom: 0;
+}
+.statistics-row.child {
+  padding-left: 30px;
+}
+.statistics-row h5 {
+  font-weight: bold;
+}
+.statistics .table > thead > tr > th,
+.statistics .table > tbody > tr > td {
+  padding: 4px;
+}
+.statistics .table > thead > tr > th {
+  background-color: #f9f9f9;
+}
+
+/* Clusters */
+.cluster-summary {
+  border: 2px #53c749 solid;
+  padding-left: 20px;
+  padding-right: 20px;
+}
+.cluster-summary h4 {
+  color: #777;
+  font-weight: bold;
+}
+.cluster-table > thead > tr > th,
+.cluster-table > tbody > tr > td {
+  padding: 4px;
+}
+.cluster-table  > thead > tr > th {
+  color: #000;
+}
+#topologyDetail .table > thead > tr > th > div > a {
+    color: black;
+    text-align: left;
+}
+.displayNone {
+  display: none;
+}
+[data-id="r_tableList"] > .table > thead > tr > th > div > a {
+    color: #000;
+}
+
+/**
+ * Bootstrap Notification
+ */
+.notifications {
+  position: fixed;
+  z-index: 9999;
+}
+
+/* Positioning */
+.notifications.top-right {
+  right: 10px;
+  top: 25px;
+}
+
+.notifications.top-left {
+  left: 10px;
+  top: 25px;
+}
+
+.notifications.bottom-left {
+  left: 10px;
+  bottom: 25px;
+}
+
+.notifications.bottom-right {
+  right: 10px;
+  bottom: 25px;
+}
+
+/* Notification Element */
+.notifications > div {
+  position: relative;
+  margin: 5px 0px;
+}
+
+.error-notification {
+  position: absolute;
+  top: 0;
+  right: 5px;
+}
+
+.breadcrumb {
+  line-height: 52px;
+  margin-left: 25px;
+  font-size: 12px;
+  color: #666;
+}
+.breadcrumb .seperator {
+  margin-left: 5px;
+  margin-right: 5px;
+}
+.statistics-container {
+  border: 1px solid #ddd;
+}
+.table-header {
+  border-left: 10px #53c749 solid;
+}
+th.sortable > div > a {
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+}
+table tr.recent > td {
+  background-color: #3FC846;
+  color: #fff;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/cluster/clusterSummary.html
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/templates/cluster/clusterSummary.html 
b/contrib/views/storm/src/main/resources/templates/cluster/clusterSummary.html
new file mode 100644
index 0000000..aa46a5a
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/templates/cluster/clusterSummary.html
@@ -0,0 +1,83 @@
+<!--
+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. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<div class="row row-margin-bottom">
+    <div class="col-md-6" data-id="clusterSummaryTable"></div>
+    <div class="col-md-12">
+        <div class="cluster-summary">
+            <h4>{{tt "h.clusterSummary"}}</h4>
+            <div class="row" id="clusterSummaryTable"></div>
+        </div>
+    </div>
+</div>
+
+<div class="row row-margin-bottom">
+    <div class="col-md-12" data-id="nbsSummary">
+        <div class="panel-group statistics-accordion" role="tablist" 
aria-multiselectable="true">
+            <div class="panel panel-default">
+                <div class="panel-heading" role="tab" id="headingOne">
+                    <h6 class="panel-title">
+                        <a data-toggle="collapse" href="#collapseNimbSum" 
aria-expanded="true" aria-controls="collapseNimbSum" class="">
+                        <i class="fa fa-caret-down"></i> {{tt 
"h.nimbusSummary"}}</a>
+                    </h6>
+                </div>
+                <div id="collapseNimbSum" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingOne" aria-expanded="true">
+                    <div class="panel-body">
+                        <div class="row" id="nbsSummaryTable"> </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div class="row row-margin-bottom">
+    <div class="col-md-12" data-id="sprSummary">
+        <div class="panel-group statistics-accordion" role="tablist" 
aria-multiselectable="true">
+            <div class="panel panel-default">
+                <div class="panel-heading" role="tab" id="headingTwo">
+                    <h6 class="panel-title">
+                        <a data-toggle="collapse" href="#collapseSubSum" 
aria-expanded="true" aria-controls="collapseSubSum">
+                        <i class="fa fa-caret-down"></i> {{tt 
"h.supervisorSummary"}}</a>
+                    </h6>
+                </div>
+                <div id="collapseSubSum" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingOne">
+                    <div class="panel-body">
+                        <div class="row" id="sprSummaryTable"> <div 
class="row"> </div> </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div class="row row-margin-bottom">
+    <div class="col-md-12" data-id="nbsConfig">
+        <div class="panel-group statistics-accordion" role="tablist" 
aria-multiselectable="true">
+            <div class="panel panel-default">
+                <div class="panel-heading" role="tab" id="headingThree">
+                    <h6 class="panel-title">
+                        <a data-toggle="collapse" href="#collapseNbs" 
aria-expanded="true" aria-controls="collapseNbs">
+                        <i class="fa fa-caret-down"></i> {{tt 
"h.nimbusConfiguration"}}</a>
+                    </h6>
+                </div>
+                <div id="collapseNbs" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingOne">
+                    <div class="panel-body"> <div class="row" 
id="nbsConfigTable"> </div> </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/site/header.html
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/templates/site/header.html 
b/contrib/views/storm/src/main/resources/templates/site/header.html
new file mode 100644
index 0000000..ec6ad02
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/templates/site/header.html
@@ -0,0 +1,23 @@
+<!--
+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. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<div class="sview-tabs">
+  <ul class="nav nav-tabs" role="tablist">
+    <li role="presentation" class="active"><a role="tab" data-toggle="tab" 
data-id="topology">{{tt 'h.topologies'}}</a></li>
+    <li role="presentation"><a role="tab" data-toggle="tab" 
data-id="cluster">{{tt 'h.cluster'}}</a></li>
+    <span class="breadcrumb displayNone"><a href="#!/topology">{{tt 
'h.topologies'}}</a> <i class="fa fa-angle-double-right seperator"></i><span 
id="breadcrumbName"></span></span>
+  </ul>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/spout/spoutItemView.html
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/templates/spout/spoutItemView.html 
b/contrib/views/storm/src/main/resources/templates/spout/spoutItemView.html
new file mode 100644
index 0000000..539fa18
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/templates/spout/spoutItemView.html
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<div>
+    <div class="row row-margin-bottom">
+        <div class="col-md-12">
+            <div class="statistics-container">
+                <div data-id="SpoutsSummaryTable"></div>
+
+                <div class="row statistics-row">
+                    <div class="col-md-12">
+                        <h5>{{tt 'lbl.outputStats'}}</h5>
+                        <div data-id="OpstSummaryTable"></div>
+                    </div>
+                </div>
+
+                <div class="row statistics-row">
+                    <div class="col-md-12">
+                        <h5>{{tt 'lbl.executors'}}</h5>
+                        <div data-id="ExtrSummaryTable"></div>
+                    </div>
+                </div>
+
+                <div class="row statistics-row">
+                    <div class="col-md-12">
+                        <h5>{{tt 'lbl.errors'}}</h5>
+                        <div data-id="ErrorSummaryTable"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/topology/topologyDetail.html
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/templates/topology/topologyDetail.html 
b/contrib/views/storm/src/main/resources/templates/topology/topologyDetail.html
new file mode 100644
index 0000000..f75f1b5
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/templates/topology/topologyDetail.html
@@ -0,0 +1,108 @@
+<!--
+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. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<div class="row row-margin-bottom">
+  <div class="col-md-3"><h3 class="topology-title"></h3></div>
+  <div class="col-md-3 topology-time-frame">
+    <label> {{tt 'lbl.selectTimeFrame'}} : </label>
+    <select id="tFrame"></select>
+  </div>
+  <div class="col-md-2">
+    <form class="form-inline">
+      <div class="checkbox"><label><input id="sysBolt" type="checkbox"> {{tt 
'lbl.showSystemBolt'}}  </label></div>
+    </form>
+  </div>
+  <div class="col-md-4">
+    <div class="btn-group-sm pull-right">
+      <button id="btnActivate" class="btn btn-success btn-sm">{{tt 
'btn.activate'}}  </button>
+      <button id="btnDeactivate" class="btn btn-success btn-sm">{{tt 
'btn.deactivate'}}  </button>
+      <button id="btnRebalance" class="btn btn-success btn-sm">{{tt 
'btn.rebalance'}}  </button>
+      <button id="btnKill" class="btn btn-success btn-sm">{{tt 'btn.kill'}}  
</button>
+    </div>
+  </div>
+</div>
+
+<div class="row row-margin-bottom">
+  <div id="topologyDetail" class="col-md-12"></div>
+</div>
+
+<div class="row row-margin-bottom">
+  <div class="col-md-9">
+    <div id="graph" class="topology-graph"></div>
+  </div>
+  <div class="col-md-3">
+    <div class="topology-summary">
+      <h4 align="center">{{tt 'lbl.topologySummary'}} </h4>
+      <div id="topo-summary"></div>
+    </div>
+  </div>
+</div>
+<div class="row">
+  <div class="col-md-12 statistics">
+    <!--h3>Statistics <button class="pull-right btn btn-success btn-sm">Open 
All</button></h3-->
+    <h3>{{tt 'lbl.statistics'}}</h3>
+    <div class="panel-group statistics-accordion" role="tablist" 
aria-multiselectable="true">
+      <!-- 1st Accordion Begin -->
+      <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+          <h6 class="panel-title">
+            <a class="collapsed" data-toggle="collapse" href="#collapseOne" 
aria-expanded="true" aria-controls="collapseOne">
+            <i class="fa fa-caret-down"></i> {{tt 'lbl.spouts'}}</a>
+          </h6>
+        </div>
+        <div id="collapseOne" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingOne">
+          <div class="panel-body" id="SpoutsTable"></div>
+        </div>
+      </div>
+      <!-- 1st Accordion End -->
+
+      <!-- 2nd Accordion Begin -->
+      <div class="panel panel-default">
+        <div class="panel-heading" role="tab" id="headingTwo">
+          <h6 class="panel-title">
+            <a class="collapsed" data-toggle="collapse" href="#collapseTwo" 
aria-expanded="false" aria-controls="collapseTwo"><span class="fa 
fa-caret-down"></span> {{tt 'lbl.bolts'}}</a>
+          </h6>
+        </div>
+        <div id="collapseTwo" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingTwo">
+          <div class="panel-body">
+            <div class="row statistics-row">
+              <div id="BoltsSummaryTable"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 2nd Accordion End -->
+
+      <!-- 3rd Accordion Begin -->
+      <div class="panel panel-default">
+        <div class="panel-heading" role="tab" id="headingThree">
+          <h6 class="panel-title">
+            <a class="collapsed" data-toggle="collapse" href="#collapseThree" 
aria-expanded="false" aria-controls="collapseThree"><span class="fa 
fa-caret-down"></span> {{tt 'lbl.topologyConfig'}}</a>
+          </h6>
+        </div>
+        <div id="collapseThree" class="panel-collapse collapse in" 
role="tabpanel" aria-labelledby="headingThree">
+          <div class="panel-body">
+            <div class="row statistics-row">
+              <div id="TopologyConfigTable"></div>
+            </div>
+          </div>
+        </div>
+      </div>
+    <!-- 3rd Accordion End -->
+
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/topology/topologyForm.html
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/templates/topology/topologyForm.html 
b/contrib/views/storm/src/main/resources/templates/topology/topologyForm.html
new file mode 100644
index 0000000..f78d08d
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/templates/topology/topologyForm.html
@@ -0,0 +1,8 @@
+<form class="form-horizontal">
+  <fieldset>
+    <div class="" data-fields="name"></div>
+    <div class="" data-fields="jar"></div>
+    <div class="" data-fields="topologyClass"></div>
+    <div class="" data-fields="arguments"></div>
+  </fieldset>
+</form>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/templates/topology/topologySummary.html
----------------------------------------------------------------------
diff --git 
a/contrib/views/storm/src/main/resources/templates/topology/topologySummary.html
 
b/contrib/views/storm/src/main/resources/templates/topology/topologySummary.html
new file mode 100644
index 0000000..3626346
--- /dev/null
+++ 
b/contrib/views/storm/src/main/resources/templates/topology/topologySummary.html
@@ -0,0 +1,23 @@
+<!--
+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. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<div class="row row-margin-bottom">
+  <div class="col-md-6" data-id="summary"></div>
+  <div class="col-md-6">
+    <button class="btn btn-success btn-sm pull-right" data-id="deployBtn"> 
{{tt 'btn.deployNewTopology'}}  </button>
+  </div>
+</div>
+<div class="row" id="summaryTable"></div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/contrib/views/storm/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/storm/src/main/resources/view.xml 
b/contrib/views/storm/src/main/resources/view.xml
new file mode 100644
index 0000000..a047d25
--- /dev/null
+++ b/contrib/views/storm/src/main/resources/view.xml
@@ -0,0 +1,22 @@
+<!--
+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. Kerberos, LDAP, Custom. Binary/Htt
+-->
+<view>
+  <name>Storm_Monitoring</name>
+  <label>Storm Monitoring</label>
+  <version>0.1.0</version>
+  <description>Ambari view for Apache Storm</description>
+</view>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cd6398a1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 108db64..62cf8eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -331,6 +331,9 @@
             
<exclude>contrib/views/slider/src/main/resources/ui/app/assets/javascripts/**</exclude>
             
<exclude>contrib/views/slider/src/main/resources/ui/bower_components/**</exclude>
             
<exclude>contrib/views/slider/src/main/resources/ui/runner.js</exclude>
+           <exclude>contrib/views/storm/src/main/resources/libs/**</exclude>
+            
<exclude>contrib/views/storm/src/main/resources/styles/default.css</exclude>
+            
<exclude>contrib/views/storm/src/main/resources/templates/**</exclude>
             
<exclude>contrib/addons/package/deb/nagios_addon_deb_control</exclude>
             
<exclude>contrib/addons/src/addOns/nagios/conf.d/hdp_mon_nagios_addons.conf</exclude>
             <exclude>contrib/views/*/.classpath</exclude>

Reply via email to