GEARPUMP-6: show add/remove worker buttons for admin

Project: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-gearpump/commit/02597f75
Tree: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/tree/02597f75
Diff: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/diff/02597f75

Branch: refs/heads/master
Commit: 02597f75fe34740bc8db2dff1716a1ba6a9ec693
Parents: 37e0a38
Author: Qian Xu <[email protected]>
Authored: Thu Mar 31 16:31:45 2016 +0800
Committer: manuzhang <[email protected]>
Committed: Tue Apr 26 14:24:31 2016 +0800

----------------------------------------------------------------------
 project/Build.scala                             |  2 +-
 services/dashboard/index.html                   |  5 +-
 services/dashboard/services/models/models.js    |  7 +++
 services/dashboard/services/restapi.js          | 29 +++++++++++
 .../dashboard/views/apps/submit/submit.html     |  7 +--
 .../views/cluster/workers/add_worker.html       | 46 ++++++++++++++++++
 .../views/cluster/workers/add_worker.js         | 35 ++++++++++++++
 .../views/cluster/workers/workers_listview.html | 17 +++++--
 .../views/cluster/workers/workers_listview.js   | 51 +++++++++++++++++---
 9 files changed, 183 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/project/Build.scala
----------------------------------------------------------------------
diff --git a/project/Build.scala b/project/Build.scala
index 761c3b9..a99530f 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -308,7 +308,7 @@ object Build extends sbt.Build {
       "org.webjars.bower" % "vis" % "4.7.0",
       "org.webjars.bower" % "clipboard.js" % "0.1.1",
       "org.webjars.npm" % "dashing-deps" % "0.1.2",
-      "org.webjars.npm" % "dashing" % "0.4.6"
+      "org.webjars.npm" % "dashing" % "0.4.8"
   ).map(_.exclude("org.scalamacros", 
"quasiquotes_2.10")).map(_.exclude("org.scalamacros", "quasiquotes_2.10.3")))
 
   lazy val serviceJSSettings = Seq(

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/index.html
----------------------------------------------------------------------
diff --git a/services/dashboard/index.html b/services/dashboard/index.html
index 3ba09e3..26511ec 100644
--- a/services/dashboard/index.html
+++ b/services/dashboard/index.html
@@ -17,7 +17,7 @@
   <link rel="stylesheet" href="webjars/ui-select/0.14.2/dist/select.min.css"/>
   <link rel="stylesheet" 
href="webjars/angular-loading-bar/0.8.0/build/loading-bar.min.css"/>
   <link rel="stylesheet" href="webjars/vis/4.7.0/dist/vis.min.css"/>
-  <link rel="stylesheet" href="webjars/dashing/0.4.6/dist/dashing.min.css"/>
+  <link rel="stylesheet" href="webjars/dashing/0.4.8/dist/dashing.min.css"/>
 
   <!-- Site styles -->
   <link rel="stylesheet" 
href="webjars/dashing-deps/0.1.2/roboto/roboto.min.css"/>
@@ -62,7 +62,7 @@
 <script src="webjars/ng-file-upload/5.0.9/ng-file-upload-all.min.js"></script>
 <script src="webjars/clipboard.js/0.1.1/clipboard.js"></script>
 <script 
src="webjars/dashing-deps/0.1.2/echarts/2.2.7-compact/echarts-all.min.js"></script>
-<script src="webjars/dashing/0.4.6/dist/dashing.min.js"></script>
+<script src="webjars/dashing/0.4.8/dist/dashing.min.js"></script>
 
 <!-- Application -->
 <script src="dashboard.js"></script>
@@ -82,6 +82,7 @@
 <script src="views/landing/breadcrumbs.js"></script>
 <script src="views/landing/header.js"></script>
 <script src="views/cluster/master/master.js"></script>
+<script src="views/cluster/workers/add_worker.js"></script>
 <script src="views/cluster/workers/workers_listview.js"></script>
 <script src="views/cluster/workers/worker/worker.js"></script>
 <script src="views/jvm/jvm_metrics_view.js"></script>

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/services/models/models.js
----------------------------------------------------------------------
diff --git a/services/dashboard/services/models/models.js 
b/services/dashboard/services/models/models.js
index f05ff59..794f2ce 100644
--- a/services/dashboard/services/models/models.js
+++ b/services/dashboard/services/models/models.js
@@ -122,6 +122,9 @@ angular.module('io.gearpump.models', [])
             configLink: restapi.workerConfigLink(obj.workerId)
           });
         },
