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/17 15:47:45 UTC
ambari git commit: AMBARI-10104 Enhanced Configs: create models and
mappers for tab sections and subsections. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk 9fe2741dc -> ea1d531be
AMBARI-10104 Enhanced Configs: create models and mappers for tab sections and subsections. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ea1d531b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ea1d531b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ea1d531b
Branch: refs/heads/trunk
Commit: ea1d531beb002af36e320550873594acae5147d4
Parents: 9fe2741
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Tue Mar 17 16:14:03 2015 +0200
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Tue Mar 17 16:47:37 2015 +0200
----------------------------------------------------------------------
.../app/assets/data/configurations/theme.json | 174 ++++++++++++++
ambari-web/app/assets/test/tests.js | 1 +
ambari-web/app/mappers.js | 1 +
.../mappers/configs/config_versions_mapper.js | 14 +-
ambari-web/app/mappers/configs/themes_mapper.js | 177 +++++++++++++++
ambari-web/app/models.js | 5 +-
.../app/models/configs/config_property.js | 46 +++-
ambari-web/app/models/configs/config_version.js | 10 +-
ambari-web/app/models/configs/section.js | 37 +++
.../app/models/configs/stack_config_property.js | 8 +-
ambari-web/app/models/configs/sub_section.js | 36 +++
ambari-web/app/models/configs/tab.js | 34 +++
ambari-web/app/utils/ajax/ajax.js | 6 +
ambari-web/app/utils/config.js | 59 +++--
.../views/common/configs/service_config_view.js | 32 +--
.../test/mappers/configs/themes_mapper_test.js | 225 +++++++++++++++++++
16 files changed, 800 insertions(+), 65 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/assets/data/configurations/theme.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/configurations/theme.json b/ambari-web/app/assets/data/configurations/theme.json
new file mode 100644
index 0000000..b756230
--- /dev/null
+++ b/ambari-web/app/assets/data/configurations/theme.json
@@ -0,0 +1,174 @@
+{
+ "Theme": {
+ "name": "default",
+ "service_name": "YARN",
+ "description": "Default theme for YARN service",
+ "configuration": {
+ "layouts": [
+ {
+ "name": "default",
+ "tabs": [
+ {
+ "name": "Settings",
+ "display-name": "Settings",
+ "layout": {
+ "tab-columns": "1",
+ "tab-rows": "2",
+ "sections": [
+ {
+ "name": "section-nm-sizing",
+ "display-name": "NM Sizing",
+ "row-index": "0",
+ "column-span": "1",
+ "column-index": "0",
+ "row-span": "1",
+ "section-columns": "1",
+ "section-rows": "1",
+ "subsections": []
+ },
+ {
+ "name": "section-scheduler-defaults",
+ "display-name": "Scheduler Defaults",
+ "row-index": "1",
+ "column-index": "0",
+ "row-span": "1",
+ "section-columns": "1",
+ "section-rows": "1",
+ "subsections": []
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "placement": {
+ "configuration-layout": "default",
+ "configs": [
+ {
+ "config": "yarn.nodemanager.resource.memory-mb",
+ "section-name": "section-nm-sizing"
+ },
+ {
+ "config": "yarn.nodemanager.vmem-pmem-ratio",
+ "section-name": "section-nm-sizing"
+ },
+ {
+ "config": "yarn.nodemanager.resource.percentage-physical-cpu-limit",
+ "section-name": "section-nm-sizing"
+ },
+ {
+ "config": "yarn.nodemanager.resource.cpu-vcores",
+ "section-name": "section-nm-sizing"
+ },
+ {
+ "config": "yarn.scheduler.minimum-allocation-mb",
+ "section-name": "section-scheduler-defaults"
+ },
+ {
+ "config": "yarn.scheduler.maximum-allocation-mb",
+ "section-name": "section-scheduler-defaults"
+ },
+ {
+ "config": "yarn.scheduler.minimum-allocation-vcores",
+ "section-name": "section-scheduler-defaults"
+ },
+ {
+ "config": "yarn.scheduler.maximum-allocation-vcores",
+ "section-name": "section-scheduler-defaults"
+ }
+ ]
+ },
+ "widgets":[
+ {
+ "config":"yarn.nodemanager.resource.memory-mb",
+ "widget":{
+ "type":"slider",
+ "units":[
+ {
+ "unit-name":"MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "yarn.nodemanager.vmem-pmem-ratio",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "float"
+ }
+ ]
+ }
+ },
+ {
+ "config": "yarn.nodemanager.resource.percentage-physical-cpu-limit",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "percent"
+ }
+ ]
+ }
+ },
+ {
+ "config": "yarn.nodemanager.resource.cpu-vcores",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config":"yarn.scheduler.minimum-allocation-mb",
+ "widget":{
+ "type":"slider",
+ "units":[
+ {
+ "unit-name":"MB"
+ }
+ ]
+ }
+ },
+ {
+ "config":"yarn.scheduler.maximum-allocation-mb",
+ "widget":{
+ "type":"slider",
+ "units":[
+ {
+ "unit-name":"MB"
+ }
+ ]
+ }
+ },
+ {
+ "config":"yarn.scheduler.minimum-allocation-vcores",
+ "widget":{
+ "type":"slider",
+ "units":[
+ {
+ "unit-name":"int"
+ }
+ ]
+ }
+ },
+ {
+ "config":"yarn.scheduler.maximum-allocation-vcores",
+ "widget":{
+ "type":"slider",
+ "units":[
+ {
+ "unit-name":"int"
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/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 12a4d07..ee6d81c 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -133,6 +133,7 @@ var files = ['test/init_model_test',
'test/mappers/configs/stack_config_properties_mapper_test',
'test/mappers/configs/config_groups_mapper_test',
'test/mappers/configs/config_versions_mapper_test',
+ 'test/mappers/configs/themes_mapper_test',
'test/mixins/common/chart/storm_linear_time_test',
'test/mixins/common/localStorage_test',
'test/mixins/common/serverValidator_test',
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
index 01c49eb..04086af 100644
--- a/ambari-web/app/mappers.js
+++ b/ambari-web/app/mappers.js
@@ -21,6 +21,7 @@ require('mappers/server_data_mapper');
require('mappers/stack_service_mapper');
require('mappers/stack_mapper');
require('mappers/stack_version_mapper');
+require('mappers/configs/themes_mapper');
require('mappers/configs/stack_config_properties_mapper');
//require('mappers/configs/config_groups_mapper');
require('mappers/configs/config_versions_mapper');
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/mappers/configs/config_versions_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/config_versions_mapper.js b/ambari-web/app/mappers/configs/config_versions_mapper.js
index f268e13..1ae43dc 100644
--- a/ambari-web/app/mappers/configs/config_versions_mapper.js
+++ b/ambari-web/app/mappers/configs/config_versions_mapper.js
@@ -32,10 +32,11 @@ App.configVersionsMapper = App.QuickDataMapper.create({
author: 'user',
notes: 'service_config_version_note',
is_current: 'is_current',
- index: 'index'
+ index: 'index',
+ is_for_compare: 'is_for_compare'
},
- map: function (json) {
+ map: function (json, isForCompare) {
var configVersions = [];
var itemIds = {};
var serviceToHostMap = {};
@@ -48,6 +49,7 @@ App.configVersionsMapper = App.QuickDataMapper.create({
itemIds[parsedItem.id] = true;
parsedItem.index = index;
parsedItem.config_properties = [];
+ parsedItem.is_for_compare = Boolean(isForCompare);
if (serviceToHostMap[item.service_name]) {
serviceToHostMap[item.service_name] = serviceToHostMap[item.service_name].concat(item.hosts);
@@ -66,12 +68,14 @@ App.configVersionsMapper = App.QuickDataMapper.create({
var properties_array = Object.keys(config.properties);
for (var i = 0; i < properties_array.length; i++) {
var key = properties_array[i];
- var property = App.StackConfigProperty.find(key + '_' + type).toJSON();
- property.id = key + '_' + type + '_' + item.service_config_version;
+ var property = {
+ id: key + '_' + type + '_' + item.service_config_version,
+ config_version_id: parsedItem.id,
+ stack_config_property_id: key + '_' + type
+ };
property.value = property.default_value = config.properties[key];
property.is_final = property.default_is_final = !!item.properties_attributes && item.properties_attributes.final[key] === "true";
- property.config_version_id = parsedItem.id;
properties.push(property);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/mappers/configs/themes_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/themes_mapper.js b/ambari-web/app/mappers/configs/themes_mapper.js
new file mode 100644
index 0000000..62f4d31
--- /dev/null
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -0,0 +1,177 @@
+/**
+ * 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.themesMapper = App.QuickDataMapper.create({
+ tabModel: App.Tab,
+ sectionModel: App.Section,
+ subSectionModel: App.SubSection,
+
+ tabConfig: {
+ "id": "name",
+ "name": "name",
+ "display_name": "display-name",
+ "columns": "layout.tab-columns",
+ "rows": "layout.tab-rows",
+ "service_name": "service_name",
+ "sections_key": "sections"
+ },
+
+ sectionConfig: {
+ "id": "name",
+ "name": "name",
+ "display_name": "display-name",
+ "row_index": "row-index",
+ "column_index": "column-index",
+ "row_span": "row-span",
+ "column_span": "column-span",
+ "section_columns": "section-columns",
+ "section_rows": "section-rows",
+ "tab_id": "tab_id"
+ },
+
+ subSectionConfig: {
+ "id": "name",
+ "name": "name",
+ "display_name": "display-name",
+ "border": "border",
+ "row_index": "row-index",
+ "column_index": "column-index",
+ "column_span": "column-span",
+ "row_span": "row-span",
+ "configProperties": "config_properties",
+ "section_id": "section_id"
+ },
+
+ map: function (json) {
+ var tabs = [];
+ if (Em.get(json, "Theme.configuration.layouts")) {
+ var serviceName = Em.get(json, "Theme.service_name");
+ Em.get(json, "Theme.configuration.layouts").forEach(function(layout) {
+
+ if (layout.tabs) {
+ layout.tabs.forEach(function(tab) {
+ var parsedTab = this.parseIt(tab, this.get("tabConfig"));
+ parsedTab.id = serviceName + "_" + tab.name;
+ parsedTab.service_name = serviceName;
+
+ if (Em.get(tab, "layout.sections")) {
+ var sections = [];
+ Em.get(tab, "layout.sections").forEach(function(section) {
+ var parsedSection = this.parseIt(section, this.get("sectionConfig"));
+ parsedSection.tab_id = parsedTab.id;
+
+ if (section.subsections) {
+ var subSections = [];
+ section.subsections.forEach(function(subSection) {
+ var parsedSubSection = this.parseIt(subSection, this.get("subSectionConfig"));
+ parsedSubSection.section_id = parsedSection.id;
+
+ subSections.push(parsedSubSection);
+ }, this);
+ App.store.loadMany(this.get("subSectionModel"), subSections);
+ parsedSection.sub_sections = subSections.mapProperty("id");
+ }
+
+ sections.push(parsedSection);
+ }, this);
+
+ App.store.loadMany(this.get("sectionModel"), sections);
+ parsedTab.sections = sections.mapProperty("id");
+ }
+
+ tabs.push(parsedTab);
+ }, this)
+ }
+
+ }, this);
+ }
+
+ /**
+ * create tie between <code>stackConfigProperty<code> and <code>subSection<code>
+ */
+ if (Em.get(json, "Theme.configuration.placement.configs")) {
+ Em.get(json, "Theme.configuration.placement.configs").forEach(function(configLink) {
+
+ var configId = this.getConfigId(configLink);
+ var subSectionId = configLink["subsection-name"];
+
+ var subSection = App.SubSection.find(subSectionId);
+ var configProperty = App.StackConfigProperty.find(configId);
+ if (configProperty && subSection) {
+ subSection.get('configProperties').pushObject(configProperty);
+ configProperty.set('subSection', subSection);
+ } else {
+ console.warn('there is no such property: ' + configId + '. Or subsection: ' + subSectionId);
+ }
+ }, this);
+ }
+
+ /**
+ * add widget object to <code>stackConfigProperty<code>
+ */
+ if (Em.get(json, "Theme.configuration.widgets")) {
+ Em.get(json, "Theme.configuration.widgets").forEach(function(widget) {
+ var configId = this.getConfigId(widget);
+
+ var configProperty = App.StackConfigProperty.find(configId);
+ if (configProperty) {
+ configProperty.set('widget', widget.widget);
+ } else {
+ console.warn('there is no such property: ' + configId);
+ }
+ }, this);
+ }
+ App.store.loadMany(this.get("tabModel"), tabs);
+ },
+
+ /**
+ * transform info from json to config id
+ * @param {Object} json
+ * @returns {string|null}
+ */
+ getConfigId: function(json) {
+ if (json && json.config && typeof json.config === "string") {
+ var split = json.config.split("/");
+ return split[1] + "_" + split[0];
+ } else {
+ console.warn('getConfigId: invalid input data');
+ return null;
+ }
+ },
+
+ /**
+ * generates Advanced tabs for selected or all services
+ * @param {[string]} [serviceNames=null]
+ */
+ generateAdvancedTabs: function(serviceNames) {
+ serviceNames = Em.isArray(serviceNames) ? serviceNames : App.StackService.find().mapProperty('serviceName');
+ var advancedTabs = [];
+ serviceNames.forEach(function(serviceName) {
+ advancedTabs.pushObject({
+ id: serviceName + '_advanced',
+ name: 'advanced',
+ display_name: 'Advanced',
+ is_advanced: true,
+ service_name: serviceName
+ });
+ });
+ App.store.loadMany(this.get("tabModel"), advancedTabs);
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index 361b099..c762a7f 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -64,4 +64,7 @@ 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
+require('models/configs/config_property');
+require('models/configs/tab');
+require('models/configs/section');
+require('models/configs/sub_section');
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/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
index 49cf3a2..6be05d8 100644
--- a/ambari-web/app/models/configs/config_property.js
+++ b/ambari-web/app/models/configs/config_property.js
@@ -18,7 +18,7 @@
var App = require('app');
-App.ConfigProperty = App.StackConfigProperty.extend({
+App.ConfigProperty = DS.Model.extend({
/**
* id is consist of property <code>name<code>+<code>fileName<code>+<code>configVersion.version<code>
@@ -33,10 +33,22 @@ App.ConfigProperty = App.StackConfigProperty.extend({
value: DS.attr('string'),
/**
+ * default value of property
+ * @property {string}
+ */
+ defaultValue: DS.attr('string'),
+
+ /**
* defines if property is final
* @property {boolean}
*/
- isFinal: DS.attr('boolean', {defaultValue: false}),
+ isFinal: DS.attr('boolean', {defaultValue: false}),
+
+ /**
+ * defines if property is final by default
+ * @property {boolean}
+ */
+ defaultIsFinal: DS.attr('boolean', {defaultValue: false}),
/**
* link to config version
@@ -45,6 +57,13 @@ App.ConfigProperty = App.StackConfigProperty.extend({
configVersion: DS.belongsTo('App.ConfigVersion'),
/**
+ * link to config version
+ * from this model we can get all static info about property
+ * @property {App.ConfigVersion}
+ */
+ stackConfigProperty: DS.belongsTo('App.StackConfigProperty'),
+
+ /**
* 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
@@ -84,12 +103,6 @@ App.ConfigProperty = App.StackConfigProperty.extend({
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}
*/
@@ -144,6 +157,23 @@ App.ConfigProperty = App.StackConfigProperty.extend({
}.property('configVersion.isDefault'),
/**
+ * defines if property is added by user
+ * @property {boolean}
+ */
+ isUserProperty: function() {
+ return Em.isNone(this.get('stackConfigProperty'));
+ }.property('stackConfigProperty'),
+
+ /**
+ * defines if this property is belongs to version
+ * with which we make comparison
+ * @property {boolean}
+ */
+ isForCompare: function() {
+ return this.get('configVersion.isForCompare');
+ }.property('configVersion.isForCompare'),
+
+ /**
* Indicates when value is not the default value.
* Returns false when there is no default value.
* @type {boolean}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/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
index 29bc52b..4acb664 100644
--- a/ambari-web/app/models/configs/config_version.js
+++ b/ambari-web/app/models/configs/config_version.js
@@ -20,7 +20,15 @@
var App = require('app');
App.ConfigVersion = App.ServiceConfigVersion.extend({
- configProperties: DS.hasMany('App.ConfigProperty')
+ configProperties: DS.hasMany('App.ConfigProperty'),
+
+ /**
+ * this flag is true when we compare some version with
+ * this config version
+ * this flag make influence on displaying properties
+ * @property {boolean} [isForCompare=false]
+ */
+ isForCompare: DS.attr('boolean', {defaultValue: false})
});
App.ConfigVersion.FIXTURES = [];
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/models/configs/section.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/section.js b/ambari-web/app/models/configs/section.js
new file mode 100644
index 0000000..d78cfea
--- /dev/null
+++ b/ambari-web/app/models/configs/section.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.Section = DS.Model.extend({
+ id: DS.attr('string'),
+ name: DS.attr('string'),
+ displayName: DS.attr('string'),
+ rowIndex: DS.attr('number', {defaultValue: 1}),
+ rowSpan: DS.attr('number', {defaultValue: 1}),
+ columnIndex: DS.attr('number', {defaultValue: 1}),
+ columnSpan: DS.attr('number', {defaultValue: 1}),
+ sectionColumns: DS.attr('number', {defaultValue: 1}),
+ sectionRows: DS.attr('number', {defaultValue: 1}),
+ subSections: DS.hasMany('App.SubSection'),
+ tab: DS.belongsTo('App.Tab')
+});
+
+
+App.Section.FIXTURES = [];
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/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
index 7a29fac..4a87b36 100644
--- a/ambari-web/app/models/configs/stack_config_property.js
+++ b/ambari-web/app/models/configs/stack_config_property.js
@@ -147,7 +147,13 @@ App.StackConfigProperty = DS.Model.extend({
* }
* @property {object}
*/
- valueAttributes: DS.attr('object', {defaultValue: null})
+ valueAttributes: DS.attr('object', {defaultValue: null}),
+
+ /**
+ * sub section to which belongs this property
+ * @property {App.SubSection}
+ */
+ subSection: DS.belongsTo('App.SubSection')
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/models/configs/sub_section.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/sub_section.js b/ambari-web/app/models/configs/sub_section.js
new file mode 100644
index 0000000..648aae3
--- /dev/null
+++ b/ambari-web/app/models/configs/sub_section.js
@@ -0,0 +1,36 @@
+/**
+ * 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.SubSection = DS.Model.extend({
+ id: DS.attr('string'),
+ name: DS.attr('string'),
+ displayName: DS.attr('string'),
+ border: DS.attr('boolean', {defaultValue: true}),
+ rowIndex: DS.attr('number', {defaultValue: 1}),
+ columnIndex: DS.attr('number', {defaultValue: 1}),
+ rowSpan: DS.attr('number', {defaultValue: 1}),
+ columnSpan: DS.attr('number', {defaultValue: 1}),
+ section: DS.belongsTo('App.Section'),
+ configProperties: DS.hasMany('App.StackConfigProperty')
+});
+
+
+App.SubSection.FIXTURES = [];
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/models/configs/tab.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/tab.js b/ambari-web/app/models/configs/tab.js
new file mode 100644
index 0000000..0365ffb
--- /dev/null
+++ b/ambari-web/app/models/configs/tab.js
@@ -0,0 +1,34 @@
+/**
+ * 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.Tab = DS.Model.extend({
+ id: DS.attr('string'),
+ name: DS.attr('string'),
+ displayName: DS.attr('string'),
+ columns: DS.attr('number', {defaultValue: 1}),
+ rows: DS.attr('number', {defaultValue: 1}),
+ isAdvanced: DS.attr('boolean', {defaultValue: false}),
+ serviceName: DS.attr('string'),
+ sections: DS.hasMany('App.Section')
+});
+
+
+App.Tab.FIXTURES = [];
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 66136de..66353fb 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -603,7 +603,13 @@ var urls = {
}
}
},
+ /*************************CONFIG THEME****************************************/
+ 'configs.theme': {
+ 'real': '{stackVersionUrl}/services/{serviceName}/artifacts/theme',
+ 'mock': '/data/configurations/theme.json'
+ },
+
/*************************CONFIG GROUPS***************************************/
'configs.config_groups.load.all': {
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 1e96bb6..91ae72d 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -1910,38 +1910,37 @@ App.config = Em.Object.create({
/**
* load config groups
- * @param {String} serviceName
- * @param {Number} configGroupId
+ * @param {string} [serviceName=null]
+ * @param {number} [configGroupId=null]
+ * @param {number} [configVersion=null]
+ * @param {boolean} [isForCompare=false]
* @returns {$.ajax}
* @method loadConfigGroups
*/
- loadConfigVersions: function (serviceName, configGroupId, configVersion) {
- var info = this.generateAjaxDataForVersions(serviceName, configGroupId, configVersion);
- return App.ajax.send({
- name: info.name,
- sender: this,
- data: info.data,
- success: 'saveConfigVersionsToModel'
- });
+ loadConfigVersions: function (serviceName, configGroupId, configVersion, isForCompare) {
+ var info = this.generateAjaxDataForVersions(serviceName, configGroupId, configVersion, isForCompare);
+ return App.ajax.send($.extend({sender: this, success: 'saveConfigVersionsToModel'}, info));
},
/**
* generate ajax info
- * @param serviceName
- * @param configGroupId
- * @param configVersion
+ * @param {string} [serviceName=null]
+ * @param {number} [configGroupId=null]
+ * @param {number} [configVersion=null]
+ * @param {boolean} [isForCompare=false]
* @returns {{name: string, data: {}}}
*/
- generateAjaxDataForVersions: function (serviceName, configGroupId, configVersion) {
+ generateAjaxDataForVersions: function (serviceName, configGroupId, configVersion, isForCompare) {
var result = {
name: 'configs.config_versions.load.all.min',
data: {}
- }
+ };
if (serviceName) {
result.data.serviceName = serviceName;
if (configVersion) {
result.name = 'configs.config_versions.load';
- result.data.configVersion = configVersion
+ result.data.configVersion = configVersion;
+ result.data.isForCompare = isForCompare;
} else if (configGroupId) {
result.name = 'configs.config_versions.load.group';
result.data.configGroupId = configGroupId;
@@ -1958,7 +1957,31 @@ App.config = Em.Object.create({
* @param opt
* @param params
*/
- saveConfigVersionsToModel: function (data) {
- App.configVersionsMapper.map(data);
+ saveConfigVersionsToModel: function (data, opt, params) {
+ App.configVersionsMapper.map(data, params.isForCompare);
+ },
+
+ /**
+ * load config themes
+ * @param {string} serviceName
+ * @returns {$.ajax}
+ */
+ loadConfigTheme: function(serviceName) {
+ return App.ajax.send({
+ name: 'configs.theme',
+ sender: this,
+ data: {
+ serviceName: serviceName
+ },
+ success: 'saveThemeToModel'
+ });
+ },
+
+ /**
+ * runs <code>themeMapper<code>
+ * @param data
+ */
+ saveThemeToModel: function(data) {
+ App.themesMapper.map(data);
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/app/views/common/configs/service_config_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/service_config_view.js b/ambari-web/app/views/common/configs/service_config_view.js
index ec11fe5..fc58b48 100644
--- a/ambari-web/app/views/common/configs/service_config_view.js
+++ b/ambari-web/app/views/common/configs/service_config_view.js
@@ -85,43 +85,13 @@ App.ServiceConfigView = Em.View.extend({
'App.router.wizardStep7Controller.selectedConfigGroup.name'
),
- // TODO remove workaround for `Advanced` tab after Tab model implementation
- /**
- * Create `Advanced` tab which is not related to fancy tab section.
- * This tab contains properties without widgets.
- *
- * @returns {Ember.Object}
- */
- getAdvancedTab: function() {
- var tabId = 'advanced-' + this.get('controller.selectedService.serviceName').toLowerCase() + '-tab';
- return this.createTabObject(Em.Object.create({
- id: tabId,
- name: Em.I18n.t('common.advanced')
- }));
- },
-
- /**
- * @param {Ember.Object} model
- * @returns {Ember.Object}
- */
- createTabObject: function(model) {
- return Em.Object.create({
- id: model.get('id'),
- displayName: model.get('name'),
- tabClassName: '.' + model.get('id'),
- isAdvanced: model.get('name') == Em.I18n.t('common.advanced')
- });
- },
-
/**
* Object that used for Twitter Bootstrap tabs markup.
*
* @returns {Ember.A}
*/
tabs: function() {
- var tabs = Em.A([]);
- // filter Tab models by service name and create object here
- tabs.pushObject(this.getAdvancedTab());
+ var tabs = App.Tab.find();
// make first tab active
tabs.get('firstObject').set('isActive', true);
return tabs;
http://git-wip-us.apache.org/repos/asf/ambari/blob/ea1d531b/ambari-web/test/mappers/configs/themes_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/configs/themes_mapper_test.js b/ambari-web/test/mappers/configs/themes_mapper_test.js
new file mode 100644
index 0000000..195a62f
--- /dev/null
+++ b/ambari-web/test/mappers/configs/themes_mapper_test.js
@@ -0,0 +1,225 @@
+/**
+ * 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('mappers/configs/themes_mapper');
+require('models/configs/tab');
+require('models/configs/section');
+require('models/configs/sub_section');
+require('models/configs/stack_config_property');
+
+describe('App.themeMapper', function () {
+
+ beforeEach(function () {
+ App.resetDsStoreTypeMap(App.Tab);
+ App.resetDsStoreTypeMap(App.Section);
+ App.resetDsStoreTypeMap(App.SubSection);
+ App.resetDsStoreTypeMap(App.StackConfigProperty);
+ sinon.stub(App.store, 'commit', Em.K);
+ });
+ afterEach(function () {
+ App.store.commit.restore();
+ });
+
+ describe("#map", function () {
+
+ var json = {
+ "Theme": {
+ "service_name": "HDFS",
+ "name": "default",
+ "description": "Default theme for HDFS service",
+ "configuration": {
+ "layouts": [
+ {
+ "name": "default",
+ "tabs": [
+ {
+ "name": "settings",
+ "display-name": "Settings",
+ "layout": {
+ "tab-columns": "2",
+ "tab-rows": "1",
+ "sections": [
+ {
+ "name": "Section-1",
+ "display-name": "Section One",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1",
+ "section-columns": "2",
+ "section-rows": "3",
+ "subsections": [
+ {
+ "name": "subsection1",
+ "display-name": "Storage",
+ "border": "false",
+ "row-index": "0",
+ "column-index": "0",
+ "column-span": "1",
+ "row-span": "1"
+ }
+ ]
+ },
+ {
+ "name": "Section-2",
+ "display-name": "Section Two",
+ "row-index": "0",
+ "column-index": "1"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "placement": {
+ "configuration-layout": "default",
+ "configs": [
+ {
+ "config": "c1/p1",
+ "subsection-name": "subsection1"
+ },
+ {
+ "config": "c1/p2",
+ "subsection-name": "subsection1"
+ }
+ ]
+ },
+ "widgets": [
+ {
+ "config": "c1/p1",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ },
+ {
+ "unit-name": "GB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "c1/p2",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "percent"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ };
+
+ it('should map theme data', function () {
+
+ App.StackConfigProperty.createRecord({id: 'p1_c1'});
+ App.StackConfigProperty.createRecord({id: 'p2_c1'});
+
+ App.themesMapper.map(json);
+
+ expect(App.Tab.find().get('length')).to.equal(1);
+ expect(App.Section.find().get('length')).to.equal(2);
+ expect(App.SubSection.find().get('length')).to.equal(1);
+
+ //checking tab
+ expect(App.Tab.find('HDFS_settings').toJSON()).to.eql({
+ id: 'HDFS_settings',
+ name: 'settings',
+ display_name: 'Settings',
+ columns: "2",
+ rows: "1",
+ is_advanced: false,
+ service_name: 'HDFS'
+ });
+
+ //checking section
+ expect(App.Tab.find('HDFS_settings').get('sections').objectAt(0).toJSON()).to.eql({
+ "id": "Section-1",
+ "name": "Section-1",
+ "display_name": "Section One",
+ "row_index": "0",
+ "row_span": "1",
+ "column_index": "0",
+ "column_span": "1",
+ "section_columns": "2",
+ "section_rows": "3",
+ "tab_id": "HDFS_settings"
+ });
+
+ //checking subsection
+ expect(App.Tab.find('HDFS_settings').get('sections').objectAt(0).get('subSections').objectAt(0).toJSON()).to.eql({
+ "id": "subsection1",
+ "name": "subsection1",
+ "display_name": "Storage",
+ "border": "false",
+ "row_index": "0",
+ "row_span": "1",
+ "column_index": "0",
+ "column_span": "1",
+ "section_id": "Section-1"
+ });
+
+ //checking stack config object
+ var config = App.Tab.find('HDFS_settings').get('sections').objectAt(0).get('subSections').objectAt(0).get('configProperties').objectAt(0);
+ expect(config.get('id')).to.eql("p1_c1");
+ expect(config.get('subSection.id')).to.eql("subsection1");
+ expect(config.get('widget')).to.eql({
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ },
+ {
+ "unit-name": "GB"
+ }
+ ]
+ });
+ });
+ });
+
+ describe('generateAdvancedTabs', function () {
+ it('generates advanced tabs', function () {
+ App.themesMapper.generateAdvancedTabs(['HDFS']);
+ expect(App.Tab.find('HDFS_advanced').toJSON()).to.eql({
+ "id": "HDFS_advanced",
+ "name": "advanced",
+ "display_name": "Advanced",
+ "columns": 1,
+ "rows": 1,
+ "is_advanced": true,
+ "service_name": "HDFS"
+ });
+ });
+ });
+
+ describe('getConfigId', function () {
+ it('gets configs id from json', function () {
+ expect(App.themesMapper.getConfigId({config: "c1/p1"})).to.equal("p1_c1");
+ });
+ it('returns null as data is invalid', function () {
+ expect(App.themesMapper.getConfigId({configs: "c1/p1"})).to.equal(null);
+ });
+ });
+});