You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2015/03/13 11:25:00 UTC

ambari git commit: AMBARI-10039 Enhanced Configs: Create models for configGroup, configVersion and configProperty. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 1ea0ffbfa -> e88914da6


AMBARI-10039 Enhanced Configs: Create models for configGroup, configVersion and configProperty. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e88914da
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e88914da
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e88914da

Branch: refs/heads/trunk
Commit: e88914da66382a5396434d0a546eb72f3f522473
Parents: 1ea0ffb
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Thu Mar 12 15:21:45 2015 +0200
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Fri Mar 13 10:40:40 2015 +0200

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js             |   3 +-
 ambari-web/app/models.js                        |   8 +-
 ambari-web/app/models/configs/config_group.js   |  32 ++++
 .../app/models/configs/config_property.js       | 164 +++++++++++++++++++
 ambari-web/app/models/configs/config_version.js |  27 +++
 .../models/configs/service_config_version.js    | 108 ++++++++++++
 .../app/models/configs/stack_config_property.js | 156 ++++++++++++++++++
 ambari-web/app/models/service_config_version.js | 108 ------------
 .../test/models/configs/config_property_test.js |  66 ++++++++
 .../configs/service_config_version_test.js      |  54 ++++++
 .../test/models/service_config_version_test.js  |  54 ------
 11 files changed, 615 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/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 ffc3856..10b7f65 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -259,13 +259,14 @@ var files = ['test/init_model_test',
   'test/models/host_component_test',
   'test/models/hosts_test',
   'test/models/service_config_test',
-  'test/models/service_config_version_test',
   'test/models/stack_service_component_test',
   'test/models/service_test',
   'test/models/stack_service_test',
   'test/models/user_test',
   'test/models/host_stack_version_test',
   'test/models/upgrade_entity_test',
+  'test/models/configs/service_config_version_test',
+  'test/models/configs/config_property_test',
   'test/routes/views_test',
   //contains test with fake timers that affect Date
   'test/utils/lazy_loading_test'

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index d48e934..63b8c1e 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -57,7 +57,11 @@ require('models/host_component');
 require('models/target_cluster');
 require('models/slave_component');
 require('models/config_group');
-require('models/service_config_version');
 require('models/host_stack_version');
 require('models/root_service');
-require('models/upgrade_entity');
\ No newline at end of file
+require('models/upgrade_entity');
+require('models/configs/service_config_version');
+require('models/configs/stack_config_property');
+require('models/configs/config_group');
+require('models/configs/config_version');
+require('models/configs/config_property');
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/configs/config_group.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/config_group.js b/ambari-web/app/models/configs/config_group.js
new file mode 100644
index 0000000..c3598b2
--- /dev/null
+++ b/ambari-web/app/models/configs/config_group.js
@@ -0,0 +1,32 @@
+/**
+ * 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.ServiceConfigGroup = DS.Model.extend({
+  id: DS.attr('number'),
+  name: DS.attr('string'),
+  serviceName: DS.attr('string'),
+  description: DS.attr('string'),
+  hostNames: DS.attr('array'),
+  configVersions: DS.hasMany('App.ConfigVersion'),
+  service: DS.belongsTo('App.Service')
+});
+
+App.ServiceConfigGroup.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/configs/config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/config_property.js b/ambari-web/app/models/configs/config_property.js
new file mode 100644
index 0000000..b5bb941
--- /dev/null
+++ b/ambari-web/app/models/configs/config_property.js
@@ -0,0 +1,164 @@
+/**
+ * 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.ConfigProperty = App.StackConfigProperty.extend({
+
+  /**
+   * id is consist of property <code>name<code>+<code>fileName<code>+<code>configVersion.version<code>
+   */
+  id: DS.attr('string'),
+
+  /**
+   * value of property
+   * by default is same as <code>defaultValue<code>
+   * @property {string}
+   */
+  value: DS.attr('string'),
+
+  /**
+   * defines if property is final
+   * @property {boolean}
+   */
+  isFinal:  DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * link to config version
+   * @property {App.ConfigVersion}
+   */
+  configVersion: DS.belongsTo('App.ConfigVersion'),
+
+  /**
+   * defines if property should be visible for user
+   * all properties that has <code>isVisible<code> false will be present in model
+   * and saved but will be hidden from user
+   * @property {boolean}
+   */
+  isVisible: DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * defines if property value is required
+   * in case user enter empty value error will be shown
+   * @property {boolean}
+   */
+  isRequired: DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * defines if property can be edited by user
+   * @property {boolean}
+   */
+  isEditable: DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * opposite to <code>isEditable<code> property
+   * @property {boolean}
+   */
+  isNotEditable: Ember.computed.not('isEditable'),
+
+  /**
+   * defines if property belongs to default config group
+   * if true it's config group is default
+   * //TODO probably make computed basing on configVersion.configGroup.isDefault
+   * @property {boolean}
+   */
+  isOriginalSCP : DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * defines if property can contain overriden values
+   * @property {boolean}
+   */
+  isOverridable: DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * defines if property is used for security
+   * @property {boolean}
+   */
+  isSecureConfig: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * defines if property is added by user
+   * @property {boolean}
+   */
+  isUserProperty: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * if true - don't show property
+   * @property {boolean}
+   */
+  isHiddenByFilter: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * Don't show "Undo" for hosts on Installer Step7
+   * if value is true
+   * @property {boolean}
+   */
+  cantBeUndone: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * error message; by default is empty
+   * if value is not correct or missing for required property
+   * this will contain error message
+   * @property {string}
+   */
+  errorMessage: DS.attr('string', {defaultValue: ''}),
+
+  /**
+   * warning message; by default is empty
+   * if value is out of recommended range
+   * this will contain warning message
+   * @property {string}
+   */
+  warnMessage: DS.attr('string', {defaultValue: ''}),
+
+  /**
+   * defines if property has errors
+   * @type {boolean}
+   */
+  hasErrors: function() {
+    return this.get('errorMessage') !== '';
+  }.property('errorMessage'),
+
+  /**
+   * defines if property has warnings
+   * @type {boolean}
+   */
+  hasWarnings: function() {
+    return this.get('warnMessage') !== '';
+  }.property('warnMessage'),
+
+  /**
+   * Indicates when value is not the default value.
+   * Returns false when there is no default value.
+   * @type {boolean}
+   */
+  isNotDefaultValue: function () {
+    return this.get('isEditable')
+      && ((this.get('defaultValue') != null && this.get('value') !== this.get('defaultValue'))
+      || (this.get('supportsFinal') && this.get('isFinal') !== this.get('defaultIsFinal')));
+  }.property('value', 'defaultValue', 'isEditable', 'isFinal', 'defaultIsFinal'),
+
+  /**
+   * opposite to <code>hasErrors<code>
+   */
+  isValid: Ember.computed.not('hasErrors')
+});
+
+
+App.ConfigProperty.FIXTURES = [];
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/configs/config_version.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/config_version.js b/ambari-web/app/models/configs/config_version.js
new file mode 100644
index 0000000..30c32fe
--- /dev/null
+++ b/ambari-web/app/models/configs/config_version.js
@@ -0,0 +1,27 @@
+/**
+ * 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.ConfigVersion = App.ServiceConfigVersion.extend({
+  configGroup: DS.belongsTo('App.ServiceConfigGroup'),
+  configProperties: DS.hasMany('App.ConfigProperty')
+});
+
+App.ConfigVersion.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/configs/service_config_version.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/service_config_version.js b/ambari-web/app/models/configs/service_config_version.js
new file mode 100644
index 0000000..6729cfe
--- /dev/null
+++ b/ambari-web/app/models/configs/service_config_version.js
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+var dateUtil = require('utils/date');
+
+
+App.ServiceConfigVersion = DS.Model.extend({
+  serviceName: DS.attr('string'),
+  displayName: function() {
+    return App.format.role(this.get('serviceName'));
+  }.property('serviceName'),
+  groupName: DS.attr('string'),
+  groupId: DS.attr('number'),
+  version: DS.attr('number'),
+  createTime: DS.attr('number'),
+  author: DS.attr('string'),
+  notes: DS.attr('string'),
+  service: DS.belongsTo('App.Service'),
+  hosts: DS.attr('array'),
+  index: DS.attr('number'),
+  isCurrent: DS.attr('boolean'),
+  isDisplayed: DS.attr('boolean'),
+  isDefault: function() {
+    return this.get('groupName') === 'default';
+  }.property('groupName'),
+  currentTooltip: function () {
+    return Em.I18n.t('dashboard.configHistory.table.current.tooltip').format(this.get('displayName'), this.get('configGroupName'));
+  }.property('displayName', 'configGroupName'),
+  configGroupName: function () {
+    return this.get('isDefault') ? (this.get('displayName') + ' ' + Em.I18n.t('common.default')) : this.get('groupName');
+  }.property('groupName','isDefault'),
+  authorFormatted: function () {
+    var author = this.get('author');
+    if (author) {
+      return author.length > 20 ? author.slice(0, 20) + '...' : author;
+    }
+  }.property('author'),
+  fullNotes: function () {
+    return (typeof this.get('notes') === 'string') ? this.get('notes') || Em.I18n.t('dashboard.configHistory.table.notes.no') : Em.I18n.t('dashboard.configHistory.table.notes.no');
+  }.property('notes'),
+  briefNotes: function () {
+    return this.get('fullNotes').slice(0, 81);
+  }.property('fullNotes'),
+  moreNotesExists: function () {
+    return (typeof this.get('notes') === 'string') ?  this.get('notes').length > 80 : false;
+  }.property('notes'),
+  versionText: function () {
+    return Em.I18n.t('dashboard.configHistory.table.version.versionText').format(this.get('version'));
+  }.property('version'),
+  makeCurrentButtonText: function() {
+    return Em.I18n.t('dashboard.configHistory.info-bar.revert.versionButton').format(this.get('versionText'));
+  }.property('versionText'),
+  createdDate: function () {
+    return dateUtil.dateFormat(this.get('createTime'));
+  }.property('createTime'),
+  timeSinceCreated: function () {
+    return $.timeago(this.get('createTime'));
+  }.property('createTime'),
+  /**
+   * determine whether ServiceConfigVersion is requested from server
+   */
+  isRequested: DS.attr('boolean'),
+  isRestartRequired: function () {
+    if (this.get('service.isRestartRequired') && this.get('isCurrent')) {
+      var hostNames = this.get('hosts');
+      if (!hostNames.length) return false;
+      for (var i = 0; i < hostNames.length; i++) {
+        if (Object.keys(this.get('service.restartRequiredHostsAndComponents')).contains(hostNames[i])) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }.property('service.isRestartRequired','isDefault', 'isCurrent', 'hosts', 'service.restartRequiredHostsAndComponents', 'router.mainServiceInfoConfigsController.configGroups'),
+  disabledActionMessages: function () {
+    return {
+      view: (this.get('isDisplayed')) ? Em.I18n.t('dashboard.configHistory.info-bar.view.button.disabled') : '',
+      compare: (this.get('isDisplayed')) ? Em.I18n.t('dashboard.configHistory.info-bar.compare.button.disabled') : '',
+      revert: (this.get('isCurrent')) ? Em.I18n.t('dashboard.configHistory.info-bar.revert.button.disabled') : ''
+    }
+  }.property('isDisplayed', 'isCurrent'),
+  disabledActionAttr: function () {
+    return {
+      view: (this.get('isDisplayed')) ? 'disabled' : false,
+      compare: (this.get('isDisabled') || this.get('isDisplayed')) ? 'disabled' : false,
+      revert: (this.get('isDisabled') || this.get('isCurrent')) ? 'disabled' : false
+    }
+  }.property('isDisplayed', 'isCurrent', 'isDisabled')
+});
+
+App.ServiceConfigVersion.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/configs/stack_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/stack_config_property.js b/ambari-web/app/models/configs/stack_config_property.js
new file mode 100644
index 0000000..7a29fac
--- /dev/null
+++ b/ambari-web/app/models/configs/stack_config_property.js
@@ -0,0 +1,156 @@
+/**
+ * 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.StackConfigProperty = DS.Model.extend({
+  /**
+   * id is consist of property <code>name<code>+<code>fileName<code>
+   */
+  id: DS.attr('string'),
+  /**
+   * name of property that is taken from stack
+   * @property {string}
+   */
+  name: DS.attr('string'),
+
+  /**
+   * display name of property that is taken from ui or
+   * if UI has no info about property this can be formatted or plain name of property
+   * @property {string}
+   */
+  displayName: DS.attr('string'),
+
+  /**
+   * filename of property that is taken from stack
+   * ex: "hdfs-site.xml"
+   * @property {string}
+   */
+  fileName: DS.attr('string'),
+
+  /**
+   * description of config property meaning
+   * @property {string}
+   */
+  description: DS.attr('string'),
+
+  /**
+   * defaultValue value of property is taken from stack before cluster is created
+   * after cluster created is taken from cluster properties value
+   * @property {string}
+   */
+  defaultValue: DS.attr('string'),
+
+  /**
+   * defines if property support usage <code>isFinal<code> flag
+   * @property {boolean}
+   */
+  supportsFinal: DS.attr('boolean', {defaultValue: true}),
+
+  /**
+   * defines the defaultValue value of <code>isFinal<code> value
+   * @property {boolean}
+   */
+  defaultIsFinal: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * type of property
+   * @property {string[]}
+   */
+  type: DS.attr('array', {defaultValue: []}),
+
+  /**
+   * defines what kind of value this property contains
+   * ex: string, digits, number, directories, custom
+   * @property {string}
+   */
+  displayType: DS.attr('string', {defaultValue: 'string'}),
+
+  /**
+   * defines category name of property
+   * used for advanced tab
+   * @property {string}
+   */
+  categoryName: DS.attr('string'),
+
+  /**
+   * service name
+   * @property {string}
+   */
+  serviceName:  DS.attr('string'),
+
+  /**
+   * stack name
+   * @property {string}
+   */
+  stackName:  DS.attr('string'),
+
+  /**
+   * stack version
+   * @property {string}
+   */
+  stackVersion:  DS.attr('string'),
+
+  /**
+   * describe widget details
+   * @property {object}
+   */
+  widget: DS.attr('object', {defaultValue: null}),
+
+  /**
+   * this property contains array of properties which value
+   * is dependent from current property
+   * @property {array}
+   */
+  propertyDependedBy: DS.attr('array', {defaultValue: []}),
+
+  /**
+   * info for displaying property
+   * example:
+   * {
+   *    "type": "value-list",
+   *    "entries": ["true", "false"],
+   *    "entry_labels": ["Active", "Inactive"],
+   *    "entries_editable": "false",
+   *    "selection_cardinality": "1"
+   * },
+   * OR
+   * {
+   *    "type": "int",
+   *    "minimum": "512",
+   *    "maximum": "10240",
+   *    "unit": "MB"
+   * },
+   * OR
+   * {
+   *    "type": "value-list",
+   *    "entries": ["New_MySQL_Database", "Existing_MySQL_Database", "Existing_PostgreSQL_Database", "Existing_Oracle_Database"],
+   *    "entry_labels": ["New MySQL Database", "Existing MySQL Database", "Existing PostgreSQL Database", "Existing Oracle Database"],
+   *    "entry_descriptions": ["d1", "d2", "d3", "d4"],
+   *    "entries_editable": "false",
+   *    "selection_cardinality": "1" // 0+, 1+, etc.
+   * }
+   * @property {object}
+   */
+  valueAttributes: DS.attr('object', {defaultValue: null})
+
+});
+
+
+App.StackConfigProperty.FIXTURES = [];
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/app/models/service_config_version.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service_config_version.js b/ambari-web/app/models/service_config_version.js
deleted file mode 100644
index 6729cfe..0000000
--- a/ambari-web/app/models/service_config_version.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * 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 dateUtil = require('utils/date');
-
-
-App.ServiceConfigVersion = DS.Model.extend({
-  serviceName: DS.attr('string'),
-  displayName: function() {
-    return App.format.role(this.get('serviceName'));
-  }.property('serviceName'),
-  groupName: DS.attr('string'),
-  groupId: DS.attr('number'),
-  version: DS.attr('number'),
-  createTime: DS.attr('number'),
-  author: DS.attr('string'),
-  notes: DS.attr('string'),
-  service: DS.belongsTo('App.Service'),
-  hosts: DS.attr('array'),
-  index: DS.attr('number'),
-  isCurrent: DS.attr('boolean'),
-  isDisplayed: DS.attr('boolean'),
-  isDefault: function() {
-    return this.get('groupName') === 'default';
-  }.property('groupName'),
-  currentTooltip: function () {
-    return Em.I18n.t('dashboard.configHistory.table.current.tooltip').format(this.get('displayName'), this.get('configGroupName'));
-  }.property('displayName', 'configGroupName'),
-  configGroupName: function () {
-    return this.get('isDefault') ? (this.get('displayName') + ' ' + Em.I18n.t('common.default')) : this.get('groupName');
-  }.property('groupName','isDefault'),
-  authorFormatted: function () {
-    var author = this.get('author');
-    if (author) {
-      return author.length > 20 ? author.slice(0, 20) + '...' : author;
-    }
-  }.property('author'),
-  fullNotes: function () {
-    return (typeof this.get('notes') === 'string') ? this.get('notes') || Em.I18n.t('dashboard.configHistory.table.notes.no') : Em.I18n.t('dashboard.configHistory.table.notes.no');
-  }.property('notes'),
-  briefNotes: function () {
-    return this.get('fullNotes').slice(0, 81);
-  }.property('fullNotes'),
-  moreNotesExists: function () {
-    return (typeof this.get('notes') === 'string') ?  this.get('notes').length > 80 : false;
-  }.property('notes'),
-  versionText: function () {
-    return Em.I18n.t('dashboard.configHistory.table.version.versionText').format(this.get('version'));
-  }.property('version'),
-  makeCurrentButtonText: function() {
-    return Em.I18n.t('dashboard.configHistory.info-bar.revert.versionButton').format(this.get('versionText'));
-  }.property('versionText'),
-  createdDate: function () {
-    return dateUtil.dateFormat(this.get('createTime'));
-  }.property('createTime'),
-  timeSinceCreated: function () {
-    return $.timeago(this.get('createTime'));
-  }.property('createTime'),
-  /**
-   * determine whether ServiceConfigVersion is requested from server
-   */
-  isRequested: DS.attr('boolean'),
-  isRestartRequired: function () {
-    if (this.get('service.isRestartRequired') && this.get('isCurrent')) {
-      var hostNames = this.get('hosts');
-      if (!hostNames.length) return false;
-      for (var i = 0; i < hostNames.length; i++) {
-        if (Object.keys(this.get('service.restartRequiredHostsAndComponents')).contains(hostNames[i])) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }.property('service.isRestartRequired','isDefault', 'isCurrent', 'hosts', 'service.restartRequiredHostsAndComponents', 'router.mainServiceInfoConfigsController.configGroups'),
-  disabledActionMessages: function () {
-    return {
-      view: (this.get('isDisplayed')) ? Em.I18n.t('dashboard.configHistory.info-bar.view.button.disabled') : '',
-      compare: (this.get('isDisplayed')) ? Em.I18n.t('dashboard.configHistory.info-bar.compare.button.disabled') : '',
-      revert: (this.get('isCurrent')) ? Em.I18n.t('dashboard.configHistory.info-bar.revert.button.disabled') : ''
-    }
-  }.property('isDisplayed', 'isCurrent'),
-  disabledActionAttr: function () {
-    return {
-      view: (this.get('isDisplayed')) ? 'disabled' : false,
-      compare: (this.get('isDisabled') || this.get('isDisplayed')) ? 'disabled' : false,
-      revert: (this.get('isDisabled') || this.get('isCurrent')) ? 'disabled' : false
-    }
-  }.property('isDisplayed', 'isCurrent', 'isDisabled')
-});
-
-App.ServiceConfigVersion.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/test/models/configs/config_property_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/config_property_test.js b/ambari-web/test/models/configs/config_property_test.js
new file mode 100644
index 0000000..84cae0b
--- /dev/null
+++ b/ambari-web/test/models/configs/config_property_test.js
@@ -0,0 +1,66 @@
+/**
+ * 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/configs/config_property');
+
+var model;
+
+describe('App.ConfigProperty', function () {
+  model = App.ConfigProperty.createRecord();
+
+  describe('#hasErrors', function () {
+    it('should set hasErrors to true', function () {
+      expect(model.setProperties({'errorMessage': 'some error'}).get('hasErrors')).to.eql(true);
+    });
+    it('should set hasErrors to false', function () {
+      expect(model.setProperties({'errorMessage': ''}).get('hasErrors')).to.eql(false);
+    });
+  });
+
+  describe('#hasWarnings', function () {
+    it('should set hasWarnings to true', function () {
+      expect(model.setProperties({'warnMessage': 'some warning'}).get('hasWarnings')).to.eql(true);
+    });
+    it('should set hasWarnings to false', function () {
+      expect(model.setProperties({'warnMessage': ''}).get('hasWarnings')).to.eql(false);
+    });
+  });
+
+  describe('#isNotDefaultValue', function () {
+    var tests = [
+      { isEditable: false, value: 1, defaultValue: 2, supportsFinal: true, isFinal: true, defaultIsFinal: false, isNotDefaultValue: false },
+      { isEditable: true, value: 1, defaultValue: 1, supportsFinal: false, isFinal: true, defaultIsFinal: true, isNotDefaultValue: false },
+      { isEditable: true, value: 1, defaultValue: null, supportsFinal: false, isFinal: true, defaultIsFinal: true, isNotDefaultValue: false },
+      { isEditable: true, value: 1, defaultValue: 1, supportsFinal: true, isFinal: true, defaultIsFinal: true, isNotDefaultValue: false },
+
+      { isEditable: true, value: 2, defaultValue: 1, supportsFinal: true, isFinal: true, defaultIsFinal: true, isNotDefaultValue: true },
+      { isEditable: true, value: 2, defaultValue: 1, supportsFinal: false, isFinal: true, defaultIsFinal: false, isNotDefaultValue: true },
+      { isEditable: true, value: 1, defaultValue: 1, supportsFinal: true, isFinal: false, defaultIsFinal: true, isNotDefaultValue: true },
+    ];
+
+    tests.forEach(function(t, i) {
+      it('should set isNotDefaultValue to ' + t.isNotDefaultValue + ' situation ' + i, function () {
+        expect(model.setProperties({'isEditable': t.isEditable, 'value': t.value, defaultValue: t.defaultValue,
+          supportsFinal: t.supportsFinal, isFinal: t.isFinal, defaultIsFinal:t.defaultIsFinal}).get('isNotDefaultValue')).to.eql(t.isNotDefaultValue);
+      });
+    });
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/test/models/configs/service_config_version_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/service_config_version_test.js b/ambari-web/test/models/configs/service_config_version_test.js
new file mode 100644
index 0000000..fbddcb8
--- /dev/null
+++ b/ambari-web/test/models/configs/service_config_version_test.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');
+require('models/configs/service_config_version');
+
+var model;
+
+describe('App.ServiceConfigVersion', function () {
+
+  beforeEach(function () {
+    model = App.ServiceConfigVersion.createRecord({});
+  });
+
+  describe('#authorFormatted', function () {
+
+    var cases = [
+      {
+        author: 'admin',
+        authorFormatted: 'admin',
+        title: 'should display username as is'
+      },
+      {
+        author: 'userNameIsTooLongToDisplay',
+        authorFormatted: 'userNameIsTooLongToD...',
+        title: 'should trim username to 20 chars'
+      }
+    ];
+
+    cases.forEach(function (item) {
+      it(item.title, function () {
+        model.set('author', item.author);
+        expect(model.get('authorFormatted')).to.equal(item.authorFormatted);
+      });
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/e88914da/ambari-web/test/models/service_config_version_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/service_config_version_test.js b/ambari-web/test/models/service_config_version_test.js
deleted file mode 100644
index a4a93f3..0000000
--- a/ambari-web/test/models/service_config_version_test.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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/service_config_version');
-
-var model;
-
-describe('App.ServiceConfigVersion', function () {
-
-  beforeEach(function () {
-    model = App.ServiceConfigVersion.createRecord({});
-  });
-
-  describe('#authorFormatted', function () {
-
-    var cases = [
-      {
-        author: 'admin',
-        authorFormatted: 'admin',
-        title: 'should display username as is'
-      },
-      {
-        author: 'userNameIsTooLongToDisplay',
-        authorFormatted: 'userNameIsTooLongToD...',
-        title: 'should trim username to 20 chars'
-      }
-    ];
-
-    cases.forEach(function (item) {
-      it(item.title, function () {
-        model.set('author', item.author);
-        expect(model.get('authorFormatted')).to.equal(item.authorFormatted);
-      });
-    });
-
-  });
-
-});