1/**
2 * Controller for power-operations
3 *
4 * @module app/serverControl
5 * @exports powerOperationsController
6 * @name powerOperationsController
7 */
8
9window.angular && (function(angular) {
10  'use strict';
11
12  angular.module('app.serverControl').controller('powerOperationsController', [
13    '$scope', 'APIUtils', 'dataService', 'Constants', '$timeout', '$interval',
14    '$interpolate', '$q',
15    function(
16        $scope, APIUtils, dataService, Constants, $timeout, $interval,
17        $interpolate, $q) {
18      $scope.dataService = dataService;
19      $scope.confirm = false;
20      $scope.power_confirm = false;
21      $scope.warmboot_confirm = false;
22      $scope.coldboot_confirm = false;
23      $scope.orderly_confirm = false;
24      $scope.immediately_confirm = false;
25      $scope.loading = false;
26
27      var pollChassisStatusTimer = undefined;
28      var pollHostStatusTimer = undefined;
29      var pollStartTime = null;
30
31      //@TODO: call api and get proper state
32      $scope.toggleState = function() {
33        dataService.server_state =
34            (dataService.server_state == 'Running') ? 'Off' : 'Running';
35      };
36
37      $scope.powerOn = function() {
38        $scope.loading = true;
39        dataService.setUnreachableState();
40        APIUtils.hostPowerOn()
41            .then(function(response) {
42              return response;
43            })
44            .then(function(lastStatus) {
45              pollStartTime = new Date();
46              return pollHostStatusTillOn();
47            })
48            .then(function(hostState) {
49              $scope.loading = false;
50            })
51            .catch(function(error) {
52              dataService.activateErrorModal({
53                title: Constants.MESSAGES.POWER_OP.POWER_ON_FAILED,
54                description: error.statusText ?
55                    $interpolate(
56                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
57                        {status: error.status, description: error.statusText}) :
58                    error
59              });
60              $scope.loading = false;
61            });
62      };
63      $scope.powerOnConfirm = function() {
64        if ($scope.confirm) {
65          return;
66        }
67        $scope.confirm = true;
68        $scope.power_confirm = true;
69      };
70
71      function setHostState(state) {
72        if (state == Constants.HOST_STATE_TEXT.off_code) {
73          dataService.setPowerOffState();
74        } else if (state == Constants.HOST_STATE_TEXT.on_code) {
75          dataService.setPowerOnState();
76        } else {
77          dataService.setErrorState();
78        }
79      }
80
81      function pollChassisStatusTillOff() {
82        var deferred = $q.defer();
83        pollChassisStatusTimer = $interval(function() {
84          var now = new Date();
85          if ((now.getTime() - pollStartTime.getTime()) >=
86              Constants.TIMEOUT.CHASSIS_OFF) {
87            $interval.cancel(pollChassisStatusTimer);
88            pollChassisStatusTimer = undefined;
89            deferred.reject(
90                new Error(Constants.MESSAGES.POLL.CHASSIS_OFF_TIMEOUT));
91          }
92          APIUtils.getChassisState()
93              .then(function(state) {
94                if (state === Constants.CHASSIS_POWER_STATE.off_code) {
95                  $interval.cancel(pollChassisStatusTimer);
96                  pollChassisStatusTimer = undefined;
97                  deferred.resolve(state);
98                }
99              })
100              .catch(function(error) {
101                $interval.cancel(pollChassisStatusTimer);
102                pollChassisStatusTimer = undefined;
103                deferred.reject(error);
104              });
105        }, Constants.POLL_INTERVALS.POWER_OP);
106
107        return deferred.promise;
108      }
109
110      function pollHostStatusTillOn() {
111        var deferred = $q.defer();
112        pollHostStatusTimer = $interval(function() {
113          var now = new Date();
114          if ((now.getTime() - pollStartTime.getTime()) >=
115              Constants.TIMEOUT.HOST_ON) {
116            $interval.cancel(pollHostStatusTimer);
117            pollHostStatusTimer = undefined;
118            deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT));
119          }
120          APIUtils.getHostState()
121              .then(function(state) {
122                setHostState(state);
123                if (state === Constants.HOST_STATE_TEXT.on_code) {
124                  $interval.cancel(pollHostStatusTimer);
125                  pollHostStatusTimer = undefined;
126                  deferred.resolve(state);
127                } else if (state === Constants.HOST_STATE_TEXT.error_code) {
128                  $interval.cancel(pollHostStatusTimer);
129                  pollHostStatusTimer = undefined;
130                  deferred.reject(
131                      new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
132                }
133              })
134              .catch(function(error) {
135                $interval.cancel(pollHostStatusTimer);
136                pollHostStatusTimer = undefined;
137                deferred.reject(error);
138              });
139        }, Constants.POLL_INTERVALS.POWER_OP);
140
141        return deferred.promise;
142      }
143
144      function pollHostStatusTillOff() {
145        var deferred = $q.defer();
146        pollHostStatusTimer = $interval(function() {
147          var now = new Date();
148          if ((now.getTime() - pollStartTime.getTime()) >=
149              Constants.TIMEOUT.HOST_OFF) {
150            $interval.cancel(pollHostStatusTimer);
151            pollHostStatusTimer = undefined;
152            deferred.reject(
153                new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT));
154          }
155          APIUtils.getHostState()
156              .then(function(state) {
157                setHostState(state);
158                if (state === Constants.HOST_STATE_TEXT.off_code) {
159                  $interval.cancel(pollHostStatusTimer);
160                  pollHostStatusTimer = undefined;
161                  deferred.resolve(state);
162                }
163              })
164              .catch(function(error) {
165                $interval.cancel(pollHostStatusTimer);
166                pollHostStatusTimer = undefined;
167                deferred.reject(error);
168              });
169        }, Constants.POLL_INTERVALS.POWER_OP);
170
171        return deferred.promise;
172      }
173      $scope.warmReboot = function() {
174        $scope.loading = true;
175        dataService.setUnreachableState();
176        APIUtils.hostReboot()
177            .then(function(response) {
178              return response;
179            })
180            .then(function(lastStatus) {
181              pollStartTime = new Date();
182              return pollHostStatusTillOff();
183            })
184            .then(function(hostState) {
185              pollStartTime = new Date();
186              return pollHostStatusTillOn();
187            })
188            .then(function(hostState) {
189              $scope.loading = false;
190            })
191            .catch(function(error) {
192              dataService.activateErrorModal({
193                title: Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED,
194                description: error.statusText ?
195                    $interpolate(
196                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
197                        {status: error.status, description: error.statusText}) :
198                    error
199              });
200              $scope.loading = false;
201            });
202      };
203      $scope.testState = function() {
204        $timeout(function() {
205          dataService.setPowerOffState();
206          $timeout(function() {
207            dataService.setPowerOnState();
208          }, 2000);
209        }, 1000);
210      };
211      $scope.warmRebootConfirm = function() {
212        if ($scope.confirm) {
213          return;
214        }
215        $scope.confirm = true;
216        $scope.warmboot_confirm = true;
217      };
218
219      $scope.coldReboot = function() {
220        $scope.loading = true;
221        dataService.setUnreachableState();
222        APIUtils.chassisPowerOff()
223            .then(function(state) {
224              return state;
225            })
226            .then(function(lastState) {
227              pollStartTime = new Date();
228              return pollChassisStatusTillOff();
229            })
230            .then(function(chassisState) {
231              return APIUtils.hostPowerOn().then(function(hostState) {
232                return hostState;
233              });
234            })
235            .then(function(hostState) {
236              pollStartTime = new Date();
237              return pollHostStatusTillOn();
238            })
239            .then(function(state) {
240              $scope.loading = false;
241            })
242            .catch(function(error) {
243              dataService.activateErrorModal({
244                title: Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED,
245                description: error.statusText ?
246                    $interpolate(
247                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
248                        {status: error.status, description: error.statusText}) :
249                    error
250              });
251              $scope.loading = false;
252            });
253      };
254      $scope.coldRebootConfirm = function() {
255        if ($scope.confirm) {
256          return;
257        }
258        $scope.confirm = true;
259        $scope.coldboot_confirm = true;
260      };
261
262      $scope.orderlyShutdown = function() {
263        $scope.loading = true;
264        dataService.setUnreachableState();
265        APIUtils.hostPowerOff()
266            .then(function(response) {
267              return response;
268            })
269            .then(function(lastStatus) {
270              pollStartTime = new Date();
271              return pollHostStatusTillOff();
272            })
273            .then(function(hostState) {
274              pollStartTime = new Date();
275              return pollChassisStatusTillOff();
276            })
277            .then(function(chassisState) {
278              $scope.loading = false;
279            })
280            .catch(function(error) {
281              dataService.activateErrorModal({
282                title: Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED,
283                description: error.statusText ?
284                    $interpolate(
285                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
286                        {status: error.status, description: error.statusText}) :
287                    error
288              });
289              $scope.loading = false;
290            });
291      };
292      $scope.orderlyShutdownConfirm = function() {
293        if ($scope.confirm) {
294          return;
295        }
296        $scope.confirm = true;
297        $scope.orderly_confirm = true;
298      };
299
300      $scope.immediateShutdown = function() {
301        $scope.loading = true;
302        dataService.setUnreachableState();
303        APIUtils.chassisPowerOff()
304            .then(function(response) {
305              return response;
306            })
307            .then(function(lastStatus) {
308              pollStartTime = new Date();
309              return pollChassisStatusTillOff();
310            })
311            .then(function(chassisState) {
312              dataService.setPowerOffState();
313              $scope.loading = false;
314            })
315            .catch(function(error) {
316              dataService.activateErrorModal({
317                title: Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED,
318                description: error.statusText ?
319                    $interpolate(
320                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
321                        {status: error.status, description: error.statusText}) :
322                    error
323              });
324              $scope.loading = false;
325            });
326      };
327      $scope.immediateShutdownConfirm = function() {
328        if ($scope.confirm) {
329          return;
330        }
331        $scope.confirm = true;
332        $scope.immediately_confirm = true;
333      };
334    }
335  ]);
336
337})(angular);
338