You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jl...@apache.org on 2016/06/27 23:36:53 UTC

[27/34] ambari git commit: AMBARI-17355 & AMBARI-17354: POC: FE & BE changes for first class support for Yarn hosted services

http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/resources/app.js
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/app.js b/ambari-server/src/main/resources/app.js
new file mode 100644
index 0000000..901a697
--- /dev/null
+++ b/ambari-server/src/main/resources/app.js
@@ -0,0 +1,219702 @@
+(function() {
+  'use strict';
+
+  var globals = typeof window === 'undefined' ? global : window;
+  if (typeof globals.require === 'function') return;
+
+  var modules = {};
+  var cache = {};
+  var has = ({}).hasOwnProperty;
+
+  var aliases = {};
+
+  var endsWith = function(str, suffix) {
+    return str.indexOf(suffix, str.length - suffix.length) !== -1;
+  };
+
+  var unalias = function(alias, loaderPath) {
+    var start = 0;
+    if (loaderPath) {
+      if (loaderPath.indexOf('components/' === 0)) {
+        start = 'components/'.length;
+      }
+      if (loaderPath.indexOf('/', start) > 0) {
+        loaderPath = loaderPath.substring(start, loaderPath.indexOf('/', start));
+      }
+    }
+    var result = aliases[alias + '/index.js'] || aliases[loaderPath + '/deps/' + alias + '/index.js'];
+    if (result) {
+      return 'components/' + result.substring(0, result.length - '.js'.length);
+    }
+    return alias;
+  };
+
+  var expand = (function() {
+    var reg = /^\.\.?(\/|$)/;
+    return function(root, name) {
+      var results = [], parts, part;
+      parts = (reg.test(name) ? root + '/' + name : name).split('/');
+      for (var i = 0, length = parts.length; i < length; i++) {
+        part = parts[i];
+        if (part === '..') {
+          results.pop();
+        } else if (part !== '.' && part !== '') {
+          results.push(part);
+        }
+      }
+      return results.join('/');
+    };
+  })();
+  var dirname = function(path) {
+    return path.split('/').slice(0, -1).join('/');
+  };
+
+  var localRequire = function(path) {
+    return function(name) {
+      var absolute = expand(dirname(path), name);
+      return globals.require(absolute, path);
+    };
+  };
+
+  var initModule = function(name, definition) {
+    var module = {id: name, exports: {}};
+    cache[name] = module;
+    definition(module.exports, localRequire(name), module);
+    return module.exports;
+  };
+
+  var require = function(name, loaderPath) {
+    var path = expand(name, '.');
+    if (loaderPath == null) loaderPath = '/';
+    path = unalias(name, loaderPath);
+
+    if (has.call(cache, path)) return cache[path].exports;
+    if (has.call(modules, path)) return initModule(path, modules[path]);
+
+    var dirIndex = expand(path, './index');
+    if (has.call(cache, dirIndex)) return cache[dirIndex].exports;
+    if (has.call(modules, dirIndex)) return initModule(dirIndex, modules[dirIndex]);
+
+    throw new Error('Cannot find module "' + name + '" from '+ '"' + loaderPath + '"');
+  };
+
+  require.alias = function(from, to) {
+    aliases[to] = from;
+  };
+
+  require.register = require.define = function(bundle, fn) {
+    if (typeof bundle === 'object') {
+      for (var key in bundle) {
+        if (has.call(bundle, key)) {
+          modules[key] = bundle[key];
+        }
+      }
+    } else {
+      modules[bundle] = fn;
+    }
+  };
+
+  require.list = function() {
+    var result = [];
+    for (var item in modules) {
+      if (has.call(modules, item)) {
+        result.push(item);
+      }
+    }
+    return result;
+  };
+
+  require.brunch = true;
+  globals.require = require;
+})();
+require.register("app", function(exports, require, module) {
+/**
+ * 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.
+ */
+
+// Application bootstrapper
+require('utils/ember_reopen');
+require('utils/ember_computed');
+var stringUtils = require('utils/string_utils');
+
+module.exports = Em.Application.create({
+  name: 'Ambari Web',
+  rootElement: '#wrapper',
+
+  store: DS.Store.create({
+    revision: 4,
+    adapter: DS.FixtureAdapter.create({
+      simulateRemoteResponse: false
+    }),
+    typeMaps: {},
+    recordCache: []
+  }),
+  isAdmin: false,
+  isOperator: false,
+  isClusterUser: false,
+  isPermissionDataLoaded: false,
+  auth: null,
+  isOnlyViewUser: function() {
+    return App.auth && (App.auth.length == 0 || (App.isAuthorized('VIEW.USE') && App.auth.length == 1));
+  }.property('auth'),
+
+  /**
+   * @type {boolean}
+   * @default false
+   */
+  isKerberosEnabled: false,
+
+  /**
+   * state of stack upgrade process
+   * states:
+   *  - INIT
+   *  - PENDING
+   *  - IN_PROGRESS
+   *  - HOLDING
+   *  - COMPLETED
+   *  - ABORTED
+   *  - HOLDING_FAILED
+   *  - HOLDING_TIMEDOUT
+   * @type {String}
+   */
+  upgradeState: 'INIT',
+
+  /**
+   * flag is true when upgrade process is running
+   * @returns {boolean}
+   */
+  upgradeInProgress: Em.computed.equal('upgradeState', 'IN_PROGRESS'),
+
+  /**
+   * flag is true when upgrade process is waiting for user action
+   * to proceed, retry, perform manual steps etc.
+   * @returns {boolean}
+   */
+  upgradeHolding: function() {
+    return this.get('upgradeState').contains("HOLDING") || this.get('upgradeAborted');
+  }.property('upgradeState', 'upgradeAborted'),
+
+  /**
+   * flag is true when upgrade process is aborted
+   * SHOULD behave similar to HOLDING_FAILED state
+   * @returns {boolean}
+   */
+  upgradeAborted: function () {
+    return this.get('upgradeState') === "ABORTED" && !App.router.get('mainAdminStackAndUpgradeController.isSuspended');
+  }.property('upgradeState', 'App.router.mainAdminStackAndUpgradeController.isSuspended'),
+
+  /**
+   * flag is true when upgrade process is suspended
+   * @returns {boolean}
+   */
+  upgradeSuspended: function () {
+    return this.get('upgradeState') === "ABORTED" && App.router.get('mainAdminStackAndUpgradeController.isSuspended');
+  }.property('upgradeState', 'App.router.mainAdminStackAndUpgradeController.isSuspended'),
+
+  /**
+   * RU is running
+   * @type {boolean}
+   */
+  upgradeIsRunning: Em.computed.or('upgradeInProgress', 'upgradeHolding'),
+
+  /**
+   * flag is true when upgrade process is running or suspended
+   * or wizard used by another user
+   * @returns {boolean}
+   */
+  wizardIsNotFinished: function () {
+    return this.get('upgradeIsRunning') ||
+           this.get('upgradeSuspended') ||
+           App.router.get('wizardWatcherController.isNonWizardUser');
+  }.property('upgradeIsRunning', 'upgradeAborted', 'router.wizardWatcherController.isNonWizardUser', 'upgradeSuspended'),
+
+  /**
+   * Options:
+   *  - ignoreWizard: ignore when some wizard is running by another user (default `false`)
+   *
+   * @param {string} authRoles
+   * @param {object} options
+   * @returns {boolean}
+   */
+  isAuthorized: function(authRoles, options) {
+    options = $.extend({ignoreWizard: false}, options);
+    var result = false;
+    authRoles = $.map(authRoles.split(","), $.trim);
+
+    if (!this.get('upgradeSuspended') &&
+        !App.get('supports.opsDuringRollingUpgrade') &&
+        !['INIT', 'COMPLETED'].contains(this.get('upgradeState')) ||
+        !App.auth){
+      return false;
+    }
+
+    if (!options.ignoreWizard && App.router.get('wizardWatcherController.isNonWizardUser')) {
+      return false;
+    }
+
+    authRoles.forEach(function(auth) {
+      result = result || App.auth.contains(auth);
+    });
+
+    return result;
+  },
+
+  isStackServicesLoaded: false,
+  /**
+   * return url prefix with number value of version of HDP stack
+   */
+  stackVersionURL: function () {
+    return '/stacks/{0}/versions/{1}'.format(this.get('currentStackName') || 'HDP', this.get('currentStackVersionNumber'));
+  }.property('currentStackName','currentStackVersionNumber'),
+
+  falconServerURL: function () {
+    var falconService = this.Service.find().findProperty('serviceName', 'FALCON');
+    if (falconService) {
+      return falconService.get('hostComponents').findProperty('componentName', 'FALCON_SERVER').get('hostName');
+    }
+    return '';
+  }.property().volatile(),
+
+  /* Determine if Application Timeline Service supports Kerberization.
+   * Because this value is retrieved from the cardinality of the component, it is safe to keep in app.js
+   * since its value will not change during the lifetime of the application.
+   */
+  doesATSSupportKerberos: function() {
+    var YARNService = App.StackServiceComponent.find().filterProperty('serviceName', 'YARN');
+    if (YARNService.length) {
+      var ATS = App.StackServiceComponent.find().findProperty('componentName', 'APP_TIMELINE_SERVER');
+      return (!!ATS && !!ATS.get('minToInstall'));
+    }
+    return false;
+  }.property('router.clusterController.isLoaded'),
+
+  clusterName: null,
+  clockDistance: null, // server clock - client clock
+  currentStackVersion: '',
+  currentStackName: function() {
+    return Em.get((this.get('currentStackVersion') || this.get('defaultStackVersion')).match(/(.+)-\d.+/), '1');
+  }.property('currentStackVersion', 'defaultStackVersion'),
+
+  /**
+   * true if cluster has only 1 host
+   * for now is used to disable move/HA actions
+   * @type {boolean}
+   */
+  isSingleNode: Em.computed.equal('allHostNames.length', 1),
+
+  allHostNames: [],
+
+  /**
+   * This object is populated to keep track of uninstalled components to be included in the layout for recommendation/validation call
+   * @type {object}
+   * keys = componentName, hostName
+   */
+  componentToBeAdded: {},
+
+
+  /**
+   * This object is populated to keep track of installed components to be excluded in the layout for recommendation/validation call
+   * @type {object}
+   * keys = componentName, hostName
+   */
+  componentToBeDeleted: {},
+
+  uiOnlyConfigDerivedFromTheme: [],
+
+  currentStackVersionNumber: function () {
+    var regExp = new RegExp(this.get('currentStackName') + '-');
+    return (this.get('currentStackVersion') || this.get('defaultStackVersion')).replace(regExp, '');
+  }.property('currentStackVersion', 'defaultStackVersion', 'currentStackName'),
+
+  isHadoop23Stack: function () {
+    return (stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.3") > -1);
+  }.property('currentStackVersionNumber'),
+
+  isHadoopWindowsStack: Em.computed.equal('currentStackName', 'HDPWIN'),
+
+  /**
+   * If NameNode High Availability is enabled
+   * Based on <code>clusterStatus.isInstalled</code>, stack version, <code>SNameNode</code> availability
+   *
+   * @type {bool}
+   */
+  isHaEnabled: function () {
+    return App.Service.find('HDFS').get('isLoaded') && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE');
+  }.property('router.clusterController.dataLoadList.services', 'router.clusterController.isServiceContentFullyLoaded'),
+
+  /**
+   * If ResourceManager High Availability is enabled
+   * Based on number of ResourceManager host components installed
+   *
+   * @type {bool}
+   */
+  isRMHaEnabled: function () {
+    var result = false;
+    var rmStackComponent = App.StackServiceComponent.find().findProperty('componentName','RESOURCEMANAGER');
+    if (rmStackComponent && rmStackComponent.get('isMultipleAllowed')) {
+      result = this.HostComponent.find().filterProperty('componentName', 'RESOURCEMANAGER').length > 1;
+    }
+    return result;
+  }.property('router.clusterController.isLoaded', 'isStackServicesLoaded'),
+
+  /**
+   * If Ranger Admin High Availability is enabled
+   * Based on number of Ranger Admin host components installed
+   *
+   * @type {bool}
+   */
+  isRAHaEnabled: function () {
+    var result = false;
+    var raStackComponent = App.StackServiceComponent.find().findProperty('componentName','RANGER_ADMIN');
+    if (raStackComponent && raStackComponent.get('isMultipleAllowed')) {
+      result = App.HostComponent.find().filterProperty('componentName', 'RANGER_ADMIN').length > 1;
+    }
+    return result;
+  }.property('router.clusterController.isLoaded', 'isStackServicesLoaded'),
+
+  /**
+   * Object with utility functions for list of service names with similar behavior
+   */
+  services: Em.Object.create({
+    all: function () {
+      return App.StackService.find().mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    clientOnly: function () {
+      return App.StackService.find().filterProperty('isClientOnlyService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    hasClient: function () {
+      return App.StackService.find().filterProperty('hasClient').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    hasMaster: function () {
+      return App.StackService.find().filterProperty('hasMaster').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    hasSlave: function () {
+      return App.StackService.find().filterProperty('hasSlave').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    noConfigTypes: function () {
+      return App.StackService.find().filterProperty('isNoConfigTypes').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    servicesWithHeatmapTab: function () {
+      return App.StackService.find().filterProperty('hasHeatmapSection').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    monitoring: function () {
+      return App.StackService.find().filterProperty('isMonitoringService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    hostMetrics: function () {
+      return App.StackService.find().filterProperty('isHostMetricsService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    serviceMetrics: function () {
+      return App.StackService.find().filterProperty('isServiceMetricsService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+
+    supportsServiceCheck: function() {
+      return App.StackService.find().filterProperty('serviceCheckSupported').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded')
+  }),
+
+  /**
+   * List of components with allowed action for them
+   * @type {Em.Object}
+   */
+  components: Em.Object.create({
+    allComponents: function () {
+      return App.StackServiceComponent.find().mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    reassignable: function () {
+      return App.StackServiceComponent.find().filterProperty('isReassignable').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    restartable: function () {
+      return App.StackServiceComponent.find().filterProperty('isRestartable').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    deletable: function () {
+      return App.StackServiceComponent.find().filterProperty('isDeletable').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    rollinRestartAllowed: function () {
+      return App.StackServiceComponent.find().filterProperty('isRollinRestartAllowed').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    decommissionAllowed: function () {
+      return App.StackServiceComponent.find().filterProperty('isDecommissionAllowed').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    refreshConfigsAllowed: function () {
+      return App.StackServiceComponent.find().filterProperty('isRefreshConfigsAllowed').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    addableToHost: function () {
+      return App.StackServiceComponent.find().filterProperty('isAddableToHost').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    addableMasterInstallerWizard: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterAddableInstallerWizard').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    multipleMasters: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstances').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    slaves: function () {
+      return App.StackServiceComponent.find().filterProperty('isSlave').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    masters: function () {
+      return App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    clients: function () {
+      return App.StackServiceComponent.find().filterProperty('isClient').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    nonHDP: function () {
+      return App.StackServiceComponent.find().filterProperty('isNonHDPComponent').mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded')
+  })
+});
+
+});
+
+require.register("config", function(exports, require, module) {
+/**
+ * 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');
+
+App.version = '2.4.0.0'; // filled out by set-ambari-version.sh script
+App.testMode = (location.port == '3333'); // test mode is automatically enabled if running on brunch server
+App.testModeDelayForActions = 10000;
+App.skipBootstrap = false;
+App.alwaysGoToInstaller = false;
+App.testEnableSecurity = true; // By default enable security is tested; turning it false tests disable security
+App.testNameNodeHA = true;
+App.apiPrefix = '/api/v2';
+App.defaultStackVersion = 'HDP-2.5';
+App.defaultWindowsStackVersion = 'HDPWIN-2.1';
+
+App.defaultJavaHome = '/usr/jdk/jdk1.6.0_31';
+App.timeout = 180000; // default AJAX timeout
+App.maxRetries = 3; // max number of retries for certain AJAX calls
+App.sessionKeepAliveInterval  = 60000;
+App.bgOperationsUpdateInterval = 6000;
+App.componentsUpdateInterval = 6000;
+App.contentUpdateInterval = 15000;
+App.hostStatusCountersUpdateInterval = 10000;
+App.alertDefinitionsUpdateInterval = 10000;
+App.alertInstancesUpdateInterval = 10000;
+App.alertGroupsUpdateInterval = 10000;
+App.clusterEnvUpdateInterval = 10000;
+App.pageReloadTime = 3600000;
+App.nnCheckpointAgeAlertThreshold = 12; // in hours
+App.singleNodeInstall = false;
+App.singleNodeAlias = document.location.hostname;
+App.minDiskSpace = 2.0; // minimum disk space required for '/' for each host before install, unit GB
+App.minDiskSpaceUsrLib = 1.0; // minimum disk space for '/usr/lib' for each host before install, unit GB
+App.healthIconClassGreen = 'icon-ok-sign'; // bootstrap icon class for healthy/started service/host/host-component
+App.healthIconClassRed = 'icon-warning-sign'; // bootstrap icon class for master down/stopped service/host/host-component
+App.healthIconClassOrange = 'icon-minus-sign'; // bootstrap icon class for slave down/decommissioned host/host-component
+App.healthIconClassYellow = 'icon-question-sign'; // bootstrap icon class for heartbeat lost service/host/host-component
+App.isManagedMySQLForHiveEnabled = false;
+App.isStormMetricsSupported = true;
+App.healthStatusRed = '#ff0000';
+App.healthStatusGreen = '#5AB400';
+App.healthStatusOrange = '#FF8E00';
+App.inactivityRemainTime = 60; // in seconds
+
+App.stackVersionsAvailable = true;
+
+// experimental features are automatically enabled if running on brunch server
+App.enableExperimental = false;
+
+App.supports = {
+  preUpgradeCheck: true,
+  displayOlderVersions: false,
+  autoRollbackHA: false,
+  alwaysEnableManagedMySQLForHive: false,
+  preKerberizeCheck: false,
+  customizeAgentUserAccount: false,
+  installGanglia: false,
+  opsDuringRollingUpgrade: false,
+  customizedWidgetLayout: false,
+  showPageLoadTime: false,
+  skipComponentStartAfterInstall: false,
+  preInstallChecks: false,
+  hostComboSearchBox: true,
+  serviceAutoStart: false,
+  logSearch: true,
+  redhatSatellite: false,
+  enableIpa: false,
+  addingNewRepository: false,
+  kerberosStackAdvisor: true,
+  logCountVizualization: false
+};
+
+if (App.enableExperimental) {
+  for (var support in App.supports) {
+    App.supports[support] = true;
+  }
+}
+
+// this is to make sure that IE does not cache data when making AJAX calls to the server
+if (!$.mocho) {
+  $.ajaxSetup({
+    cache: false,
+    headers: {"X-Requested-By": "X-Requested-By"}
+  });
+}
+
+/**
+ * Test Mode values
+ */
+App.test_hostname = 'hostname';
+
+});
+
+require.register("controllers", function(exports, require, module) {
+/**
+ * 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.
+ */
+
+
+// load all controllers here
+
+require('controllers/application');
+require('controllers/login_controller');
+require('controllers/wizard');
+require('controllers/installer');
+require('controllers/experimental');
+require('controllers/global/background_operations_controller');
+require('controllers/global/wizard_watcher_controller');
+require('controllers/global/user_settings_controller');
+require('controllers/global/errors_handler_controller');
+require('controllers/main');
+require('controllers/main/dashboard');
+require('controllers/main/dashboard/config_history_controller');
+require('controllers/main/admin');
+require('controllers/main/admin/service_auto_start');
+require('controllers/main/admin/highAvailability_controller');
+require('controllers/main/admin/highAvailability/nameNode/wizard_controller');
+require('controllers/main/admin/highAvailability/progress_controller');
+require('controllers/main/admin/highAvailability/progress_popup_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollback_controller');
+require('controllers/main/admin/highAvailability/nameNode/step1_controller');
+require('controllers/main/admin/highAvailability/nameNode/step2_controller');
+require('controllers/main/admin/highAvailability/nameNode/step3_controller');
+require('controllers/main/admin/highAvailability/nameNode/step4_controller');
+require('controllers/main/admin/highAvailability/nameNode/step5_controller');
+require('controllers/main/admin/highAvailability/nameNode/step6_controller');
+require('controllers/main/admin/highAvailability/nameNode/step7_controller');
+require('controllers/main/admin/highAvailability/nameNode/step8_controller');
+require('controllers/main/admin/highAvailability/nameNode/step9_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller');
+require('controllers/main/admin/highAvailability/resourceManager/wizard_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step1_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step2_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step3_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step4_controller');
+require('controllers/main/admin/highAvailability/hawq/addStandby/wizard_controller');
+require('controllers/main/admin/highAvailability/hawq/addStandby/step1_controller');
+require('controllers/main/admin/highAvailability/hawq/addStandby/step2_controller');
+require('controllers/main/admin/highAvailability/hawq/addStandby/step3_controller');
+require('controllers/main/admin/highAvailability/hawq/addStandby/step4_controller');
+require('controllers/main/admin/highAvailability/hawq/removeStandby/wizard_controller');
+require('controllers/main/admin/highAvailability/hawq/removeStandby/step1_controller');
+require('controllers/main/admin/highAvailability/hawq/removeStandby/step2_controller');
+require('controllers/main/admin/highAvailability/hawq/removeStandby/step3_controller');
+require('controllers/main/admin/highAvailability/hawq/activateStandby/wizard_controller');
+require('controllers/main/admin/highAvailability/hawq/activateStandby/step1_controller');
+require('controllers/main/admin/highAvailability/hawq/activateStandby/step2_controller');
+require('controllers/main/admin/highAvailability/hawq/activateStandby/step3_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/wizard_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/step1_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/step2_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/step3_controller');
+require('controllers/main/admin/highAvailability/rangerAdmin/step4_controller');
+require('controllers/main/admin/stack_and_upgrade_controller');
+require('controllers/main/admin/serviceAccounts_controller');
+require('utils/polling');
+require('controllers/main/admin/kerberos');
+require('controllers/main/admin/kerberos/wizard_controller');
+require('controllers/main/admin/kerberos/disable_controller');
+require('controllers/main/admin/kerberos/progress_controller');
+require('controllers/main/admin/kerberos/step1_controller');
+require('controllers/main/admin/kerberos/step2_controller');
+require('controllers/main/admin/kerberos/step3_controller');
+require('controllers/main/admin/kerberos/step4_controller');
+require('controllers/main/admin/kerberos/step5_controller');
+require('controllers/main/admin/kerberos/step6_controller');
+require('controllers/main/admin/kerberos/step7_controller');
+require('controllers/main/admin/kerberos/step8_controller');
+require('controllers/main/alert_definitions_controller');
+require('controllers/main/alerts/alert_definitions_actions_controller');
+require('controllers/main/alerts/add_alert_definition/add_alert_definition_controller');
+require('controllers/main/alerts/add_alert_definition/step1_controller');
+require('controllers/main/alerts/add_alert_definition/step2_controller');
+require('controllers/main/alerts/add_alert_definition/step3_controller');
+require('controllers/main/alerts/definition_details_controller');
+require('controllers/main/alerts/definition_configs_controller');
+require('controllers/main/alerts/alert_instances_controller');
+require('controllers/main/alerts/manage_alert_groups_controller');
+require('controllers/main/alerts/manage_alert_notifications_controller');
+require('controllers/main/service');
+require('controllers/main/service/item');
+require('controllers/main/service/info/summary');
+require('controllers/main/service/info/configs');
+require('controllers/main/service/info/audit');
+require('controllers/main/service/add_controller');
+require('controllers/main/service/reassign_controller');
+require('controllers/main/service/reassign/step1_controller');
+require('controllers/main/service/reassign/step2_controller');
+require('controllers/main/service/reassign/step3_controller');
+require('controllers/main/service/reassign/step4_controller');
+require('controllers/main/service/reassign/step5_controller');
+require('controllers/main/service/reassign/step6_controller');
+require('controllers/main/service/manage_config_groups_controller');
+require('controllers/main/service/widgets/create/wizard_controller');
+require('controllers/main/service/widgets/create/step1_controller');
+require('controllers/main/service/widgets/create/step2_controller');
+require('controllers/main/service/widgets/create/step3_controller');
+require('controllers/main/service/widgets/edit_controller');
+require('controllers/main/host');
+require('controllers/main/host/bulk_operations_controller');
+require('controllers/main/host/details');
+require('controllers/main/host/configs_service');
+require('controllers/main/host/add_controller');
+require('controllers/main/host/combo_search_box');
+require('controllers/main/host/addHost/step4_controller');
+require('controllers/main/host/host_alerts_controller');
+require('controllers/main/charts');
+require('controllers/main/charts/heatmap_metrics/heatmap_metric');
+require('controllers/main/charts/heatmap');
+require('controllers/main/service/info/heatmap');
+require('controllers/main/views_controller');
+require('controllers/main/views/details_controller');
+require('controllers/wizard/step0_controller');
+require('controllers/wizard/step1_controller');
+require('controllers/wizard/step2_controller');
+require('controllers/wizard/step3_controller');
+require('controllers/wizard/step4_controller');
+require('controllers/wizard/step5_controller');
+require('controllers/wizard/step6_controller');
+require('controllers/wizard/step7_controller');
+require('controllers/wizard/step7/assign_master_controller');
+require('controllers/wizard/step7/pre_install_checks_controller');
+require('controllers/wizard/step8_controller');
+require('controllers/wizard/step9_controller');
+require('controllers/wizard/step10_controller');
+require('controllers/global/cluster_controller');
+require('controllers/global/update_controller');
+require('controllers/global/configuration_controller');
+require('controllers/main/service/reassign/step7_controller');
+
+});
+
+require.register("controllers/application", function(exports, require, module) {
+/**
+ * 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');
+
+App.ApplicationController = Em.Controller.extend(App.UserPref, {
+
+  name: 'applicationController',
+
+  isPollerRunning: false,
+
+  clusterName: function () {
+    return (App.router.get('clusterController.clusterName') || 'My Cluster');
+  }.property('App.router.clusterController.clusterName'),
+
+  /**
+   * set ambari server version from installerController or mainController, making sure version shown up all the time
+   */
+  ambariVersion: function () {
+    return (App.router.get('installerController.ambariServerVersion') || App.router.get('mainController.ambariServerVersion') || Em.I18n.t('common.notAvailable'));
+  }.property('App.router.installerController.ambariServerVersion', 'App.router.mainController.ambariServerVersion'),
+
+  clusterDisplayName: Em.computed.truncate('clusterName', 13, 10),
+
+  isClusterDataLoaded: Em.computed.and('App.router.clusterController.isLoaded','App.router.loggedIn'),
+
+  isExistingClusterDataLoaded: Em.computed.and('App.router.clusterInstallCompleted', 'isClusterDataLoaded'),
+
+  enableLinks: Em.computed.and('isExistingClusterDataLoaded', '!App.isOnlyViewUser'),
+
+  /**
+   * Determines if "Exit" menu-item should be shown
+   * It should if cluster isn't installed
+   * If cluster is installer, <code>isClusterDataLoaded</code> is checked
+   * @type {boolean}
+   */
+  showExitLink: function () {
+    if (App.router.get('clusterInstallCompleted')) {
+      return this.get('isClusterDataLoaded');
+    }
+    return true;
+  }.property('App.router.clusterInstallCompleted', 'isClusterDataLoaded'),
+
+  init: function(){
+    this._super();
+  },
+
+  startKeepAlivePoller: function() {
+    if (!this.get('isPollerRunning')) {
+     this.set('isPollerRunning',true);
+      App.updater.run(this, 'getStack', 'isPollerRunning', App.sessionKeepAliveInterval);
+    }
+  },
+
+  getStack: function(callback) {
+    App.ajax.send({
+      name: 'router.login.clusters',
+      sender: this,
+      callback: callback
+    });
+  },
+
+  goToAdminView: function () {
+    App.router.route("adminView");
+  },
+
+  showAboutPopup: function() {
+
+    var self = this;
+    App.ModalPopup.show({
+      header: Em.I18n.t('common.aboutAmbari'),
+      secondary: false,
+      bodyClass: Em.View.extend({
+        templateName: require('templates/common/about'),
+        ambariVersion: this.get('ambariVersion')
+      })
+    });    
+  }
+
+});
+});
+
+require.register("controllers/experimental", function(exports, require, module) {
+/**
+ * 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');
+
+App.ExperimentalController = Em.Controller.extend(App.UserPref, {
+  name: 'experimentalController',
+  supports: function () {
+    return Em.keys(App.get('supports')).map(function (sup) {
+      return Ember.Object.create({
+        name: sup,
+        selected: App.get('supports')[sup]
+      });
+    });
+  }.property('App.supports'),
+
+
+  loadSupports: function () {
+    return this.getUserPref('user-pref-' + App.router.get('loginName') + '-supports');
+  },
+
+  getUserPrefSuccessCallback: function (response, request, data) {
+    if (response) {
+      App.set('supports', response);
+    }
+  },
+
+  doSave: function () {
+    var supports = this.get('supports');
+    supports.forEach(function(s){
+      var propName = 'App.supports.' + s.get('name');
+      var propValue = s.get('selected');
+      Ember.set(propName, propValue);
+    });
+    this.postUserPref('user-pref-' + App.router.get('loginName') + '-supports', App.get('supports')).complete(function(){
+      App.router.transitionTo('root.index');
+    });
+  },
+
+  doCancel: function () {
+    App.router.transitionTo('root.index');
+  },
+
+  doResetUIStates: function () {
+    var self = this;
+    return App.ModalPopup.show({
+      header: Em.I18n.t('reset.ui.states'),
+      bodyClass: Ember.View.extend({
+        template: Ember.Handlebars.compile(Em.I18n.t('reset.ui.states.body'))
+      }),
+      primary: Em.I18n.t('yes'),
+      onPrimary: function () {
+        var router = App.router;
+        App.db.cleanUp();
+        router.clearAllSteps();
+        App.cache.clear();
+        App.clusterStatus.setClusterStatus({});
+        this.hide();
+        router.transitionTo('root.index');
+      }
+    });
+  }
+});
+
+});
+
+require.register("controllers/global/background_operations_controller", function(exports, require, module) {
+/**
+ * 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');
+
+App.BackgroundOperationsController = Em.Controller.extend({
+  name: 'backgroundOperationsController',
+
+  /**
+   * Whether we need to refresh background operations or not
+   */
+  isWorking : false,
+
+  allOperationsCount : 0,
+
+  /**
+   * For host component popup
+   */
+  services:[],
+  serviceTimestamp: null,
+
+  /**
+   * Number of operation to load
+   */
+  operationsCount: 10,
+  /**
+   * Possible levels:
+   * REQUESTS_LIST
+   * HOSTS_LIST
+   * TASKS_LIST
+   * TASK_DETAILS
+   */
+  levelInfo: Em.Object.create({
+    name: 'REQUESTS_LIST',
+    requestId: null,
+    taskId: null
+  }),
+
+  /**
+   * Start polling, when <code>isWorking</code> become true
+   */
+  startPolling: function(){
+    if(this.get('isWorking')){
+      this.requestMostRecent();
+      App.updater.run(this, 'requestMostRecent', 'isWorking', App.bgOperationsUpdateInterval);
+    }
+  }.observes('isWorking'),
+
+  /**
+   * Get requests data from server
+   * @param callback
+   */
+  requestMostRecent: function (callback) {
+    var queryParams = this.getQueryParams();
+    App.ajax.send({
+      'name': queryParams.name,
+      'sender': this,
+      'success': queryParams.successCallback,
+      'callback': callback,
+      'data': queryParams.data
+    });
+    return !this.isInitLoading();
+  },
+
+  /**
+   * indicate whether data for current level has already been loaded or not
+   * @return {Boolean}
+   */
+  isInitLoading: function () {
+    var levelInfo = this.get('levelInfo');
+    var request = this.get('services').findProperty('id', levelInfo.get('requestId'));
+
+    if (levelInfo.get('name') === 'HOSTS_LIST') {
+      return !!(request && App.isEmptyObject(request.get('hostsMap')));
+    }
+    return false;
+  },
+  /**
+   * construct params of ajax query regarding displayed level
+   */
+  getQueryParams: function () {
+    var levelInfo = this.get('levelInfo');
+    var count = this.get('operationsCount');
+    var result = {
+      name: 'background_operations.get_most_recent',
+      successCallback: 'callBackForMostRecent',
+      data: {
+        'operationsCount': count
+      }
+    };
+    if (levelInfo.get('name') === 'TASK_DETAILS' && !App.get('testMode')) {
+      result.name = 'background_operations.get_by_task';
+      result.successCallback = 'callBackFilteredByTask';
+      result.data = {
+        'taskId': levelInfo.get('taskId'),
+        'requestId': levelInfo.get('requestId')
+      };
+    } else if (levelInfo.get('name') === 'TASKS_LIST' || levelInfo.get('name') === 'HOSTS_LIST') {
+      result.name = 'background_operations.get_by_request';
+      result.successCallback = 'callBackFilteredByRequest';
+      result.data = {
+        'requestId': levelInfo.get('requestId')
+      };
+    }
+    return result;
+  },
+
+  /**
+   * Push hosts and their tasks to request
+   * @param data
+   * @param ajaxQuery
+   * @param params
+   */
+  callBackFilteredByRequest: function (data, ajaxQuery, params) {
+    var requestId = data.Requests.id;
+    var requestInputs = data.Requests.inputs;
+    var request = this.get('services').findProperty('id', requestId);
+    var hostsMap = {};
+    var previousTaskStatusMap = request.get('previousTaskStatusMap');
+    var currentTaskStatusMap = {};
+    data.tasks.forEach(function (task) {
+      var host = hostsMap[task.Tasks.host_name];
+      task.Tasks.request_id = requestId;
+      task.Tasks.request_inputs = requestInputs;
+      if (host) {
+        host.logTasks.push(task);
+        host.isModified = (host.isModified) ? true : previousTaskStatusMap[task.Tasks.id] !== task.Tasks.status;
+      } else {
+        hostsMap[task.Tasks.host_name] = {
+          name: task.Tasks.host_name,
+          publicName: task.Tasks.host_name,
+          logTasks: [task],
+          isModified: previousTaskStatusMap[task.Tasks.id] !== task.Tasks.status
+        };
+      }
+      currentTaskStatusMap[task.Tasks.id] = task.Tasks.status;
+    }, this);
+    /**
+     * sync up request progress with up to date progress of hosts on Host's list,
+     * to avoid discrepancies while waiting for response with latest progress of request
+     * after switching to operation's list
+     */
+    if (request.get('isRunning')) {
+      request.set('progress', App.HostPopup.getProgress(data.tasks));
+      request.set('status', App.HostPopup.getStatus(data.tasks)[0]);
+      request.set('isRunning', request.get('progress') !== 100);
+    }
+    request.set('previousTaskStatusMap', currentTaskStatusMap);
+    request.set('hostsMap', hostsMap);
+    this.set('serviceTimestamp', App.dateTime());
+  },
+  /**
+   * Update task, with uploading two additional properties: stdout and stderr
+   * @param data
+   * @param ajaxQuery
+   * @param params
+   */
+  callBackFilteredByTask: function (data, ajaxQuery, params) {
+    var request = this.get('services').findProperty('id', data.Tasks.request_id);
+    var host = request.get('hostsMap')[data.Tasks.host_name];
+    var task = host.logTasks.findProperty('Tasks.id', data.Tasks.id);
+    task.Tasks.status = data.Tasks.status;
+    task.Tasks.stdout = data.Tasks.stdout;
+    task.Tasks.stderr = data.Tasks.stderr;
+
+    // Put some command information to task object
+    task.Tasks.command = data.Tasks.command;
+    task.Tasks.custom_command_name = data.Tasks.custom_command_name;
+    task.Tasks.structured_out = data.Tasks.structured_out;
+
+    task.Tasks.output_log = data.Tasks.output_log;
+    task.Tasks.error_log = data.Tasks.error_log;
+    this.set('serviceTimestamp', App.dateTime());
+  },
+
+  /**
+   * returns true if it's upgrade equest
+   * use this flag to exclude upgrade requests from bgo
+   * @param {object} request
+   * @returns {boolean}
+   */
+  isUpgradeRequest: function(request) {
+    var context = Em.get(request, 'Requests.request_context');
+    return context ? /(upgrading|downgrading)/.test(context.toLowerCase()) : false;
+  },
+  /**
+   * Prepare, received from server, requests for host component popup
+   * @param data
+   */
+  callBackForMostRecent: function (data) {
+    var runningServices = 0;
+    var currentRequestIds = [];
+    var countIssued = this.get('operationsCount');
+    var countGot = data.itemTotal;
+    var restoreUpgradeState = false;
+
+    data.items.forEach(function (request) {
+      if (this.isUpgradeRequest(request)) {
+        if (!App.get('upgradeIsRunning') && !App.get('testMode')) {
+          restoreUpgradeState = true;
+        }
+        return;
+      }
+      var rq = this.get("services").findProperty('id', request.Requests.id);
+      var isRunning = this.isRequestRunning(request);
+      var requestParams = this.parseRequestContext(request.Requests.request_context);
+      this.assignScheduleId(request, requestParams);
+      currentRequestIds.push(request.Requests.id);
+
+      if (rq) {
+        rq.setProperties({
+          progress: Math.floor(request.Requests.progress_percent),
+          status: request.Requests.request_status,
+          isRunning: isRunning,
+          startTime: App.dateTimeWithTimeZone(request.Requests.start_time),
+          endTime: request.Requests.end_time > 0 ? App.dateTimeWithTimeZone(request.Requests.end_time) : request.Requests.end_time
+        });
+      } else {
+        rq = Em.Object.create({
+          id: request.Requests.id,
+          name: requestParams.requestContext,
+          displayName: requestParams.requestContext,
+          progress: Math.floor(request.Requests.progress_percent),
+          status: request.Requests.request_status,
+          isRunning: isRunning,
+          hostsMap: {},
+          tasks: [],
+          startTime: App.dateTimeWithTimeZone(request.Requests.start_time),
+          endTime: request.Requests.end_time > 0 ? App.dateTimeWithTimeZone(request.Requests.end_time) : request.Requests.end_time,
+          dependentService: requestParams.dependentService,
+          sourceRequestScheduleId: request.Requests.request_schedule && request.Requests.request_schedule.schedule_id,
+          previousTaskStatusMap: {},
+          contextCommand: requestParams.contextCommand
+        });
+        this.get("services").unshift(rq);
+        //To sort DESC by request id
+        this.set("services", this.get("services").sortProperty('id').reverse());
+      }
+      runningServices += ~~isRunning;
+    }, this);
+    if (restoreUpgradeState) {
+      App.router.get('clusterController').restoreUpgradeState();
+    }
+    this.removeOldRequests(currentRequestIds);
+    this.set("allOperationsCount", runningServices);
+    this.set('isShowMoreAvailable', countGot >= countIssued);
+    this.set('serviceTimestamp', App.dateTimeWithTimeZone());
+  },
+
+  isShowMoreAvailable: null,
+
+  /**
+   * remove old requests
+   * as API returns 10, or  20 , or 30 ...etc latest request, the requests that absent in response should be removed
+   * @param currentRequestIds
+   */
+  removeOldRequests: function (currentRequestIds) {
+    var services = this.get('services');
+
+    for (var i = 0, l = services.length; i < l; i++) {
+      if (!currentRequestIds.contains(services[i].id)) {
+        services.splice(i, 1);
+        i--;
+        l--;
+      }
+    }
+  },
+
+  /**
+   * identify whether request is running by task counters
+   * @param request
+   * @return {Boolean}
+   */
+  isRequestRunning: function (request) {
+    return (request.Requests.task_count -
+      (request.Requests.aborted_task_count + request.Requests.completed_task_count + request.Requests.failed_task_count
+        + request.Requests.timed_out_task_count - request.Requests.queued_task_count)) > 0;
+  },
+  /**
+   * identify whether there is only one host in request
+   * @param inputs
+   * @return {Boolean}
+   */
+  isOneHost: function (inputs) {
+    if (!inputs) {
+      return false;
+    }
+    inputs = JSON.parse(inputs);
+    if (inputs && inputs.included_hosts) {
+      return inputs.included_hosts.split(',').length < 2;
+    }
+    return false
+  },
+  /**
+   * assign schedule_id of request to null if it's Recommission operation
+   * @param request
+   * @param requestParams
+   */
+  assignScheduleId: function (request, requestParams) {
+    var oneHost = this.isOneHost(request.Requests.inputs);
+    if (request.Requests.request_schedule && oneHost && /Recommission/.test(requestParams.requestContext)) {
+      request.Requests.request_schedule.schedule_id = null;
+    }
+  },
+
+  /**
+   * parse request context and if keyword "_PARSE_" is present then format it
+   * @param requestContext
+   * @return {Object}
+   */
+  parseRequestContext: function (requestContext) {
+    var parsedRequestContext;
+    var service;
+    var contextCommand;
+    if (requestContext) {
+      if (requestContext.indexOf(App.BackgroundOperationsController.CommandContexts.PREFIX) !== -1) {
+        var contextSplits = requestContext.split('.');
+        contextCommand = contextSplits[1];
+        service = contextSplits[2];
+        switch(contextCommand){
+        case "STOP":
+        case "START":
+          if (service === 'ALL_SERVICES') {
+            parsedRequestContext = Em.I18n.t("requestInfo." + contextCommand.toLowerCase()).format(Em.I18n.t('common.allServices'));
+          } else {
+            parsedRequestContext = Em.I18n.t("requestInfo." + contextCommand.toLowerCase()).format(App.format.role(service, true));
+          }
+          break;
+        case "ROLLING-RESTART":
+          parsedRequestContext = Em.I18n.t("rollingrestart.rest.context").format(App.format.role(service, true), contextSplits[3], contextSplits[4]);
+          break;
+        }
+      } else {
+        parsedRequestContext = requestContext;
+      }
+    } else {
+      parsedRequestContext = Em.I18n.t('requestInfo.unspecified');
+    }
+    return {
+      requestContext: parsedRequestContext,
+      dependentService: service,
+      contextCommand: contextCommand
+    }
+  },
+
+  popupView: null,
+
+  /**
+   * Onclick handler for background operations number located right to logo
+   */
+  showPopup: function(){
+    // load the checkbox on footer first, then show popup.
+    var self = this;
+    App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) {
+      App.updater.immediateRun('requestMostRecent');
+      if(self.get('popupView') && App.HostPopup.get('isBackgroundOperations')){
+        self.set ('popupView.isNotShowBgChecked', !initValue);
+        self.set('popupView.isOpen', true);
+        $(self.get('popupView.element')).appendTo('#wrapper');
+      } else {
+        self.set('popupView', App.HostPopup.initPopup("", self, true));
+        self.set('popupView.isNotShowBgChecked', !initValue);
+      }
+    });
+  },
+
+  /**
+   * Called on logout
+   */
+  clear: function () {
+    // set operations count to default value
+    this.set('operationsCount', 10);
+  }
+
+});
+
+/**
+ * Each background operation has a context in which it operates.
+ * Generally these contexts are fixed messages. However, we might
+ * want to associate semantics to this context - like showing, disabling
+ * buttons when certain operations are in progress.
+ *
+ * To make this possible we have command contexts where the context
+ * is not a human readable string, but a pattern indicating the command
+ * it is running. When UI shows these, they are translated into human
+ * readable strings.
+ *
+ * General pattern of context names is "_PARSE_.{COMMAND}.{ID}[.{Additional-Data}...]"
+ */
+App.BackgroundOperationsController.CommandContexts = {
+  PREFIX : "_PARSE_",
+  /**
+   * Stops all services
+   */
+  STOP_ALL_SERVICES : "_PARSE_.STOP.ALL_SERVICES",
+  /**
+   * Starts all services
+   */
+  START_ALL_SERVICES : "_PARSE_.START.ALL_SERVICES",
+  /**
+   * Starts service indicated by serviceID.
+   * @param {String} serviceID Parameter {0}. Example: HDFS
+   */
+  START_SERVICE : "_PARSE_.START.{0}",
+  /**
+   * Stops service indicated by serviceID.
+   * @param {String} serviceID Parameter {0}. Example: HDFS
+   */
+  STOP_SERVICE : "_PARSE_.STOP.{0}",
+  /**
+   * Performs rolling restart of componentID in batches.
+   * This context is the batchNumber batch out of totalBatchCount batches.
+   * @param {String} componentID Parameter {0}. Example "DATANODE"
+   * @param {Number} batchNumber Parameter {1}. Batch number of this batch. Example 3.
+   * @param {Number} totalBatchCount Parameter {2}. Total number of batches. Example 10.
+   */
+  ROLLING_RESTART : "_PARSE_.ROLLING-RESTART.{0}.{1}.{2}"
+};
+
+});
+
+require.register("controllers/global/cluster_controller", function(exports, require, module) {
+/**
+ * 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 stringUtils = require('utils/string_utils');
+var credentialUtils = require('utils/credentials');
+
+App.ClusterController = Em.Controller.extend(App.ReloadPopupMixin, {
+  name: 'clusterController',
+  isLoaded: false,
+  ambariProperties: null,
+  clusterEnv: null,
+  clusterDataLoadedPercent: 'width:0', // 0 to 1
+
+  isClusterNameLoaded: false,
+
+  isAlertsLoaded: false,
+
+  isComponentsStateLoaded: false,
+
+  isHostsLoaded: false,
+
+  isConfigsPropertiesLoaded: false,
+
+  isComponentsConfigLoaded: false,
+
+  isStackConfigsLoaded: false,
+
+  isServiceMetricsLoaded: false,
+
+  /**
+   * @type {boolean}
+   */
+  isHostComponentMetricsLoaded: false,
+
+  /**
+   * Ambari uses custom jdk.
+   * @type {Boolean}
+   */
+  isCustomJDK: false,
+
+  isHostContentLoaded: Em.computed.and('isHostsLoaded', 'isComponentsStateLoaded'),
+
+  isServiceContentFullyLoaded: Em.computed.and('isServiceMetricsLoaded', 'isComponentsStateLoaded', 'isComponentsConfigLoaded'),
+
+  clusterName: Em.computed.alias('App.clusterName'),
+
+  updateLoadStatus: function (item) {
+    var loadList = this.get('dataLoadList');
+    var loaded = true;
+    var numLoaded = 0;
+    var loadListLength = 0;
+    loadList.set(item, true);
+    for (var i in loadList) {
+      if (loadList.hasOwnProperty(i)) {
+        loadListLength++;
+        if (!loadList[i] && loaded) {
+          loaded = false;
+        }
+      }
+      // calculate the number of true
+      if (loadList.hasOwnProperty(i) && loadList[i]) {
+        numLoaded++;
+      }
+    }
+    this.set('isLoaded', loaded);
+    this.set('clusterDataLoadedPercent', 'width:' + (Math.floor(numLoaded / loadListLength * 100)).toString() + '%');
+  },
+
+  dataLoadList: Em.Object.create({
+    'stackComponents': false,
+    'services': false
+  }),
+
+  /**
+   * load cluster name
+   */
+  loadClusterName: function (reload, deferred) {
+    var dfd = deferred || $.Deferred();
+
+    if (App.get('clusterName') && !reload) {
+      App.set('clusterName', this.get('clusterName'));
+      this.set('isClusterNameLoaded', true);
+      dfd.resolve();
+    } else {
+      App.ajax.send({
+        name: 'cluster.load_cluster_name',
+        sender: this,
+        data: {
+          reloadPopupText: Em.I18n.t('app.reloadPopup.noClusterName.text'),
+          errorLogMessage: 'failed on loading cluster name',
+          callback: this.loadClusterName,
+          args: [reload, dfd],
+          shouldUseDefaultHandler: true
+        },
+        success: 'reloadSuccessCallback',
+        error: 'reloadErrorCallback',
+        callback: function () {
+          if (!App.get('currentStackVersion')) {
+            App.set('currentStackVersion', App.defaultStackVersion);
+          }
+        }
+      }).then(
+        function () {
+          dfd.resolve();
+        },
+        null
+      );
+    }
+    return dfd.promise();
+  },
+
+  reloadSuccessCallback: function (data) {
+    this._super();
+    if (data.items && data.items.length > 0) {
+      App.setProperties({
+        clusterName: data.items[0].Clusters.cluster_name,
+        currentStackVersion: data.items[0].Clusters.version,
+        isKerberosEnabled: data.items[0].Clusters.security_type === 'KERBEROS'
+      });
+      this.set('isClusterNameLoaded', true);
+    }
+  },
+
+  /**
+   * load current server clock in milli-seconds
+   */
+  loadClientServerClockDistance: function () {
+    var dfd = $.Deferred();
+    this.getServerClock().done(function () {
+      dfd.resolve();
+    });
+    return dfd.promise();
+  },
+
+  getServerClock: function () {
+    return App.ajax.send({
+      name: 'ambari.service',
+      sender: this,
+      data: {
+        fields: '?fields=RootServiceComponents/server_clock'
+      },
+      success: 'getServerClockSuccessCallback',
+      error: 'getServerClockErrorCallback'
+    });
+  },
+  getServerClockSuccessCallback: function (data) {
+    var clientClock = new Date().getTime();
+    var serverClock = (data.RootServiceComponents.server_clock).toString();
+    serverClock = serverClock.length < 13 ? serverClock + '000' : serverClock;
+    App.set('clockDistance', serverClock - clientClock);
+    App.set('currentServerTime', parseInt(serverClock));
+  },
+  getServerClockErrorCallback: function () {
+  },
+
+  getUrl: function (testUrl, url) {
+    return (App.get('testMode')) ? testUrl : App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + url;
+  },
+
+  /**
+   *  load all data and update load status
+   */
+  loadClusterData: function () {
+    var self = this;
+    this.loadAuthorizations();
+    this.getAllHostNames();
+    this.loadAmbariProperties();
+    if (!App.get('clusterName')) {
+      return;
+    }
+
+    if (this.get('isLoaded')) { // do not load data repeatedly
+      App.router.get('mainController').startPolling();
+      return;
+    }
+    App.router.get('userSettingsController').getAllUserSettings();
+    var clusterUrl = this.getUrl('/data/clusters/cluster.json', '?fields=Clusters');
+    var hostsController = App.router.get('mainHostController');
+    hostsController.set('isCountersUpdating', true);
+    hostsController.updateStatusCounters();
+
+    App.HttpClient.get(clusterUrl, App.clusterMapper, {
+      complete: function (jqXHR, textStatus) {
+        App.set('isCredentialStorePersistent', Em.getWithDefault(App.Cluster.find().findProperty('clusterName', App.get('clusterName')), 'isCredentialStorePersistent', false));
+      }
+    }, function (jqXHR, textStatus) {
+    });
+
+
+    self.restoreUpgradeState();
+
+    App.router.get('wizardWatcherController').getUser();
+
+    var updater = App.router.get('updateController');
+
+    /**
+     * Order of loading:
+     * 1. load all created service components
+     * 2. request for service components supported by stack
+     * 3. load stack components to model
+     * 4. request for services
+     * 5. put services in cache
+     * 6. request for hosts and host-components (single call)
+     * 7. request for service metrics
+     * 8. load host-components to model
+     * 9. load services from cache with metrics to model
+     */
+    self.loadStackServiceComponents(function (data) {
+      data.items.forEach(function (service) {
+        service.StackServices.is_selected = true;
+        service.StackServices.is_installed = false;
+      }, self);
+      App.stackServiceMapper.mapStackServices(data);
+      App.config.setPreDefinedServiceConfigs(true);
+      self.updateLoadStatus('stackComponents');
+      updater.updateServices(function () {
+        self.updateLoadStatus('services');
+
+        //hosts should be loaded after services in order to properly populate host-component relation in App.cache.services
+        updater.updateHost(function () {
+          self.set('isHostsLoaded', true);
+        });
+        App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
+          App.config.loadClusterConfigsFromStack().complete(function () {
+            self.set('isConfigsPropertiesLoaded', true);
+          });
+        });
+        // components state loading doesn't affect overall progress
+        updater.updateComponentsState(function () {
+          self.set('isComponentsStateLoaded', true);
+          // service metrics should be loaded after components state for mapping service components to service in the DS model
+          // service metrics loading doesn't affect overall progress
+          updater.updateServiceMetric(function () {
+            self.set('isServiceMetricsLoaded', true);
+            // make second call, because first is light since it doesn't request host-component metrics
+            updater.updateServiceMetric(function() {
+              self.set('isHostComponentMetricsLoaded', true);
+            });
+            // components config loading doesn't affect overall progress
+            updater.updateComponentConfig(function () {
+              self.set('isComponentsConfigLoaded', true);
+            });
+          });
+        });
+      });
+    });
+
+    //force clear filters  for hosts page to load all data
+    App.db.setFilterConditions('mainHostController', null);
+
+    // alerts loading doesn't affect overall progress
+    console.time('Overall alerts loading time');
+    updater.updateAlertGroups(function () {
+      updater.updateAlertDefinitions(function () {
+        updater.updateAlertDefinitionSummary(function () {
+          updater.updateUnhealthyAlertInstances(function () {
+            console.timeEnd('Overall alerts loading time');
+            self.set('isAlertsLoaded', true);
+          });
+        });
+      });
+    });
+
+    //load cluster-env, used by alert check tolerance // TODO services auto-start
+    updater.updateClusterEnv();
+
+    /*  Root service mapper maps all the data exposed under Ambari root service which includes ambari configurations i.e ambari-properties
+     ** This is useful information but its not being used in the code anywhere as of now
+
+     self.loadRootService().done(function (data) {
+     App.rootServiceMapper.map(data);
+     self.updateLoadStatus('rootService');
+     });
+
+     */
+  },
+
+  /**
+   * restore upgrade status from server
+   * and make call to get latest status from server
+   */
+  restoreUpgradeState: function () {
+    return this.getAllUpgrades().done(function (data) {
+      var upgradeController = App.router.get('mainAdminStackAndUpgradeController');
+      var lastUpgradeData = data.items.sortProperty('Upgrade.request_id').pop();
+      var dbUpgradeState = App.db.get('MainAdminStackAndUpgrade', 'upgradeState');
+
+      if (!Em.isNone(dbUpgradeState)) {
+        App.set('upgradeState', dbUpgradeState);
+      }
+
+      if (lastUpgradeData) {
+        upgradeController.restoreLastUpgrade(lastUpgradeData);
+      } else {
+        upgradeController.initDBProperties();
+        upgradeController.loadUpgradeData(true);
+      }
+      upgradeController.loadStackVersionsToModel(true).done(function () {
+        App.set('stackVersionsAvailable', App.StackVersion.find().content.length > 0);
+      });
+    });
+  },
+
+  loadRootService: function () {
+    return App.ajax.send({
+      name: 'service.ambari',
+      sender: this
+    });
+  },
+
+  requestHosts: function (realUrl, callback) {
+    var testHostUrl = '/data/hosts/HDP2/hosts.json';
+    var url = this.getUrl(testHostUrl, realUrl);
+    App.HttpClient.get(url, App.hostsMapper, {
+      complete: callback
+    }, callback)
+  },
+
+  /**
+   *
+   * @param callback
+   */
+  loadStackServiceComponents: function (callback) {
+    var callbackObj = {
+      loadStackServiceComponentsSuccess: callback
+    };
+    App.ajax.send({
+      name: 'wizard.service_components',
+      data: {
+        stackUrl: App.get('stackVersionURL'),
+        stackVersion: App.get('currentStackVersionNumber')
+      },
+      sender: callbackObj,
+      success: 'loadStackServiceComponentsSuccess'
+    });
+  },
+
+  loadAmbariProperties: function () {
+    return App.ajax.send({
+      name: 'ambari.service',
+      sender: this,
+      success: 'loadAmbariPropertiesSuccess',
+      error: 'loadAmbariPropertiesError'
+    });
+  },
+
+  loadAuthorizations: function() {
+    return App.ajax.send({
+      name: 'router.user.authorizations',
+      sender: this,
+      data: {userName: App.db.getLoginName()},
+      success: 'loadAuthorizationsSuccessCallback'
+    });
+  },
+
+  loadAuthorizationsSuccessCallback: function(response) {
+    if (response && response.items) {
+      App.set('auth', response.items.mapProperty('AuthorizationInfo.authorization_id').uniq());
+      App.db.setAuth(App.get('auth'));
+    }
+  },
+
+  loadAmbariPropertiesSuccess: function (data) {
+    this.set('ambariProperties', data.RootServiceComponents.properties);
+    // Absence of 'jdk.name' and 'jce.name' properties says that ambari configured with custom jdk.
+    this.set('isCustomJDK', App.isEmptyObject(App.permit(data.RootServiceComponents.properties, ['jdk.name', 'jce.name'])));
+    App.router.get('mainController').monitorInactivity();
+  },
+
+  loadAmbariPropertiesError: function () {
+
+  },
+
+  updateClusterData: function () {
+    var testUrl = '/data/clusters/HDP2/cluster.json';
+    var clusterUrl = this.getUrl(testUrl, '?fields=Clusters');
+    App.HttpClient.get(clusterUrl, App.clusterMapper, {
+      complete: function () {
+      }
+    });
+  },
+
+  /**
+   *
+   * @returns {*|Transport|$.ajax|boolean|ServerResponse}
+   */
+  getAllHostNames: function () {
+    return App.ajax.send({
+      name: 'hosts.all',
+      sender: this,
+      success: 'getHostNamesSuccess',
+      error: 'getHostNamesError'
+    });
+  },
+
+  getHostNamesSuccess: function (data) {
+    App.set("allHostNames", data.items.mapProperty("Hosts.host_name"));
+  },
+
+  getHostNamesError: function () {
+
+  },
+
+
+  /**
+   * puts kerberos admin credentials in the live cluster session
+   * and resend ajax request
+   * @param {credentialResourceObject} credentialResource
+   * @param {object} ajaxOpt
+   * @returns {$.ajax}
+   */
+  createKerberosAdminSession: function (credentialResource, ajaxOpt) {
+    return credentialUtils.createOrUpdateCredentials(App.get('clusterName'), credentialUtils.ALIAS.KDC_CREDENTIALS, credentialResource).then(function() {
+      if (ajaxOpt) {
+        $.ajax(ajaxOpt);
+      }
+    });
+  },
+
+  //TODO Replace this check with any other which is applicable to non-HDP stack
+  /**
+   * Check if HDP stack version is more or equal than 2.2.2 to determine if pluggable metrics for Storm are supported
+   * @method checkDetailedRepoVersion
+   * @returns {promise|*|promise|promise|HTMLElement|promise}
+   */
+  checkDetailedRepoVersion: function () {
+    var dfd;
+    var currentStackName = App.get('currentStackName');
+    var currentStackVersionNumber = App.get('currentStackVersionNumber');
+    if (currentStackName == 'HDP' && currentStackVersionNumber == '2.2') {
+      dfd = App.ajax.send({
+        name: 'cluster.load_detailed_repo_version',
+        sender: this,
+        success: 'checkDetailedRepoVersionSuccessCallback',
+        error: 'checkDetailedRepoVersionErrorCallback'
+      });
+    } else {
+      dfd = $.Deferred();
+      App.set('isStormMetricsSupported', currentStackName != 'HDP' || stringUtils.compareVersions(currentStackVersionNumber, '2.2') == 1);
+      dfd.resolve();
+    }
+    return dfd.promise();
+  },
+
+  checkDetailedRepoVersionSuccessCallback: function (data) {
+    var items = data.items;
+    var version;
+    if (items && items.length) {
+      var repoVersions = items[0].repository_versions;
+      if (repoVersions && repoVersions.length) {
+        version = Em.get(repoVersions[0], 'RepositoryVersions.repository_version');
+      }
+    }
+    App.set('isStormMetricsSupported', stringUtils.compareVersions(version, '2.2.2') > -1 || !version);
+  },
+  checkDetailedRepoVersionErrorCallback: function () {
+    App.set('isStormMetricsSupported', true);
+  },
+
+  /**
+   * Load required data for all upgrades from API
+   * @returns {$.ajax}
+   */
+  getAllUpgrades: function () {
+    return App.ajax.send({
+      name: 'cluster.load_last_upgrade',
+      sender: this
+    });
+  }
+});
+
+});
+
+require.register("controllers/global/configuration_controller", function(exports, require, module) {
+/**
+ * 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');
+
+App.ConfigurationController = Em.Controller.extend({
+  name: 'configurationController',
+
+  /**
+   * get configs by tags
+   * return Deferred object with configs as argument
+   * @param tags {Object}
+   * ** siteName
+   * ** tagName (optional)
+   * @return {object}
+   */
+  getConfigsByTags: function (tags) {
+    var storedTags = [];
+    App.db.getConfigs().forEach(function (site) {
+      storedTags.push({
+        siteName: site.type,
+        tagName: site.tag
+      })
+    });
+    if (this.checkTagsChanges(tags, storedTags)) {
+      return this.loadFromServer(tags);
+    } else {
+      return this.loadFromDB(tags.mapProperty('siteName'));
+    }
+  },
+  /**
+   * check whether tag versions have been changed
+   * if they are different then return true
+   * otherwise false
+   * @param tags
+   * @param storedTags
+   * @return {Boolean}
+   */
+  checkTagsChanges: function (tags, storedTags) {
+    var isDifferent = false;
+    var i = 0;
+    while (i < tags.length && !isDifferent) {
+      var storedTag = storedTags.findProperty('siteName', tags[i].siteName);
+      isDifferent = (!storedTag || !tags[i].tagName || storedTag.tagName !== tags[i].tagName);
+      i++;
+    }
+    return isDifferent;
+  },
+  loadFromDB: function (siteNames) {
+    var dfd = $.Deferred();
+    var configs = App.db.getConfigs().filter(function (site) {
+      return (siteNames.contains(site.type));
+    });
+    dfd.resolve(configs);
+    return dfd.promise()
+  },
+  /**
+   * load configs from server
+   * and update them in local DB
+   * @param tags
+   * @return {Array}
+   */
+  loadFromServer: function (tags) {
+    var self = this;
+    var dfd = $.Deferred();
+    if (!tags.everyProperty('tagName')) {
+      var configTags;
+      var jqXhr =  this.loadConfigTags();
+      jqXhr.done(function (data) {
+        configTags = data.Clusters.desired_configs;
+        tags.forEach(function (_tag) {
+          if (_tag.siteName && configTags[_tag.siteName] && !_tag.tagName) {
+            _tag.tagName = configTags[_tag.siteName].tag;
+          }
+        }, self);
+        self.loadConfigsByTags(tags,dfd);
+      });
+    } else {
+      self.loadConfigsByTags(tags,dfd);
+    }
+    return dfd.promise();
+  },
+
+  /**
+   *  loadConfigsByTags: Loads properties for a config tag
+   *  @params tags
+   *  @params dfd jqXhr promise
+   */
+  loadConfigsByTags: function (tags,dfd) {
+    var self = this;
+    var loadedConfigs = [];
+    App.config.loadConfigsByTags(tags).done(function (data) {
+      if (data.items) {
+        data.items.forEach(function (item) {
+          loadedConfigs.push(item);
+        });
+      }
+    }).complete(function () {
+      self.saveToDB(loadedConfigs);
+      dfd.resolve(loadedConfigs);
+    });
+  },
+
+  /**
+   * loadConfigTags: Loads all config tags applied to the cluster
+   * @return: jqXhr promise
+   */
+  loadConfigTags: function () {
+    return App.ajax.send({
+      name: 'config.tags',
+      sender: this
+    });
+  },
+
+  /**
+   * save properties obtained from server to local DB
+   * @param loadedConfigs
+   */
+  saveToDB: function (loadedConfigs) {
+    var storedConfigs = App.db.getConfigs();
+    loadedConfigs.forEach(function (loadedSite) {
+      var storedSite = storedConfigs.findProperty('type', loadedSite.type);
+      if (storedSite) {
+        storedSite.tag = loadedSite.tag;
+        storedSite.properties = loadedSite.properties;
+        storedSite.properties_attributes = loadedSite.properties_attributes;
+      } else {
+        storedConfigs.push(loadedSite);
+      }
+    });
+    App.db.setConfigs(storedConfigs);
+  }
+});
+
+});
+
+require.register("controllers/global/errors_handler_controller", function(exports, require, module) {
+/**
+ * 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');
+
+App.ErrorsHandlerController = Em.Controller.extend(App.UserPref, {
+  init: function () {
+    var oldError = window.onerror || Em.K;
+    var self = this;
+    window.onerror = function (err, url, lineNumber, colNumber, Err) {
+      oldError.call(this, err, url, lineNumber, colNumber, Err);
+      var ls = localStorage.getObject('errors') || {};
+      if(Object.keys(localStorage.getObject('errors')).length > 25) {
+        delete ls[Object.keys(ls).sort()[0]];
+      }
+      var key = new Date().getTime();
+      var val = {
+        file: url,
+        line: lineNumber,
+        col: colNumber,
+        error: err,
+        stackTrace: Em.get(Err || {}, 'stack')
+      };
+      ls[key] = val;
+      localStorage.setObject('errors', ls);
+      self.postUserPref(key, val);
+    };
+    return this._super();
+  }
+});
+
+});
+
+require.register("controllers/global/update_controller", function(exports, require, module) {
+/**
+ * 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');
+
+App.UpdateController = Em.Controller.extend({
+  name: 'updateController',
+  isUpdated: false,
+  cluster: null,
+  isWorking: false,
+  updateAlertInstances: Em.computed.and('isWorking', '!App.router.mainAlertInstancesController.isUpdating'),
+  timeIntervalId: null,
+  clusterName: Em.computed.alias('App.router.clusterController.clusterName'),
+
+  /**
+   * keys which should be preloaded in order to filter hosts by host-components
+   */
+  hostsPreLoadKeys: ['host_components/HostRoles/component_name', 'host_components/HostRoles/stale_configs', 'host_components/HostRoles/maintenance_state'],
+
+  paginationKeys: ['page_size', 'from'],
+
+  /**
+   * @type {Array}
+   */
+  serviceComponentMetrics: [
+    'host_components/metrics/jvm/memHeapUsedM',
+    'host_components/metrics/jvm/HeapMemoryMax',
+    'host_components/metrics/jvm/HeapMemoryUsed',
+    'host_components/metrics/jvm/memHeapCommittedM',
+    'host_components/metrics/mapred/jobtracker/trackers_decommissioned',
+    'host_components/metrics/cpu/cpu_wio',
+    'host_components/metrics/rpc/client/RpcQueueTime_avg_time',
+    'host_components/metrics/dfs/FSNamesystem/*',
+    'host_components/metrics/dfs/namenode/Version',
+    'host_components/metrics/dfs/namenode/LiveNodes',
+    'host_components/metrics/dfs/namenode/DeadNodes',
+    'host_components/metrics/dfs/namenode/DecomNodes',
+    'host_components/metrics/dfs/namenode/TotalFiles',
+    'host_components/metrics/dfs/namenode/UpgradeFinalized',
+    'host_components/metrics/dfs/namenode/Safemode',
+    'host_components/metrics/runtime/StartTime'
+  ],
+
+  /**
+   * @type {object}
+   */
+  serviceSpecificParams: {
+    'FLUME': "host_components/processes/HostComponentProcess",
+    'YARN':  "host_components/metrics/yarn/Queue," +
+             "host_components/metrics/yarn/ClusterMetrics/NumActiveNMs," +
+             "host_components/metrics/yarn/ClusterMetrics/NumLostNMs," +
+             "host_components/metrics/yarn/ClusterMetrics/NumUnhealthyNMs," +
+             "host_components/metrics/yarn/ClusterMetrics/NumRebootedNMs," +
+             "host_components/metrics/yarn/ClusterMetrics/NumDecommissionedNMs",
+    'HBASE': "host_components/metrics/hbase/master/IsActiveMaster," +
+             "host_components/metrics/hbase/master/MasterStartTime," +
+             "host_components/metrics/hbase/master/MasterActiveTime," +
+             "host_components/metrics/hbase/master/AverageLoad," +
+             "host_components/metrics/master/AssignmentManger/ritCount",
+    'STORM': 'metrics/api/v1/cluster/summary,metrics/api/v1/topology/summary,metrics/api/v1/nimbus/summary'
+  },
+
+  /**
+   * @type {string}
+   */
+  HOSTS_TEST_URL: '/data/hosts/HDP2/hosts.json',
+
+  /**
+   * map which track status of requests, whether it's running or completed
+   * @type {object}
+   */
+  requestsRunningStatus: {
+    "updateServiceMetric": false
+  },
+
+  getUrl: function (testUrl, url) {
+    return App.get('testMode') ? testUrl : App.apiPrefix + '/clusters/' + this.get('clusterName') + url;
+  },
+
+  /**
+   * construct URL from real URL and query parameters
+   * @param realUrl
+   * @param queryParams
+   * @return {String}
+   */
+  getComplexUrl: function (realUrl, queryParams) {
+    var prefix = App.get('apiPrefix') + '/clusters/' + App.get('clusterName'),
+      params = '';
+
+    if (queryParams) {
+      params = this.computeParameters(queryParams);
+    }
+    params = params.length > 0 ? params + "&" : params;
+    return prefix + realUrl.replace('<parameters>', params);
+  },
+
+  /**
+   * compute parameters according to their type
+   * @param queryParams
+   * @return {String}
+   */
+  computeParameters: function (queryParams) {
+    var params = '';
+
+    queryParams.forEach(function (param) {
+      var customKey = param.key;
+
+      switch (param.type) {
+        case 'EQUAL':
+          if (Em.isArray(param.value)) {
+            params += param.key + '.in(' + param.value.join(',') + ')';
+          } else {
+            params += param.key + '=' + param.value;
+          }
+          break;
+        case 'LESS':
+          params += param.key + '<' + param.value;
+          break;
+        case 'MORE':
+          params += param.key + '>' + param.value;
+          break;
+        case 'MATCH':
+          if (Em.isArray(param.value)) {
+            params += '(' + param.value.map(function(v) {
+              return param.key + '.matches(' + v + ')';
+            }).join('|') + ')';
+          } else {
+            params += param.key + '.matches(' + param.value + ')';
+          }
+          break;
+        case 'MULTIPLE':
+          params += param.key + '.in(' + param.value.join(',') + ')';
+          break;
+        case 'SORT':
+          params += 'sortBy=' + param.key + '.' + param.value;
+          break;
+        case 'CUSTOM':
+          param.value.forEach(function (item, index) {
+            customKey = customKey.replace('{' + index + '}', item);
+          }, this);
+          params += customKey;
+          break;
+        case 'COMBO':
+          params += App.router.get('mainHostComboSearchBoxController').generateQueryParam(param);
+          break;
+      }
+      params += '&';
+    });
+    return params.substring(0, params.length - 1);
+  },
+
+  /**
+   * depict query parameters of table
+   */
+  queryParams: Em.Object.create({
+    'Hosts': []
+  }),
+
+  /**
+   * Pagination query-parameters for unhealthy alerts request
+   * @type {{from: Number, page_size: Number}}
+   */
+  queryParamsForUnhealthyAlertInstances: {
+    from: 0,
+    page_size: 10
+  },
+
+  /**
+   * map describes relations between updater function and table
+   */
+  tableUpdaterMap: {
+    'Hosts': 'updateHost'
+  },
+
+  /**
+   * Start polling, when <code>isWorking</code> become true
+   */
+  updateAll: function () {
+    if (this.get('isWorking') && !App.get('isOnlyViewUser')) {
+      App.updater.run(this, 'updateServices', 'isWorking');
+      App.updater.run(this, 'updateHost', 'isWorking');
+      App.updater.run(this, 'updateServiceMetric', 'isWorking', App.componentsUpdateInterval, '\/main\/(dashboard|services).*');
+      App.updater.run(this, 'updateComponentsState', 'isWorking', App.componentsUpdateInterval, '\/main\/(dashboard|services|hosts).*');
+      App.updater.run(this, 'graphsUpdate', 'isWorking');
+      App.updater.run(this, 'updateComponentConfig', 'isWorking');
+
+      App.updater.run(this, 'updateAlertGroups', 'isWorking', App.alertGroupsUpdateInterval, '\/main\/alerts.*');
+      App.updater.run(this, 'updateAlertDefinitions', 'isWorking', App.alertDefinitionsUpdateInterval, '\/main\/alerts.*');
+      App.updater.run(this, 'updateAlertDefinitionSummary', 'isWorking', App.alertDefinitionsUpdateInterval);
+      if (!App.get('router.mainAlertInstancesController.isUpdating')) {
+        App.updater.run(this, 'updateUnhealthyAlertInstances', 'updateAlertInstances', App.alertInstancesUpdateInterval, '\/main\/alerts.*');
+      }
+      App.updater.run(this, 'updateClusterEnv', 'isWorking', App.clusterEnvUpdateInterval);
+      App.updater.run(this, 'updateUpgradeState', 'isWorking', App.bgOperationsUpdateInterval);
+      App.updater.run(this, 'updateWizardWatcher', 'isWorking', App.bgOperationsUpdateInterval);
+    }
+  }.observes('isWorking', 'App.router.mainAlertInstancesController.isUpdating'),
+
+  /**
+   *
+   * @param {Function} callback
+   * @param {Function} error
+   * @param {boolean} lazyLoadMetrics
+   */
+  updateHost: function (callback, error, lazyLoadMetrics) {
+    var testUrl = this.get('HOSTS_TEST_URL'),
+        self = this,
+        hostDetailsFilter = '',
+        realUrl = '/hosts?fields=Hosts/rack_info,Hosts/host_name,Hosts/maintenance_state,Hosts/public_host_name,Hosts/cpu_count,Hosts/ph_cpu_count,' +
+            'alerts_summary,Hosts/host_status,Hosts/last_heartbeat_time,Hosts/ip,host_components/HostRoles/state,host_components/HostRoles/maintenance_state,' +
+            'host_components/HostRoles/stale_configs,host_components/HostRoles/service_name,host_components/HostRoles/display_name,host_components/HostRoles/desired_admin_state,' +
+            '<metrics>Hosts/total_mem<hostDetailsParams><stackVersions>&minimal_response=true',
+        hostDetailsParams = ',Hosts/os_arch,Hosts/os_type,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free',
+        stackVersionInfo = ',stack_versions/HostStackVersions,' +
+            'stack_versions/repository_versions/RepositoryVersions/repository_version,stack_versions/repository_versions/RepositoryVersions/id,' +
+            'stack_versions/repository_versions/RepositoryVersions/display_name',
+        mainHostController = App.router.get('mainHostController'),
+        sortProperties = mainHostController.getSortProps(),
+        loggingResource = ',host_components/logging',
+        isHostsLoaded = false;
+    this.get('queryParams').set('Hosts', mainHostController.getQueryParameters(true));
+    if (App.router.get('currentState.parentState.name') === 'hosts') {
+      App.updater.updateInterval('updateHost', App.get('contentUpdateInterval'));
+      hostDetailsParams = '';
+    }
+    else {
+      if (App.router.get('currentState.parentState.name') === 'hostDetails') {
+        hostDetailsFilter = App.router.get('location.lastSetURL').match(/\/hosts\/(.*)\/(summary|configs|alerts|stackVersions|logs)/)[1];
+        App.updater.updateInterval('updateHost', App.get('componentsUpdateInterval'));
+        //if host details page opened then request info only of one displayed host
+        this.get('queryParams').set('Hosts', [
+          {
+            key: 'Hosts/host_name',
+            value: [hostDetailsFilter],
+            type: 'MULTIPLE'
+          }
+        ]);
+      }
+      else {
+        // clusterController.isHostsLoaded may be changed in callback, that is why it's value is cached before calling callback
+        isHostsLoaded = App.router.get('clusterController.isHostsLoaded');
+        callback();
+        // On pages except for hosts/hostDetails, making sure hostsMapper loaded only once on page load, no need to update, but at least once
+        if (isHostsLoaded) {
+          return;
+        }
+      }
+    }
+
+    realUrl = realUrl.replace("<stackVersions>", stackVersionInfo);
+    realUrl = realUrl.replace("<metrics>", lazyLoadMetrics ? "" : "metrics/disk,metrics/load/load_one,");
+    realUrl = realUrl.replace('<hostDetailsParams>', hostDetailsParams);
+    if (App.get('supports.logSearch')) {
+      realUrl += loggingResource;
+    }
+
+    var clientCallback = function (skipCall, queryParams) {
+      var completeCallback = function () {
+        callback();
+        if (lazyLoadMetrics) {
+          self.loadHostsMetric(queryParams);
+        }
+      };
+      if (skipCall) {
+        //no hosts match filter by component
+        App.hostsMapper.map({
+          items: [],
+          itemTotal: '0'
+        });
+        callback();
+      }
+      else {
+        if (App.get('testMode')) {
+          realUrl = testUrl;
+        } else {
+          realUrl = self.addParamsToHostsUrl(queryParams, sortProperties, realUrl);
+        }
+
+        App.HttpClient.get(realUrl, App.hostsMapper, {
+          complete: completeCallback,
+          doGetAsPost: true,
+          params: self.computeParameters(queryParams),
+          error: error
+        });
+      }
+    };
+
+    if (!this.preLoadHosts(clientCallback)) {
+      clientCallback(false, self.get('queryParams.Hosts'));
+    }
+  },
+
+  /**
+   *
+   * @param {Array} queryParams
+   * @param {Array} sortProperties
+   * @param {string} realUrl
+   * @returns {string}
+   */
+  addParamsToHostsUrl: function (queryParams, sortProperties, realUrl) {
+    var paginationProps = this.computeParameters(queryParams.filter(function (param) {
+      return this.get('paginationKeys').contains(param.key);
+    }, this));
+    var sortProps = this.computeParameters(sortProperties);
+
+    return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + realUrl +
+      (paginationProps.length > 0 ? '&' + paginationProps : '') +
+      (sortProps.length > 0 ? '&' + sortProps : '');
+  },
+
+  /**
+   * lazy load metrics of hosts
+   * @param {Array} queryParams
+   * @returns {$.ajax|null}
+   */
+  loadHostsMetric: function (queryParams) {
+    var realUrl = '/hosts?fields=metrics/disk/disk_free,metrics/disk/disk_total,metrics/load/load_one&minim

<TRUNCATED>