+        supervisor: function(obj) {
+          return obj;
+        },
         apps: function(wrapper) {
           var objs = wrapper.appMasters;
           return decoder._asAssociativeArray(objs, decoder.appSummary, 
'appId');
@@ -362,6 +365,10 @@ angular.module('io.gearpump.models', [])
         _workerMetrics: function(workerId, args) {
           return getter._metrics('worker/' + workerId + '/metrics/', 'worker' 
+ workerId, args);
         },
+        supervisor: function() {
+          return get('supervisor',
+            decoder.supervisor);
+        },
         apps: function() {
           return get('master/applist',
             decoder.apps);

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/services/restapi.js
----------------------------------------------------------------------
diff --git a/services/dashboard/services/restapi.js 
b/services/dashboard/services/restapi.js
index f9cdceb..483fcf9 100644
--- a/services/dashboard/services/restapi.js
+++ b/services/dashboard/services/restapi.js
@@ -187,6 +187,35 @@ angular.module('dashboard')
           });
         },
 
+        /** Add a new worker */
+        addWorker: function(onComplete) {
+          var count = 1;
+          var url = restapiV1Root + 'supervisor/addworker/' + count;
+          return $http.post(url).then(function(response) {
+            if (angular.isFunction(onComplete)) {
+              onComplete(decodeSuccessResponse(response.data));
+            }
+          }, function(response) {
+            if (angular.isFunction(onComplete)) {
+              onComplete(decodeErrorResponse(response.data));
+            }
+          });
+        },
+
+        /** Remove a new worker */
+        removeWorker: function(workerId, onComplete) {
+          var url = restapiV1Root + 'supervisor/removeworker/' + workerId;
+          return $http.post(url).then(function(response) {
+            if (angular.isFunction(onComplete)) {
+              onComplete(decodeSuccessResponse(response.data));
+            }
+          }, function(response) {
+            if (angular.isFunction(onComplete)) {
+              onComplete(decodeErrorResponse(response.data));
+            }
+          });
+        },
+
         /** Replace a dag processor at runtime */
         replaceDagProcessor: function(files, formFormNames, appId, 
oldProcessorId, newProcessorDescription, onComplete) {
           var url = restapiV1Root + 'appmaster/' + appId + '/dynamicdag';

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/views/apps/submit/submit.html
----------------------------------------------------------------------
diff --git a/services/dashboard/views/apps/submit/submit.html 
b/services/dashboard/views/apps/submit/submit.html
index 001a75a..2b15000 100644
--- a/services/dashboard/views/apps/submit/submit.html
+++ b/services/dashboard/views/apps/submit/submit.html
@@ -10,7 +10,7 @@
         <p style="padding-top: 4px; padding-bottom: 14px;">Application will be 
launched immediately,
           after the JAR file is uploaded.</p>
 
-        <div ng-show="shouldNoticeSubmitFailed">
+        <div ng-if="shouldNoticeSubmitFailed">
           <div class="alert alert-danger alert-dismissible" role="alert">
             <button type="button" class="close" data-dismiss="alert"
                     ng-click="shouldNoticeSubmitFailed=false">
@@ -41,8 +41,9 @@
               ng-model="conf" 
accept-pattern="{{confFileSuffix}}"></form-control>
             <!-- input 3 -->
             <form-control
-              type="integer" min="1" label="Executor Count" 
ng-hide="isStormApp"
-              help="How many JVM processes to start for this job in the whole 
cluster. E.g. set it as 12 will start 12 executor processes spanning across the 
cluster"
+              ng-if="!isStormApp"
+              type="integer" min="1" label="Executors"
+              help="The number of executor (JVM) processes to be spawned in 
the cluster."
               ng-model="executorNum"></form-control>
             <!-- input 4 -->
             <form-control

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/views/cluster/workers/add_worker.html
----------------------------------------------------------------------
diff --git a/services/dashboard/views/cluster/workers/add_worker.html 
b/services/dashboard/views/cluster/workers/add_worker.html
new file mode 100644
index 0000000..d8a1ecf
--- /dev/null
+++ b/services/dashboard/views/cluster/workers/add_worker.html
@@ -0,0 +1,46 @@
+<div class="modal" tabindex="-1">
+  <div class="modal-dialog" style="max-width: 440px">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" ng-click="$hide()">
+          <span>&times;</span></button>
+        <h4>Add Workers</h4>
+      </div>
+      <div class="modal-body">
+        <p style="padding-top: 4px; padding-bottom: 14px;" 
ng-bind="description"></p>
+
+        <div ng-if="shouldNoticeSubmitFailed">
+          <div class="alert alert-danger alert-dismissible" role="alert">
+            <button type="button" class="close" data-dismiss="alert"
+                    ng-click="shouldNoticeSubmitFailed=false">
+              <span aria-hidden="true">&times;</span>
+            </button>
+            <h5 style="margin-top: 0">Something went wrong!</h5>
+            <p ng-bind="error"></p>
+          </div>
+        </div>
+
+        <form name="form" class="form-horizontal">
+          <!-- right margin align to cancel button right -->
+          <div style="margin-bottom: 18px">
+            <!-- input 1 -->
+            <form-control
+              label-style-class="col-sm-4"
+              control-style-class="col-sm-8"
+              type="integer" min="1" label="Instance Count"
+              ng-model="count"></form-control>
+          </div>
+        </form>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary btn-sm"
+                ng-click="add()">
+          <span ng-show="adding"
+                class="glyphicon glyphicon-repeat rotate-animation"></span>
+          Add
+        </button>
+        <button type="button" class="btn btn-default btn-sm" 
ng-click="$hide()">Cancel</button>
+      </div>
+    </div>
+  </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/views/cluster/workers/add_worker.js
----------------------------------------------------------------------
diff --git a/services/dashboard/views/cluster/workers/add_worker.js 
b/services/dashboard/views/cluster/workers/add_worker.js
new file mode 100644
index 0000000..ab4b42e
--- /dev/null
+++ b/services/dashboard/views/cluster/workers/add_worker.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed under the Apache License, Version 2.0
+ * See accompanying LICENSE file.
+ */
+angular.module('dashboard')
+
+  .controller('AddWorkerCtrl', ['$scope', 'restapi', 'i18n',
+    function($scope, restapi, i18n) {
+      'use strict';
+
+      $scope.description = i18n.terminology.worker;
+      $scope.count = 1;
+
+      $scope.add = function() {
+        $scope.adding = true;
+        $scope.shouldNoticeSubmitFailed = false;
+        return restapi.addWorker(
+          function handleResponse(response) {
+            $scope.shouldNoticeSubmitFailed = !response.success;
+            $scope.adding = false;
+            if (response.success) {
+              $scope.$hide();
+            } else {
+              $scope.error = response.error;
+            }
+          },
+          function handleException(ex) {
+            $scope.shouldNoticeSubmitFailed = true;
+            $scope.adding = false;
+            $scope.error = ex;
+          }
+        );
+      };
+    }])
+;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/views/cluster/workers/workers_listview.html
----------------------------------------------------------------------
diff --git a/services/dashboard/views/cluster/workers/workers_listview.html 
b/services/dashboard/views/cluster/workers/workers_listview.html
index f0eecf4..1f5295d 100644
--- a/services/dashboard/views/cluster/workers/workers_listview.html
+++ b/services/dashboard/views/cluster/workers/workers_listview.html
@@ -2,10 +2,21 @@
   <!-- control toolbar -->
   <div class="row">
     <div class="col-md-6">
-      <span class="table-caption-ext">Workers</span>
+      <span class="table-caption-ext pull-left">Workers</span>
+      <!-- dropdown button -->
+      <div ng-if="isSupervisor"
+           class="btn-group btn-group-after-heading">
+        <span class="btn btn-xs btn-default pull-left"
+              ng-click="showAddWorkerDialog()">
+          <span class="fa fa-plus"></span>
+          Add</span>
+      </div>
     </div>
-    <div class="col-md-3 col-md-offset-3 hidden-sm hidden-xs">
-      <searchbox ng-model="search" placeholder="Search Anything"></searchbox>
+    <div class="col-md-3 col-sm-6 text-right">
+      <!--FILTER-->
+    </div>
+    <div class="col-md-3 hidden-sm hidden-xs">
+      <searchbox ng-model="search" placeholder="Search Workers"></searchbox>
     </div>
   </div>
   <!-- end of control toolbar -->

http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/02597f75/services/dashboard/views/cluster/workers/workers_listview.js
----------------------------------------------------------------------
diff --git a/services/dashboard/views/cluster/workers/workers_listview.js 
b/services/dashboard/views/cluster/workers/workers_listview.js
index 3cdf14e..c277b38 100644
--- a/services/dashboard/views/cluster/workers/workers_listview.js
+++ b/services/dashboard/views/cluster/workers/workers_listview.js
@@ -18,28 +18,33 @@ angular.module('dashboard')
           resolve: {
             workers0: ['models', function(models) {
               return models.$get.workers();
+            }],
+            supervisor0: ['models', function(models) {
+              return models.$get.supervisor();
             }]
           }
         });
     }])
 
