You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2016/12/01 08:14:23 UTC
[40/50] ambari git commit: AMBARI-12697 Rolling upgrade: Ambari UI
should be able to display rolling upgrade history (dili via atkach)
AMBARI-12697 Rolling upgrade: Ambari UI should be able to display rolling upgrade history (dili via atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ef418377
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ef418377
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ef418377
Branch: refs/heads/branch-feature-AMBARI-18901
Commit: ef41837712fee03772aca344b2edc337396974a0
Parents: 502cffb
Author: Andrii Tkach <at...@apache.org>
Authored: Wed Nov 30 20:32:16 2016 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Wed Nov 30 20:32:16 2016 +0200
----------------------------------------------------------------------
ambari-web/app/assets/test/tests.js | 5 +
ambari-web/app/controllers.js | 1 +
.../admin/stack_upgrade_history_controller.js | 217 +++++++++++
ambari-web/app/mappers.js | 3 +-
.../app/mappers/stack_upgrade_history_mapper.js | 54 +++
ambari-web/app/messages.js | 28 ++
ambari-web/app/models.js | 2 +
.../app/models/finished_upgrade_entity.js | 92 +++++
.../stack_version/stack_upgrade_history.js | 37 ++
ambari-web/app/routes/main.js | 7 +
ambari-web/app/styles/stack_versions.less | 69 ++++
.../admin/stack_upgrade/upgrade_history.hbs | 105 ++++++
.../stack_upgrade/upgrade_history_details.hbs | 46 +++
ambari-web/app/views.js | 2 +
.../views/main/admin/stack_upgrade/menu_view.js | 6 +
.../upgrade_history_details_view.js | 85 +++++
.../admin/stack_upgrade/upgrade_history_view.js | 303 +++++++++++++++
.../stack_upgrade_history_controller_test.js | 125 +++++++
.../stack_upgrade_history_mapper_test.js | 372 +++++++++++++++++++
.../test/models/finished_upgrade_entity_test.js | 197 ++++++++++
.../upgrade_history_details_view_test.js | 248 +++++++++++++
.../stack_upgrade/upgrade_history_view_test.js | 173 +++++++++
22 files changed, 2176 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 8571fc4..7440819 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -70,6 +70,7 @@ var files = [
'test/controllers/main/admin/kerberos/step8_controller_test',
'test/controllers/main/admin/stack_and_upgrade_controller_test',
+ 'test/controllers/main/admin/stack_upgrade_history_controller_test',
'test/controllers/main/admin/serviceAccounts_controller_test',
'test/controllers/main/admin/highAvailability_controller_test',
'test/controllers/main/admin/highAvailability/progress_controller_test',
@@ -145,6 +146,7 @@ var files = [
'test/mappers/users_mapper_test',
'test/mappers/stack_mapper_test',
'test/mappers/stack_service_mapper_test',
+ 'test/mappers/stack_upgrade_history_mapper_test',
'test/mappers/repository_version_mapper_test',
'test/mappers/configs/config_groups_mapper_test',
'test/mappers/configs/service_config_version_mapper_test',
@@ -251,6 +253,8 @@ var files = [
'test/views/main/admin/stack_upgrade/upgrade_group_view_test',
'test/views/main/admin/stack_upgrade/upgrade_task_view_test',
'test/views/main/admin/stack_upgrade/upgrade_wizard_view_test',
+ 'test/views/main/admin/stack_upgrade/upgrade_history_view_test',
+ 'test/views/main/admin/stack_upgrade/upgrade_history_details_view_test',
'test/views/main/admin/stack_upgrade/version_view_test',
'test/views/main/admin/stack_upgrade/services_view_test',
'test/views/main/admin/stack_upgrade/menu_view_test',
@@ -384,6 +388,7 @@ var files = [
'test/models/widget_property_test',
'test/models/host_stack_version_test',
'test/models/upgrade_entity_test',
+ 'test/models/finished_upgrade_entity_test',
'test/models/configs/sub_section_test',
'test/models/configs/section_test',
'test/models/configs/service_config_version_test',
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index 5664029..81e5eb7 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -85,6 +85,7 @@ require('controllers/main/admin/highAvailability/journalNode/step6_controller');
require('controllers/main/admin/highAvailability/journalNode/step7_controller');
require('controllers/main/admin/highAvailability/journalNode/step8_controller');
require('controllers/main/admin/stack_and_upgrade_controller');
+require('controllers/main/admin/stack_upgrade_history_controller');
require('controllers/main/admin/serviceAccounts_controller');
require('utils/polling');
require('controllers/main/admin/kerberos');
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js b/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js
new file mode 100644
index 0000000..9bec825
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/stack_upgrade_history_controller.js
@@ -0,0 +1,217 @@
+/**
+ * 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');
+
+App.MainAdminStackUpgradeHistoryController = Em.ArrayController.extend({
+ name: 'mainAdminStackUpgradeHistoryController',
+
+ startIndex: 1,
+
+ resetStartIndex: false,
+
+ /**
+ * status of tasks/items/groups which should be grayed out and disabled
+ * @type {Array}
+ */
+ nonActiveStates: ['PENDING'],
+
+ /**
+ * mutable properties of Upgrade Task
+ * @type {Array}
+ */
+ taskDetailsProperties: ['status', 'stdout', 'stderr', 'error_log', 'host_name', 'output_log'],
+
+ /**
+ * Current upgrade record clicked on the UI
+ * @type {App.StackUpgradeHistory|null}
+ * */
+ currentUpgradeRecord: null,
+
+ isDowngrade: false,
+
+ upgradeData: null,
+
+ /**
+ * List of all <code>App.StackUpgradeHistory</code>. Latest one at the beginning
+ * @type {App.StackUpgradeHistory[]}
+ */
+ content: App.StackUpgradeHistory.find(),
+
+ upgradeHistoryUrl: function() {
+ return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/upgrades?fields=Upgrade';
+ }.property('App.clusterName'),
+
+ upgradeUpgradeRecordUrl: function() {
+ var record = this.get('currentUpgradeRecord');
+ return App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + '/upgrades/' + record.get('requestId');
+ }.property('App.clusterName', 'currentUpgradeRecord'),
+
+ loadStackUpgradeHistoryToModel: function () {
+ console.log('Load stack upgrade history');
+ var dfd = $.Deferred();
+ App.HttpClient.get(this.get('upgradeHistoryUrl'), App.stackUpgradeHistoryMapper, {
+ complete: function () {
+ dfd.resolve();
+ }
+ });
+ return dfd.promise();
+ },
+
+ loadStackUpgradeRecord: function () {
+ var record = this.get('currentUpgradeRecord');
+ this.set('isDowngrade', ('DOWNGRADE' == record.get('direction')))
+ var dfd = $.Deferred();
+ var self = this;
+ if (record != null) {
+ App.ajax.send({
+ name: 'admin.upgrade.data',
+ sender: this,
+ data: {
+ id: record.get('requestId')
+ },
+ success: 'loadUpgradeRecordSuccessCallback'
+ }).then(dfd.resolve).complete(function () {
+ });
+ } else {
+ dfd.resolve();
+ }
+ return dfd.promise();
+ },
+
+ loadUpgradeRecordSuccessCallback: function(newData){
+ if (Em.isNone(newData)) {
+ var record = this.get('currentUpgradeRecord');
+ console.debug('No data returned for upgrad record ' + record.get('requestId'))
+ return;
+ }
+ var upgradeGroups = [];
+ if (newData.upgrade_groups) {
+ nonActiveStates = this.get('nonActiveStates'),
+ //wrap all entities into App.finishedUpgradeEntity
+ newData.upgrade_groups.forEach(function (newGroup) {
+ var hasExpandableItems = newGroup.upgrade_items.some(function (item) {
+ return !nonActiveStates.contains(item.UpgradeItem.status);
+ }),
+ oldGroup = App.finishedUpgradeEntity.create({type: 'GROUP', hasExpandableItems: hasExpandableItems}, newGroup.UpgradeGroup),
+ upgradeItems = [];
+ newGroup.upgrade_items.forEach(function (item) {
+ var oldItem = App.finishedUpgradeEntity.create({type: 'ITEM'}, item.UpgradeItem);
+ this.formatMessages(oldItem);
+ oldItem.set('tasks', []);
+ upgradeItems.pushObject(oldItem);
+ }, this);
+ upgradeItems.reverse();
+ oldGroup.set('upgradeItems', upgradeItems);
+ upgradeGroups.pushObject(oldGroup);
+ }, this);
+ upgradeGroups.reverse();
+ this.set('upgradeData', Em.Object.create({
+ upgradeGroups: upgradeGroups,
+ upgrade_groups: newData.upgrade_groups,
+ Upgrade: newData.Upgrade
+ }));
+ }
+ },
+
+ /**
+ * format upgrade item text
+ * @param {App.finishedUpgradeEntity} oldItem
+ */
+ formatMessages: function (oldItem) {
+ var text = oldItem.get('text');
+ var messages = [];
+
+ try {
+ var messageArray = JSON.parse(text);
+ for (var i = 0; i < messageArray.length; i++) {
+ messages.push(messageArray[i].message);
+ }
+ oldItem.set('text', messages.join(' '));
+ } catch (err) {
+ console.warn('Upgrade Item has malformed text');
+ }
+ oldItem.set('messages', messages);
+ },
+
+ /**
+ * request Upgrade Item and its tasks from server
+ * @param {Em.Object} item
+ * @param {Function} customCallback
+ * @return {$.ajax}
+ */
+ getUpgradeItem: function (item) {
+ return App.ajax.send({
+ name: 'admin.upgrade.upgrade_item',
+ sender: this,
+ data: {
+ upgradeId: item.get('request_id'),
+ groupId: item.get('group_id'),
+ stageId: item.get('stage_id')
+ },
+ success: 'getUpgradeItemSuccessCallback'
+ });
+ },
+
+ /**
+ * success callback of <code>getTasks</code>
+ * @param {object} data
+ */
+ getUpgradeItemSuccessCallback: function (data) {
+ this.get('upgradeData.upgradeGroups').forEach(function (group) {
+ if (group.get('group_id') === data.UpgradeItem.group_id) {
+ group.get('upgradeItems').forEach(function (item) {
+ if (item.get('stage_id') === data.UpgradeItem.stage_id) {
+ if (item.get('tasks.length')) {
+ data.tasks.forEach(function (task) {
+ var currentTask = item.get('tasks').findProperty('id', task.Tasks.id);
+ this.get('taskDetailsProperties').forEach(function (property) {
+ currentTask.set(property, task.Tasks[property]);
+ }, this);
+ }, this);
+ } else {
+ var tasks = [];
+ data.tasks.forEach(function (task) {
+ tasks.pushObject(App.finishedUpgradeEntity.create({type: 'TASK'}, task.Tasks));
+ });
+ item.set('tasks', tasks);
+ }
+ item.set('isTasksLoaded', true);
+ }
+ }, this);
+ }
+ }, this);
+ },
+
+ /**
+ * status of Upgrade request
+ * @type {string}
+ */
+ requestStatus: function () {
+ if (this.get('upgradeData')){
+ if (this.get('upgradeData.Upgrade')) {
+ return this.get('upgradeData.Upgrade.request_status');
+ } else {
+ return '';
+ }
+ } else {
+ return ''
+ }
+ }.property('upgradeData.Upgrade.request_status'),
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
index 96193bc..cde9bcc 100644
--- a/ambari-web/app/mappers.js
+++ b/ambari-web/app/mappers.js
@@ -43,4 +43,5 @@ require('mappers/alert_groups_mapper');
require('mappers/alert_notification_mapper');
require('mappers/root_service_mapper');
require('mappers/widget_mapper');
-require('mappers/widget_layout_mapper');
\ No newline at end of file
+require('mappers/widget_layout_mapper');
+require('mappers/stack_upgrade_history_mapper');
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/mappers/stack_upgrade_history_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/stack_upgrade_history_mapper.js b/ambari-web/app/mappers/stack_upgrade_history_mapper.js
new file mode 100644
index 0000000..63088a7
--- /dev/null
+++ b/ambari-web/app/mappers/stack_upgrade_history_mapper.js
@@ -0,0 +1,54 @@
+/**
+ * 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');
+
+App.stackUpgradeHistoryMapper = App.QuickDataMapper.create({
+ model: App.StackUpgradeHistory,
+
+ config: {
+ "id": "Upgrade.request_id",
+ "request_id": "Upgrade.request_id",
+ "cluster_name": "Upgrade.cluster_name",
+ "direction": "Upgrade.direction",
+ "from_version": "Upgrade.from_version",
+ "to_version": "Upgrade.to_version",
+ "end_time":"Upgrade.end_time",
+ "start_time":"Upgrade.start_time",
+ "create_time": "Upgrade.create_time",
+ "request_status": "Upgrade.request_status",
+ "upgrade_type": "Upgrade.upgrade_type",
+ "downgrade_allowed": "Upgrade.downgrade_allowed",
+ "skip_failures": "Upgrade.skip_failures",
+ "skip_service_check_failures": "Upgrade.skip_service_check_failures"
+ },
+
+ map: function (json) {
+ App.set('isStackUpgradeHistoryLoaded',false);
+ var model = this.get('model');
+ var result = [];
+ json.items.forEach(function(item) {
+ var parseResult = this.parseIt(item, this.get('config'));
+ result.push(parseResult);
+ }, this);
+
+ App.store.loadMany(this.get('model'), result);
+ App.store.commit();
+ App.set('isStackUpgradeHistoryLoaded',true);
+ },
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 7c3ccd3..5c7e0e8 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -130,6 +130,7 @@ Em.I18n.translations = {
'common.open':'Open',
'common.copy':'Copy',
'common.complete':'Complete',
+ 'common.completed':'Completed',
'common.metrics':'Metrics',
'common.timeRange':'Time Range',
'common.name':'Name',
@@ -172,6 +173,7 @@ Em.I18n.translations = {
'common.recommission':'Recommission',
'common.failure': 'Failure',
'common.type': 'Type',
+ 'common.direction': 'Direction',
'common.close': 'Close',
'common.warning': 'Warning',
'common.critical': 'Critical',
@@ -192,6 +194,7 @@ Em.I18n.translations = {
'common.repositories':'Repositories',
'common.stack.versions':'Stack Versions',
'common.versions':'Versions',
+ 'common.upgrade.history':'Upgrade History',
'common.serviceAccounts': 'Service Accounts',
'common.add': 'Add',
'common.edit': 'Edit',
@@ -203,6 +206,7 @@ Em.I18n.translations = {
'common.details':'Details',
'common.stats':'Stats',
'common.abort': 'Abort',
+ 'common.aborted': 'Aborted',
'common.misc': 'Misc',
'common.userSettings': 'User Settings',
'common.aboutAmbari': 'About',
@@ -334,6 +338,14 @@ Em.I18n.translations = {
'common.logs': 'Logs',
'common.warn.message': '<div class="alert alert-warn">{0}</div>',
'common.link': 'Link',
+ 'common.from.version': 'From Version',
+ 'common.to.version': 'To Version',
+ 'common.start.time': 'Start Time',
+ 'common.end.time': 'End Time',
+ 'common.rolling': 'Rolling',
+ 'common.express': 'Express',
+ 'common.rolling.downgrade': 'Rolling Downgrade',
+ 'common.express.downgrade': 'Express Downgrade',
'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on {1}",
'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -1728,6 +1740,22 @@ Em.I18n.translations = {
'admin.stackVersions.hosts.popup.primary': "Go to Hosts",
'admin.stackVersions.details.install.hosts.popup.title': "Install {0} version",
+ 'admin.stackVersions.upgradeHistory.upgrade': 'Upgrades',
+ 'admin.stackVersions.upgradeHistory.downgrade': 'Downgrades',
+ 'admin.stackVersions.upgradeHistory.show.details': 'Click to show more details on {0}',
+ 'admin.stackVersions.upgradeHistory.success': 'Sucessful {0}',
+ 'admin.stackVersions.upgradeHistory.aborted': 'Aborted {0}',
+ 'admin.stackVersions.upgradeHistory.summary': 'Summary',
+ 'admin.stackVersions.upgradeHistory.history': 'History',
+ 'admin.stackVersions.upgradeHistory.filter.all': 'All ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.upgrade': 'Upgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.downgrade': 'Downgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.successful.upgrade': 'Successful Upgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.successful.downgrade': 'Successful Downgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade': 'Aborted Upgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade': 'Aborted Downgrade ({0})',
+ 'admin.stackVersions.upgradeHistory.no.history': 'No upgrade/downgrade history available',
+ 'admin.stackVersions.upgradeHistory.record.title': '{0} {1} to {2}',
'admin.stackUpgrade.preCheck.warning.message': "{0} Warning {1}",
'admin.stackUpgrade.preCheck.bypass.message': "{0} Error {1}",
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index b877255..e0168a2 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -30,6 +30,7 @@ require('models/stack_version/repository_version');
require('models/stack_version/os');
require('models/stack_version/service_simple');
require('models/stack_version/repository');
+require('models/stack_version/stack_upgrade_history');
require('models/operating_system');
require('models/repository');
require('models/stack_service');
@@ -64,6 +65,7 @@ require('models/master_component');
require('models/host_stack_version');
require('models/root_service');
require('models/upgrade_entity');
+require('models/finished_upgrade_entity');
require('models/configs/theme/theme_condition');
require('models/configs/service_config_version');
require('models/configs/stack_config_property');
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models/finished_upgrade_entity.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/finished_upgrade_entity.js b/ambari-web/app/models/finished_upgrade_entity.js
new file mode 100644
index 0000000..c08ef45
--- /dev/null
+++ b/ambari-web/app/models/finished_upgrade_entity.js
@@ -0,0 +1,92 @@
+/**
+ * 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.
+ */
+
+
+/**
+ * @type {Ember.Object}
+ * @class
+ */
+App.finishedUpgradeEntity = Em.Object.extend({
+
+ /**
+ * type of entity "GROUP", "ITEM", "TASK"
+ * @type {string}
+ */
+ type: null,
+
+ /**
+ * @type {boolean}
+ */
+ isExpanded: false,
+
+ /**
+ * @type {boolean}
+ */
+ hasExpandableItems: false,
+
+ /**
+ * @type {boolean}
+ */
+ isVisible: Em.computed.notEqual('status', 'PENDING'),
+
+ /**
+ * status of tasks/items/groups which should be grayed out and disabled
+ * @type {Array}
+ */
+ nonActiveStates: ['PENDING'],
+
+ /**
+ * @type {boolean}
+ */
+ isRunning: Em.computed.existsIn('status', ['IN_PROGRESS']),
+
+ /**
+ * @type {number}
+ */
+ progress: function () {
+ return Math.floor(this.get('progress_percent'));
+ }.property('progress_percent'),
+
+ /**
+ * indicate whether entity has active link
+ * @type {boolean}
+ */
+ isActive: function () {
+ return !this.get('nonActiveStates').contains(this.get('status'));
+ }.property('status'),
+
+ /**
+ * indicate whether upgrade group should be expanded
+ * @type {boolean}
+ */
+ isExpandableGroup: function () {
+ return this.get('type') === 'GROUP' && (this.get('isActive') || this.get('hasExpandableItems'));
+ }.property('isActive', 'hasExpandableItems'),
+
+ upgradeItemStatus: Em.computed.firstNotBlank('display_status', 'status'),
+
+ /**
+ * @type {string}
+ */
+ upgradeGroupStatus: function () {
+ if (this.get('type') === 'GROUP' && !this.get('isActive') && this.get('hasExpandableItems')) {
+ return 'SUBITEM_FAILED';
+ }
+ return this.get('display_status') || this.get('status');
+ }.property('isExpandableGroup', 'display_status', 'status')
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/models/stack_version/stack_upgrade_history.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_version/stack_upgrade_history.js b/ambari-web/app/models/stack_version/stack_upgrade_history.js
new file mode 100644
index 0000000..d4a89dc
--- /dev/null
+++ b/ambari-web/app/models/stack_version/stack_upgrade_history.js
@@ -0,0 +1,37 @@
+/**
+ * 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.StackUpgradeHistory = DS.Model.extend({
+ requestId: DS.attr('number'),
+ clusterName: DS.attr('string'),
+ direction: DS.attr('string'),
+ fromVersion: DS.attr('string'),
+ toVersion: DS.attr('string'),
+ requestStatus: DS.attr('string'),
+ upgradeType: DS.attr('string'),
+ downgradeAllowed: DS.attr('boolean'),
+ skipFailures: DS.attr('boolean'),
+ skipServiceCheckFailures: DS.attr('boolean'),
+ endTime: DS.attr('number'),
+ startTime: DS.attr('number'),
+ createTime: DS.attr('number'),
+});
+
+App.StackUpgradeHistory.FIXTURES = [];
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index f0fe5d7..7e7b622 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -519,6 +519,13 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
}
}),
+ upgradeHistory: Em.Route.extend({
+ route: '/history',
+ connectOutlets: function (router, context) {
+ router.get('mainAdminStackAndUpgradeController').connectOutlet('mainAdminStackUpgradeHistory');
+ },
+ }),
+
stackNavigate: function (router, event) {
var parent = event.view._parentView;
parent.deactivateChildViews();
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/styles/stack_versions.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less
index 921b418..715bbe3 100644
--- a/ambari-web/app/styles/stack_versions.less
+++ b/ambari-web/app/styles/stack_versions.less
@@ -420,6 +420,75 @@
}
}
+#stack-upgrade-record-dialog {
+ .details-box {
+ padding: 5px;
+ margin-left: 15px;
+ margin-right: 95px;
+ .button-row {
+ text-align: right;
+ padding: 5px;
+ }
+ input[type="checkbox"] {
+ margin: 0;
+ }
+ .message {
+ line-height: 30px;
+ }
+ }
+ .task-details {
+ .manage-controls a {
+ cursor: pointer;
+ margin-right: 12px;
+ }
+ textarea {
+ width: 100%;
+ min-height: 100px;
+ box-sizing: border-box;
+ }
+ }
+ .task-list {
+ overflow-x: hidden;
+ .progress {
+ margin-bottom: 0;
+ }
+ padding-left: 20px;
+ i {
+ margin-right: 5px;
+ }
+ }
+ .task-list-main-warp i {
+ font-size: 16px;
+ }
+ ul.failed-info-list {
+ max-height: 500px;
+ margin-top: 5px;
+ }
+ .upgrade-options-link {
+ position: absolute;
+ cursor: pointer;
+ right: 10%;
+ top: 13px;
+ width: 100px;
+ a {
+ font-size: 13px;
+ }
+ .icon-cogs {
+ color: #0088cc;
+ margin-right: 3px;
+ }
+ }
+ .upgrade-options-link.disabled {
+ cursor: not-allowed;
+ a, .icon-cogs {
+ color: #808080;
+ }
+ a:hover {
+ text-decoration: none;
+ }
+ }
+}
+
.repository-list {
.os-block {
border-top: 1px solid #dddddd;
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs
new file mode 100644
index 0000000..6d4a32d
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history.hbs
@@ -0,0 +1,105 @@
+{{!
+* 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.
+}}
+
+<div id="upgrade-history-section">
+ <div {{bindAttr class="view.isReady:hide:show :screensaver :no-borders "}}>
+ {{view App.SpinnerView}}
+ </div>
+ <div {{bindAttr class="view.isReady::hidden"}}>
+ <div class="btn-group display-inline-block">
+ <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
+ <span class="filters-label">{{t common.filter}}: </span>
+ <span>
+ {{view.selectedCategory.label}}
+ <span class="caret"></span>
+ </span>
+ </a>
+ <ul class="dropdown-menu">
+ {{#each category in view.categories}}
+ <li>
+ <a {{action selectCategory category target="view"}} href="#">
+ {{category.label}}
+ </a>
+ </li>
+ {{/each}}
+ </ul>
+ </div>
+ <br/>
+ <br/>
+ <table class="table advanced-header-table table-striped" id="upgrade-summary-table">
+ <thead>
+ <th>{{t common.direction}}</th>
+ <th>{{t common.type}}</th>
+ <th>{{t common.from.version}}</th>
+ <th>{{t common.to.version}}</th>
+ <th>{{t common.start.time}}</th>
+ <th>{{t common.duration}}</th>
+ <th>{{t common.end.time}}</th>
+ <th>{{t common.status}}</th>
+ </thead>
+ <tbody>
+ {{#if view.pageContent}}
+ {{#each item in view.pageContent}}
+ <tr>
+ <td class='name'>
+ <span class="trim_hostname">
+ <a href="#" class="black" {{action "showUpgradeHistoryRecord" item target="view"}}>
+ {{unbound item.directionLabel}}
+ </a>
+ </span>
+ </td>
+ <td>
+ <span>{{item.upgradeTypeLabel}}</span>
+ </td>
+ <td>
+ <span>{{item.fromVersion}}</span>
+ </td>
+ <td>
+ <span>{{item.toVersion}}</span>
+ </td>
+ <td>
+ <span>{{item.startTimeLabel}}</span>
+ </td>
+ <td>
+ <span>{{item.duration}}</span>
+ </td>
+ <td>
+ <span>{{item.endTimeLabel}}</span>
+ </td>
+ <td>
+ <span>{{item.requestStatus}}</span>
+ </td>
+ </tr>
+ {{/each}}
+ {{/if}}
+ </tbody>
+ </table>
+ <div class="page-bar">
+ <div class="items-on-page">
+ <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+ </div>
+ <div class="info">{{view.paginationInfo}}</div>
+ <div class="paging_two_button">
+ <a {{bindAttr class="view.paginationLeftClass"}}{{action previousPage target="view"}}><i
+ class="icon-arrow-left"></i></a>
+ <a {{bindAttr class="view.paginationRightClass"}}{{action nextPage target="view"}}><i
+ class="icon-arrow-right"></i></a>
+ </div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs
new file mode 100644
index 0000000..2d431f9
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_history_details.hbs
@@ -0,0 +1,46 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+<div id="stack-upgrade-record-dialog">
+ <div {{bindAttr class="view.isLoaded::hidden :row-fluid"}}>
+ <div class="span3 task-list-main-warp">{{statusIcon controller.requestStatus}}
+ {{view.upgradeStatusLabel}}</div>
+ <div class="span8">
+ {{view App.ProgressBarView
+ progressBinding="view.overallProgress"
+ statusBinding="controller.requestStatus"
+ }}
+ </div>
+ <div class="span1">
+ {{view.overallProgress}}%
+ </div>
+ </div>
+
+ <div class="task-list scrollable-block task-list-main-warp">
+ {{#if view.isReady}}
+ {{#each group in controller.upgradeData.upgradeGroups}}
+ {{#if group.isVisible}}
+ {{view App.upgradeGroupView contentBinding="group"}}
+ {{/if}}
+ {{/each}}
+ {{/if}}
+ </div>
+ {{#unless view.isReady}}
+ {{view App.SpinnerView}}
+ {{/unless}}
+</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 0d9dc3f..0dac227 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -213,6 +213,8 @@ require('views/main/admin/stack_upgrade/upgrade_version_box_view');
require('views/main/admin/stack_upgrade/upgrade_version_column_view');
require('views/main/admin/stack_upgrade/upgrade_group_view');
require('views/main/admin/stack_upgrade/upgrade_task_view');
+require('views/main/admin/stack_upgrade/upgrade_history_view');
+require('views/main/admin/stack_upgrade/upgrade_history_details_view');
require('views/main/admin/stack_upgrade/services_view');
require('views/main/admin/stack_upgrade/versions_view');
require('views/main/admin/stack_upgrade/menu_view');
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
index 1e84f1c..db5f946 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/menu_view.js
@@ -35,6 +35,12 @@ App.MainAdminStackMenuView = Em.CollectionView.extend({
label: Em.I18n.t('common.versions'),
routing: 'versions',
hidden: !App.get('stackVersionsAvailable')
+ }),
+ Em.Object.create({
+ name: 'upgradeHistory',
+ label: Em.I18n.t('common.upgrade.history'),
+ routing: 'upgradeHistory',
+ hidden: !App.get('stackVersionsAvailable')
})
]
}.property('App.stackVersionsAvailable'),
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js
new file mode 100644
index 0000000..983c26a
--- /dev/null
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_details_view.js
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+var date = require('utils/date/date');
+
+App.MainAdminStackUpgradeHistoryDetailsView = Em.View.extend({
+ controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController',
+ templateName: require('templates/main/admin/stack_upgrade/upgrade_history_details'),
+ isReady: false,
+
+ willInsertElement: function(){
+ var self = this;
+ this.get('controller').loadStackUpgradeRecord().done(function(){
+ self.populateUpgradeHistoryRecord();
+ });
+ },
+
+ willDestroyElement: function () {
+ this.set('isReady', false);
+ },
+
+ populateUpgradeHistoryRecord: function(){
+ var upgradeData = this.get('controller').get('upgradeData')
+ this.set('isReady', (upgradeData != null))
+ },
+
+ /**
+ * progress value is rounded to floor
+ * @type {number}
+ */
+ overallProgress: function () {
+ return Math.floor(this.get('controller.upgradeData.Upgrade.progress_percent'));
+ }.property('controller.upgradeData.Upgrade.progress_percent'),
+
+ /**
+ * label of Upgrade status
+ * @type {string}
+ */
+ upgradeStatusLabel: function() {
+ var labelKey = null;
+ switch (this.get('controller.upgradeData.Upgrade.request_status')) {
+ case 'QUEUED':
+ case 'PENDING':
+ case 'IN_PROGRESS':
+ labelKey = 'admin.stackUpgrade.state.inProgress';
+ break;
+ case 'COMPLETED':
+ labelKey = 'admin.stackUpgrade.state.completed';
+ break;
+ case 'ABORTED':
+ labelKey = 'admin.stackUpgrade.state.paused';
+ break;
+ case 'TIMEDOUT':
+ case 'FAILED':
+ case 'HOLDING_FAILED':
+ case 'HOLDING_TIMEDOUT':
+ case 'HOLDING':
+ labelKey = 'admin.stackUpgrade.state.paused';
+ break;
+ }
+ if (labelKey) {
+ labelKey += (this.get('controller.isDowngrade')) ? '.downgrade' : "";
+ return Em.I18n.t(labelKey);
+ } else {
+ return "";
+ }
+ }.property('controller.upgradeData.Upgrade.request_status', 'controller.isDowngrade'),
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js
new file mode 100644
index 0000000..ef5f46b
--- /dev/null
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_history_view.js
@@ -0,0 +1,303 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+var date = require('utils/date/date');
+
+App.MainAdminStackUpgradeHistoryView = App.TableView.extend(App.TableServerViewMixin, {
+
+ controllerBinding: 'App.router.mainAdminStackUpgradeHistoryController',
+
+ templateName: require('templates/main/admin/stack_upgrade/upgrade_history'),
+
+ summary: [],
+
+ isReady: false,
+
+ categories: [
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.all',
+ value: 'ALL',
+ isSelected: true
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.upgrade',
+ value: 'UPGRADE',
+ isSelected: false
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.downgrade',
+ value: 'DOWNGRADE',
+ isSelected: false
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.upgrade',
+ value: 'UPGRADE_COMPLETED',
+ isSelected: false
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.upgrade',
+ value: 'UPGRADE_ABORTED',
+ isSelected: false
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.successful.downgrade',
+ value: 'DOWNGRADE_COMPLETED',
+ isSelected: false
+ }),
+ Em.Object.create({
+ labelKey: 'admin.stackVersions.upgradeHistory.filter.aborted.downgrade',
+ value: 'DOWNGRADE_ABORTED',
+ isSelected: false
+ }),
+ ],
+
+ /**
+ * @type {object}
+ */
+ selectedCategory: Em.computed.findBy('categories', 'isSelected', true),
+
+ filteredCount: function(){
+ var filteredContent = this.get('filteredContent').toArray();
+ return filteredContent.length;
+ }.property('filteredContent'),
+
+ /**
+ * displaying content filtered by upgrade type and upgrade status.
+ */
+ filteredContent: function () {
+ var result = [];
+ var filterValue = 'ALL';
+ var category = this.get('selectedCategory');
+ if (category)
+ filterValue = category.get('value');
+ var result = this.filterBy(filterValue);
+ return result.reverse();
+ }.property('selectedCategory'),
+
+ /**
+ * sort and slice recieved content by pagination parameters
+ */
+ pageContent: function () {
+ var content = this.get('filteredContent').toArray();
+ content = this.processForDisplay(content);
+ content = content.slice(this.get('startIndex') - 1, this.get('endIndex'))
+ return content;
+ }.property('filteredContent', 'startIndex', 'endIndex'),
+
+ processForDisplay: function(content){
+ var processedContent = [];
+ content.forEach(function(item){
+ if('UPGRADE' == item.get('direction'))
+ item.set('directionLabel', Em.I18n.t('common.upgrade'));
+ else
+ item.set('directionLabel', Em.I18n.t('common.downgrade'));
+
+ if('NON_ROLLING' == item.get('upgradeType'))
+ item.set('upgradeTypeLabel', Em.I18n.t('common.express'));
+ else
+ item.set('upgradeTypeLabel', Em.I18n.t('common.rolling'));
+
+ item.set('startTimeLabel', date.startTime(item.get('startTime')));
+ item.set('endTimeLabel', date.startTime(item.get('endTime')));
+ item.set('duration', date.durationSummary(item.get('startTime'), item.get('endTime')));
+ processedContent.push(item);
+ },this);
+ return processedContent;
+ },
+
+ paginationLeftClass: function () {
+ if (this.get("startIndex") > 1) {
+ return "paginate_previous";
+ }
+ return "paginate_disabled_previous";
+ }.property("startIndex", 'filteredCount'),
+
+ /**
+ * Determines how display "next"-link - as link or text
+ * @type {string}
+ */
+ paginationRightClass: function () {
+ if (this.get("endIndex") < this.get("filteredCount")) {
+ return "paginate_next";
+ }
+ return "paginate_disabled_next";
+ }.property("endIndex", 'filteredCount'),
+
+ /**
+ * Show previous-page if user not in the first page
+ * @method previousPage
+ */
+ previousPage: function () {
+ if (this.get('paginationLeftClass') === 'paginate_previous') {
+ this._super();
+ }
+ },
+
+ /**
+ * Show next-page if user not in the last page
+ * @method nextPage
+ */
+ nextPage: function () {
+ if (this.get('paginationRightClass') === 'paginate_next') {
+ this._super();
+ }
+ },
+
+ willInsertElement: function(){
+ var self = this;
+ this.get('controller').loadStackUpgradeHistoryToModel().done(function(){
+ self.populateUpgradeHistorySummary();
+ });
+ },
+
+ didInsertElement: function () {
+ this.observesCategories();
+ },
+
+ observesCategories: function(){
+ this.get('categories').forEach(function (category) {
+ var label = Em.I18n.t(category.labelKey).format(this.filterBy(category.value).length);
+ category.set('label', label)
+ }, this);
+ }.observes('isReady'),
+
+ filterBy: function(filterValue){
+ if ('ALL' == filterValue) {
+ var all_records = App.StackUpgradeHistory.find();
+ return all_records.toArray();
+ } else {
+ var tokens = filterValue.split('_');
+ var direction_token = null
+ var status_token = null
+
+ if (tokens.length == 1) {
+ direction_token = tokens[0]
+ } else if (tokens.length > 1) {
+ direction_token = tokens[0]
+ status_token = tokens[1]
+ }
+
+ var result = []
+ App.StackUpgradeHistory.find().forEach(function(item){
+ var direction = item.get('direction');
+ if (direction == direction_token) {
+ if (status_token != null) {
+ //only for the given status
+ var status = item.get('requestStatus');
+ if (status == status_token) {
+ result.push(item)
+ }
+ } else {
+ //regardless status
+ result.push(item)
+ }
+ }
+ }, this);
+ return result
+ }
+ },
+
+ selectCategory: function(event){
+ this.get('categories').filterProperty('isSelected').setEach('isSelected', false);
+ event.context.set('isSelected', true);
+ },
+
+ populateUpgradeHistorySummary: function(){
+ this.set('isReady', false);
+ var result = [
+ Em.Object.create({
+ direction: 'UPGRADE',
+ label:Em.I18n.t('common.upgrade'),
+ hasSuccess: false,
+ success:0,
+ hasAbort: false,
+ abort:0,
+ }),
+ Em.Object.create({
+ direction: 'DOWNGRADE',
+ label:Em.I18n.t('common.downgrade'),
+ hasSuccess: false,
+ success:0,
+ hasAbort: false,
+ abort:0,
+ })
+ ];
+
+ App.StackUpgradeHistory.find().forEach(function(item){
+ var direction = item.get('direction');
+ var status = item.get('requestStatus');
+ if('UPGRADE' == direction){
+ if('COMPLETED' == status){
+ result[0].set('success', result[0].get('success') + 1);
+ } else if ('ABORTED' == status) {
+ result[0].set('abort', result[0].get('abort') + 1);
+ }
+ } else if('DOWNGRADE' == direction){
+ if('COMPLETED' == status){
+ result[1].set('success', result[1].get('success')+1);
+ } else if ('ABORTED' == status){
+ result[1].set('abort', result[1].get('abort')+1);
+ }
+ }
+ }, this);
+
+ result[0].set('hasSuccess', result[0].get('success') > 0);
+ result[1].set('hasSuccess', result[1].get('success') > 0);
+ result[0].set('hasAbort', result[0].get('abort') > 0);
+ result[1].set('hasAbort', result[1].get('abort') > 0);
+
+ this.set('summary', result);
+ this.set('isReady', true);
+ },
+
+ showUpgradeHistoryRecord: function(event) {
+ var record = event.context
+ var title = '';
+ var direction = App.format.normalizeName(record.get('direction'));
+ var type = record.get('upgradeType')
+ if ('ROLLING' == type)
+ type = App.format.normalizeName(type);
+ else if ('NON_ROLLING' == type)
+ type = 'Express'
+
+ title = Em.I18n.t('admin.stackVersions.upgradeHistory.record.title').format(type, direction, record.get('fromVersion'));
+
+ this.get('controller').set('currentUpgradeRecord', record)
+
+ App.ModalPopup.show({
+ classNames: ['full-width-modal'],
+ header: title,
+ bodyClass: App.MainAdminStackUpgradeHistoryDetailsView,
+ primary: Em.I18n.t('common.dismiss'),
+ secondary: null,
+ didInsertElement: function () {
+ this._super();
+ this.fitHeight();
+ this.fitInnerHeight();
+ },
+ fitInnerHeight: function () {
+ var block = this.$().find('#modal > .modal-body');
+ var scrollable = this.$().find('#modal .scrollable-block');
+ scrollable.css('max-height', Number(block.css('max-height').slice(0, -2)) - block.height());
+ block.css('max-height', 'none');
+ },
+ });
+ },
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js b/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js
new file mode 100644
index 0000000..bbfce19
--- /dev/null
+++ b/ambari-web/test/controllers/main/admin/stack_upgrade_history_controller_test.js
@@ -0,0 +1,125 @@
+/**
+ * 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');
+require('controllers/main/admin/stack_upgrade_history_controller');
+require('utils/string_utils');
+var testHelpers = require('test/helpers');
+describe('App.MainAdminStackUpgradeHistoryController', function() {
+
+ var controller = App.MainAdminStackUpgradeHistoryController.create({
+
+ });
+
+ describe("#upgradeHistoryUrl", function() {
+ before(function () {
+ this.mock = sinon.stub(App, 'get');
+ this.mock.withArgs('apiPrefix').returns('apiPrefix')
+ .withArgs('clusterName').returns('clusterName');
+ });
+ after(function () {
+ this.mock.restore();
+ });
+ it("should be valid", function() {
+ controller.propertyDidChange('upgradeHistoryUrl');
+ expect(controller.get('upgradeHistoryUrl')).to.equal('apiPrefix/clusters/clusterName/upgrades?fields=Upgrade');
+ });
+ });
+
+ describe("#requestStatus", function() {
+ beforeEach(function() {
+ this.mock = sinon.stub(App, 'get');
+ });
+ afterEach(function() {
+ this.mock.restore();
+ });
+ it("state should be what the record states", function() {
+ this.mock.returns(false);
+ controller.set('upgradeData', { Upgrade: {request_status: 'COMPLETED'}});
+ controller.propertyDidChange('requestStatus');
+ expect(controller.get('requestStatus')).to.equal('COMPLETED');
+ });
+
+ it("upgradeData is null", function() {
+ this.mock.returns(false);
+ controller.set('upgradeData', null);
+ controller.propertyDidChange('requestStatus');
+ expect(controller.get('requestStatus')).to.be.empty;
+ });
+ });
+
+ describe("#loadStackUpgradeRecord()", function() {
+ it("get upgrade record data", function() {
+ controller.set('currentUpgradeRecord', Em.Object.create({'requestId':1, 'direction':'DOWNGRADE'}));
+ controller.loadStackUpgradeRecord();
+ var args = testHelpers.findAjaxRequest('name', 'admin.upgrade.data');
+ expect(args[0]).to.exists;
+ expect(args[0].sender).to.be.eql(controller);
+ expect(args[0].data).to.be.eql({
+ id: 1
+ });
+ });
+ });
+
+ describe("#loadUpgradeRecordSuccessCallback()", function() {
+ it("correct data", function() {
+ var data = {
+ "Upgrade": {
+ "request_status": "COMPLETED"
+ },
+ "upgrade_groups": [
+ {
+ "UpgradeGroup": {
+ "id": 1
+ },
+ "upgrade_items": []
+ }
+ ]};
+ controller.loadUpgradeRecordSuccessCallback(data);
+ expect(controller.get('upgradeData') == null).to.be.false;
+ });
+
+ it("data is null", function() {
+ var data = null;
+ controller.set('upgradeData', null)
+ controller.loadUpgradeRecordSuccessCallback(data);
+ expect(controller.get('upgradeData') == null).to.be.true;
+ });
+ });
+
+ describe("#getUpgradeItem()", function() {
+ it("default callback", function() {
+ var item = Em.Object.create({
+ request_id: 1,
+ group_id: 2,
+ stage_id: 3
+ });
+ controller.getUpgradeItem(item);
+ var args = testHelpers.findAjaxRequest('name', 'admin.upgrade.upgrade_item');
+ expect(args[0]).to.exists;
+ expect(args[0].sender).to.be.eql(controller);
+ expect(args[0].success).to.be.equal('getUpgradeItemSuccessCallback');
+ expect(args[0].data).to.be.eql({
+ upgradeId: 1,
+ groupId: 2,
+ stageId: 3
+ });
+ });
+ });
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js b/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js
new file mode 100644
index 0000000..07027e1
--- /dev/null
+++ b/ambari-web/test/mappers/stack_upgrade_history_mapper_test.js
@@ -0,0 +1,372 @@
+/**
+ * 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.
+ */
+
+/*eslint-disable */
+
+var App = require('app');
+
+require('mappers/stack_upgrade_history_mapper');
+
+describe('App.stackUpgradeHistoryMapper', function () {
+
+ describe('#map', function () {
+
+ var data = {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades?fields=Upgrade",
+ "items" : [
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/7",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463779169144,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463779266087,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 7,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463779170159,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/8",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463779266212,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463779299440,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 8,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463779267220,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/9",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463780699654,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463780757685,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 9,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463780700670,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/10",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463780757799,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463780794009,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 10,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463780758807,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/11",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463781287967,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463781341452,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 11,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463781288984,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/12",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1463781341576,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1463781371778,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 12,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1463781342585,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/13",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464120656181,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464120881477,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 13,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464120657198,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/14",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464120881574,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464120918774,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 14,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464120882580,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/15",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464120943986,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464121132856,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 15,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464120945002,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/16",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464121132981,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464121167178,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 16,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464121133988,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/17",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464121207511,
+ "direction" : "UPGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464121301821,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Upgrading to 2.4.0.0-169",
+ "request_id" : 17,
+ "request_status" : "ABORTED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464121208524,
+ "suspended" : false,
+ "to_version" : "2.4.0.0-169",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ },
+ {
+ "href" : "http://bdavm079.svl.ibm.com:8080/api/v1/clusters/bi/upgrades/18",
+ "Upgrade" : {
+ "cluster_name" : "bi",
+ "create_time" : 1464121301933,
+ "direction" : "DOWNGRADE",
+ "downgrade_allowed" : true,
+ "end_time" : 1464121336149,
+ "exclusive" : false,
+ "from_version" : "2.3.6.0-3712",
+ "pack" : "nonrolling-upgrade-2.4",
+ "progress_percent" : 100.0,
+ "request_context" : "Downgrading to 2.3.6.0-3712",
+ "request_id" : 18,
+ "request_status" : "COMPLETED",
+ "skip_failures" : false,
+ "skip_service_check_failures" : false,
+ "start_time" : 1464121302941,
+ "suspended" : false,
+ "to_version" : "2.3.6.0-3712",
+ "type" : "INTERNAL_REQUEST",
+ "upgrade_type" : "NON_ROLLING"
+ }
+ }
+ ]
+ };
+
+ var upgradeParseResult = {
+ 'clusterName':'bi',
+ 'createTime':1464121301933,
+ "direction" : "DOWNGRADE",
+ "downgradeAllowed" : true,
+ "endTime" : 1464121336149,
+ "fromVersion" : "2.3.6.0-3712",
+ "requestId" : 18,
+ "requestStatus" : "COMPLETED",
+ "skipFailures" : false,
+ "skipServiceCheckFailures" : false,
+ "startTime" : 1464121302941,
+ "toVersion" : "2.3.6.0-3712",
+ "upgradeType" : "NON_ROLLING"
+ };
+
+ beforeEach(function () {
+ App.resetDsStoreTypeMap(App.StackUpgradeHistory);
+ sinon.stub(App.store, 'commit', Em.K);
+ });
+
+ afterEach(function(){
+ App.store.commit.restore();
+ });
+
+ it('Parse upgrade records returned by the Ambari server', function () {
+ App.stackUpgradeHistoryMapper.map(data);
+ var all_records = App.StackUpgradeHistory.find();
+ var upgrades = all_records.toArray();
+ expect(upgrades.length).to.eql(12);
+ var total_downgrades = 0;
+ var total_upgrades = 0;
+ upgrades.forEach(function(upgrade){
+ var direction = upgrade.get('direction')
+ if ('DOWNGRADE' == direction){
+ total_downgrades++;
+ }
+ if ('UPGRADE' == direction){
+ total_upgrades++;
+ }
+ });
+ expect(total_upgrades).to.eql(6);
+ expect(total_downgrades).to.eql(6);
+
+ var record = App.StackUpgradeHistory.find().findProperty('requestId', 18);
+ Em.keys(upgradeParseResult).forEach(function (key) {
+ expect(record.get(key)).to.eql(upgradeParseResult[key]);
+ });
+ });
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/models/finished_upgrade_entity_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/finished_upgrade_entity_test.js b/ambari-web/test/models/finished_upgrade_entity_test.js
new file mode 100644
index 0000000..a2a9527
--- /dev/null
+++ b/ambari-web/test/models/finished_upgrade_entity_test.js
@@ -0,0 +1,197 @@
+/**
+ * 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');
+require('models/finished_upgrade_entity');
+
+function getModel() {
+ return App.finishedUpgradeEntity.create();
+}
+
+describe('App.finishedUpgradeEntity', function () {
+ var model;
+
+ beforeEach(function () {
+ model = getModel();
+ });
+
+ App.TestAliases.testAsComputedNotEqual(getModel(), 'isVisible', 'status', 'PENDING');
+
+ describe("#progress", function() {
+ it("progress_percent = 1.9", function() {
+ model.set('progress_percent', 1.9);
+ model.propertyDidChange('progress');
+ expect(model.get('progress')).to.equal(1);
+ });
+ it("progress_percent = 1", function() {
+ model.set('progress_percent', 1);
+ model.propertyDidChange('progress');
+ expect(model.get('progress')).to.equal(1);
+ });
+ });
+
+ describe("#isActive", function() {
+ it("status IN_PROGRESS", function() {
+ model.set('status', 'IN_PROGRESS');
+ model.propertyDidChange('isActive');
+ expect(model.get('isActive')).to.be.true;
+ });
+ it("status PENDING", function() {
+ model.set('status', 'PENDING');
+ model.propertyDidChange('isActive');
+ expect(model.get('isActive')).to.be.false;
+ });
+ });
+
+ describe('#isExpandableGroup', function () {
+
+ var cases = [
+ {
+ input: {
+ type: 'ITEM'
+ },
+ isExpandableGroup: false,
+ title: 'not upgrade group'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'PENDING',
+ hasExpandableItems: false
+ },
+ isExpandableGroup: false,
+ title: 'pending upgrade group without expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'ABORTED',
+ hasExpandableItems: false
+ },
+ isExpandableGroup: true,
+ title: 'aborted upgrade group without expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'ABORTED',
+ hasExpandableItems: true
+ },
+ isExpandableGroup: true,
+ title: 'aborted upgrade group with expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'IN_PROGRESS',
+ hasExpandableItems: false
+ },
+ isExpandableGroup: true,
+ title: 'active upgrade group'
+ }
+ ];
+
+ cases.forEach(function (item) {
+ it(item.title, function () {
+ model.setProperties(item.input);
+ expect(model.get('isExpandableGroup')).to.equal(item.isExpandableGroup);
+ });
+ });
+
+ });
+
+ describe('#upgradeGroupStatus', function () {
+
+ var cases = [
+ {
+ input: {
+ type: 'ITEM',
+ upgradeSuspended: false
+ },
+ upgradeGroupStatus: undefined,
+ title: 'not upgrade group'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'PENDING',
+ hasExpandableItems: false,
+ upgradeSuspended: false
+ },
+ upgradeGroupStatus: 'PENDING',
+ title: 'pending upgrade group'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'PENDING',
+ hasExpandableItems: true,
+ upgradeSuspended: false
+ },
+ upgradeGroupStatus: 'SUBITEM_FAILED',
+ title: 'pending upgrade group with expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'ABORTED',
+ hasExpandableItems: false,
+ upgradeSuspended: false
+ },
+ upgradeGroupStatus: 'ABORTED',
+ title: 'aborted upgrade group with expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'ABORTED',
+ hasExpandableItems: true,
+ upgradeSuspended: true
+ },
+ upgradeGroupStatus: 'ABORTED',
+ title: 'aborted upgrade group with expandable items'
+ },
+ {
+ input: {
+ type: 'GROUP',
+ status: 'IN_PROGRESS',
+ hasExpandableItems: false,
+ upgradeSuspended: false
+ },
+ upgradeGroupStatus: 'IN_PROGRESS',
+ title: 'active upgrade'
+ }
+ ];
+
+ beforeEach(function() {
+ this.mock = sinon.stub(App, 'get');
+ });
+ afterEach(function() {
+ this.mock.restore();
+ });
+
+ cases.forEach(function (item) {
+ it(item.title, function () {
+ this.mock.returns(item.input.upgradeSuspended);
+ model.setProperties(item.input);
+ expect(model.get('upgradeGroupStatus')).to.equal(item.upgradeGroupStatus);
+ });
+ });
+
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js
new file mode 100644
index 0000000..ab38e34
--- /dev/null
+++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_details_view_test.js
@@ -0,0 +1,248 @@
+/**
+ * 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');
+require('views/main/admin/stack_upgrade/upgrade_history_details_view');
+var testHelpers = require('test/helpers');
+
+describe('App.MainAdminStackUpgradeHistoryDetailsView', function () {
+ var view;
+
+ beforeEach(function () {
+ view = App.MainAdminStackUpgradeHistoryDetailsView.create({
+ controller: {
+ currentUpgradeRecord: App.StackUpgradeHistory.createRecord({
+ 'requestId':1,
+ 'direction':'DOWNGRADE',
+ }),
+ }
+ });
+ });
+
+ afterEach(function () {
+ view.destroy();
+ });
+
+ describe("#overallProgress", function () {
+ it("progress is 1.9", function () {
+ view.set('controller.upgradeData', {
+ Upgrade: {
+ progress_percent: 1.9
+ }
+ });
+ expect(view.get('overallProgress')).to.equal(1);
+ });
+ it("progress is 1", function () {
+ view.set('controller.upgradeData', {
+ Upgrade: {
+ progress_percent: 1
+ }
+ });
+ expect(view.get('overallProgress')).to.equal(1);
+ });
+ });
+
+ describe("#willInsertElement()", function() {
+ beforeEach(function () {
+ sinon.spy(view.get('controller'), 'loadStackUpgradeRecord');
+ });
+ afterEach(function () {
+ view.get('controller').loadStackUpgradeRecord.restore();
+ });
+ it("load data by controller is called once", function() {
+ view.set('controller.currentUpgradeRecord', App.StackUpgradeHistory.createRecord({
+ 'requestId':1,
+ 'direction':'DOWNGRADE',
+ }));
+ view.willInsertElement();
+ expect(view.get('controller').loadStackUpgradeRecord.calledOnce).to.be.true;
+ });
+ });
+
+ describe("#willDestroyElement()", function () {
+ it("reset ready flag", function () {
+ view.set('isReady', true);
+ view.willDestroyElement();
+ expect(view.get('isReady')).to.be.false;
+ });
+ });
+
+ describe("#upgradeStatusLabel", function () {
+ beforeEach(function () {
+ Em.setFullPath(view, 'controller.upgradeData.Upgrade', {});
+ });
+
+ [
+ {
+ data: {
+ status: 'QUEUED',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress')
+ },
+ {
+ data: {
+ status: 'PENDING',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress')
+ },
+ {
+ data: {
+ status: 'IN_PROGRESS',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress')
+ },
+ {
+ data: {
+ status: 'COMPLETED',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.completed')
+ },
+ {
+ data: {
+ status: 'ABORTED',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: 'TIMEDOUT',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: 'FAILED',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: 'HOLDING_FAILED',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: 'HOLDING_TIMEDOUT',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: 'HOLDING',
+ isDowngrade: false
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused')
+ },
+ {
+ data: {
+ status: '',
+ isDowngrade: false
+ },
+ result: ''
+ },
+ {
+ data: {
+ status: 'QUEUED',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade')
+ },
+ {
+ data: {
+ status: 'PENDING',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade')
+ },
+ {
+ data: {
+ status: 'IN_PROGRESS',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.inProgress.downgrade')
+ },
+ {
+ data: {
+ status: 'COMPLETED',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.completed.downgrade')
+ },
+ {
+ data: {
+ status: 'ABORTED',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ },
+ {
+ data: {
+ status: 'TIMEDOUT',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ },
+ {
+ data: {
+ status: 'FAILED',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ },
+ {
+ data: {
+ status: 'HOLDING_FAILED',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ },
+ {
+ data: {
+ status: 'HOLDING_TIMEDOUT',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ },
+ {
+ data: {
+ status: 'HOLDING',
+ isDowngrade: true
+ },
+ result: Em.I18n.t('admin.stackUpgrade.state.paused.downgrade')
+ }
+ ].forEach(function (test) {
+ it('status = ' + test.data.status + ", isDowngrade = " + test.data.isDowngrade, function () {
+ view.set('controller.isDowngrade', test.data.isDowngrade);
+ view.set('controller.upgradeData.Upgrade.request_status', test.data.status);
+ view.propertyDidChange('upgradeStatusLabel');
+ expect(view.get('upgradeStatusLabel')).to.equal(test.result);
+ });
+ });
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ef418377/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js
new file mode 100644
index 0000000..d68a854
--- /dev/null
+++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_history_view_test.js
@@ -0,0 +1,173 @@
+/**
+ * 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');
+require('views/main/admin/stack_upgrade/upgrade_history_view');
+var testHelpers = require('test/helpers');
+
+describe('App.MainAdminStackUpgradeHistoryView', function () {
+ var view;
+
+ beforeEach(function () {
+ view = App.MainAdminStackUpgradeHistoryView.create();
+ });
+
+ afterEach(function () {
+ view.destroy();
+ });
+
+ describe("#filterBy()", function () {
+ var records = [
+ Em.Object.create({
+ requestStatus: "ABORTED",
+ direction: "UPGRADE"
+ }),
+ Em.Object.create({
+ requestStatus: "ABORTED",
+ direction: "DOWNGRADE"
+ }),
+ Em.Object.create({
+ requestStatus: "COMPLETED",
+ direction: "UPGRADE"
+ }),
+ Em.Object.create({
+ requestStatus: "COMPLETED",
+ direction: "DOWNGRADE"
+ })
+ ];
+
+
+ beforeEach(function () {
+ this.mock = sinon.stub(App.StackUpgradeHistory, 'find');
+ });
+
+ afterEach(function () {
+ this.mock.restore();
+ });
+
+ it('All should return all records', function(){
+ this.mock.returns(records);
+ var filteredResults = view.filterBy('ALL')
+ expect(filteredResults.length == 4).to.be.true
+ });
+
+ it('Filter aborted upgrades', function(){
+ this.mock.returns(records);
+ var filteredResults = view.filterBy('UPGRADE_ABORTED')
+ expect(filteredResults.length == 1).to.be.true
+ });
+
+ it('Filter completed upgrades', function(){
+ this.mock.returns(records);
+ var filteredResults = view.filterBy('UPGRADE_COMPLETED')
+ expect(filteredResults.length == 1).to.be.true
+ });
+
+ it('Filter aborted downgrades', function(){
+ this.mock.returns(records);
+ var filteredResults = view.filterBy('DOWNGRADE_ABORTED')
+ expect(filteredResults.length == 1).to.be.true
+ });
+
+ it('Filter completed downgrades', function(){
+ this.mock.returns(records);
+ var filteredResults = view.filterBy('DOWNGRADE_COMPLETED')
+ expect(filteredResults.length == 1).to.be.true
+ });
+ });
+
+ describe("#didInsertElement()", function() {
+ beforeEach(function () {
+ sinon.stub(view, 'observesCategories', Em.K);
+ });
+ afterEach(function () {
+ view.observesCategories.restore();
+ });
+ it("observesCategories is called once", function() {
+ view.didInsertElement();
+ expect(view.observesCategories.calledOnce).to.be.true;
+ });
+ });
+
+ describe("#observesCategories()", function () {
+ var mock = {format: Em.K};
+ beforeEach(function () {
+ sinon.stub(Em.I18n, 't').returns(mock);
+ sinon.stub(mock, 'format').returns('label');
+ sinon.stub(view, 'filterBy').returns([]);
+ view.set('categories', [
+ Em.Object.create({
+ labelKey: 'labelKey',
+ value: 'value',
+ isSelected: false
+ })
+ ]);
+ view.observesCategories();
+ });
+ afterEach(function () {
+ Em.I18n.t.restore();
+ mock.format.restore();
+ view.filterBy.restore();
+ });
+ it("categories[0].label is updated", function () {
+ expect(view.get('categories')[0].get('label')).to.equal('label');
+ });
+ });
+
+ describe("#selectCategory()", function() {
+ var event;
+ beforeEach(function () {
+ event = {
+ context: Em.Object.create({
+ isSelected: false,
+ value: 'ALL',
+ })
+ };
+ view.set('categories', [
+ Em.Object.create({
+ isSelected: true,
+ value: 'UPGRADE_COMPLETED',
+ }),
+ event.context
+ ]);
+ view.selectCategory(event);
+ });
+ afterEach(function () {
+ });
+ it("categories[0].isSelected false", function() {
+ expect(view.get('categories')[0].get('isSelected')).to.be.false;
+ });
+ it("isSelected is true", function() {
+ expect(event.context.get('isSelected')).to.be.true;
+ });
+ });
+
+ describe("#willInsertElement()", function() {
+ beforeEach(function () {
+ sinon.spy(view.get('controller'), 'loadStackUpgradeHistoryToModel');
+ });
+ afterEach(function () {
+ view.get('controller').loadStackUpgradeHistoryToModel.restore();
+ });
+ it("load data by controller is called once", function() {
+ view.willInsertElement();
+ expect(view.get('controller').loadStackUpgradeHistoryToModel.calledOnce).to.be.true;
+ });
+ });
+});