-  .controller('WorkersListViewCtrl', ['$scope', '$sortableTableBuilder', 
'workers0',
-    function($scope, $stb, workers0) {
+  .controller('WorkersListViewCtrl', ['$scope', '$modal', 
'$sortableTableBuilder', '$dialogs',
+    'restapi', 'workers0', 'supervisor0',
+    function($scope, $modal, $stb, $dialogs, restapi, workers0, supervisor0) {
       'use strict';
 
+      $scope.isSupervisor = (supervisor0.path||'').length > 0;
       $scope.workersTable = {
         cols: [
           // group 1/3 (4-col)
           
$stb.indicator().key('state').canSort('state.condition+"_"+aliveFor').styleClass('td-no-padding').done(),
-          
$stb.link('ID').key('id').canSort().sortDefaultDescent().styleClass('col-md-1').done(),
-          
$stb.text('Address').key('akkaAddr').canSort().styleClass('col-md-1').done(),
-          $stb.text('JVM Info').key('jvm').styleClass('col-md-2 
hidden-xs').done(),
+          $stb.link('ID').key('id').canSort().sortDefaultDescent().done(),
+          $stb.text('JVM Info').key('jvm').styleClass('col-md-1').done(),
+          $stb.text('Address').key('akkaAddr').canSort().styleClass('col-md-3 
hidden-xs').done(),
           // group 2/3 (5-col)
           
$stb.number('Executors').key('executors').canSort().styleClass('col-md-1 
hidden-xs').done(),
           $stb.progressbar('Slots 
Usage').key('slots').sortBy('slots.usage').styleClass('col-md-1').done(),
           
$stb.duration('Uptime').key('aliveFor').canSort().styleClass('col-md-3 
hidden-sm hidden-xs').done(),
           // group 3/3 (3-col)
-          $stb.button('Quick Links').key(['detail', 
'conf']).styleClass('col-md-3').done()
+          $stb.button('Quick Links').key(['detail', 'conf', 
'kill']).styleClass('col-md-3').done()
         ],
         rows: null
       };
@@ -56,7 +61,27 @@ angular.module('dashboard')
               slots: {current: worker.slots.used, max: worker.slots.total, 
usage: worker.slots.usage},
               executors: worker.executors.length || 0,
               detail: {href: worker.pageUrl, text: 'Details', class: 'btn-xs 
btn-primary'},
-              conf: {href: worker.configLink, target: '_blank', text: 
'Config', class: 'btn-xs'}
+              conf: {href: worker.configLink, target: '_blank', text: 
'Config', class: 'btn-xs'},
+              kill: {
+                text: 'Kill', class: 'btn-xs',
+                disabled: !$scope.isSupervisor,
+                click: function() {
+                  $dialogs.confirm('Are you sure to kill this worker?', 
function() {
+                    restapi.removeWorker(worker.workerId,
+                      function handleResponse(response) {
+                        if (response.success) {
+                          window.location.reload();
+                        } else {
+                          $dialogs.notice(response.error, 'Something went 
wrong');
+                        }
+                      },
+                      function handleException(ex) {
+                        $dialogs.notice(ex, 'Something went wrong');
+                      }
+                    );
+                  });
+                }
+              },
             };
           }));
       }
@@ -65,5 +90,17 @@ angular.module('dashboard')
       workers0.$subscribe($scope, function(data) {
         updateTable(data);
       });
+
+      var addWorkerDialog = $modal({
+        templateUrl: 'views/cluster/workers/add_worker.html',
+        controller: 'AddWorkerCtrl',
+        backdrop: 'static',
+        keyboard: true,
+        show: false
+      });
+
+      $scope.showAddWorkerDialog = function() {
+        addWorkerDialog.$promise.then(addWorkerDialog.show);
+      };
     }])
 ;
\ No newline at end of file

Reply via email to