You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2015/03/23 20:03:14 UTC

ambari git commit: AMBARI-10146. Create views for showing theme tabs inside service-configs (Buzhor Denys via srimanth)

Repository: ambari
Updated Branches:
  refs/heads/trunk f54d75b8b -> 34a89e8b1


AMBARI-10146. Create views for showing theme tabs inside service-configs (Buzhor Denys via srimanth)


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

Branch: refs/heads/trunk
Commit: 34a89e8b16603707ba32b8d1829dae9fb020c0f4
Parents: f54d75b
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Mon Mar 23 12:01:18 2015 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Mon Mar 23 12:01:18 2015 -0700

----------------------------------------------------------------------
 .../app/assets/data/configurations/theme.json   | 364 +++++++++++--------
 .../data/configurations/theme_services.json     | 247 +++++++++++++
 .../controllers/global/cluster_controller.js    |   4 +
 ambari-web/app/controllers/installer.js         |  10 +-
 .../controllers/main/service/add_controller.js  |   8 +-
 .../controllers/main/service/info/configs.js    |   5 +-
 ambari-web/app/controllers/wizard.js            |  29 ++
 ambari-web/app/mappers/configs/themes_mapper.js |  19 +-
 ambari-web/app/models/configs/tab.js            |  12 +-
 ambari-web/app/routes/installer.js              |   1 +
 ambari-web/app/styles/application.less          |   5 +
 .../templates/common/configs/service_config.hbs |  42 +--
 .../configs/service_config_layout_tab.hbs       |  38 ++
 .../common/configs/service_config_wizard.hbs    |  34 +-
 ambari-web/app/utils/ajax/ajax.js               |   7 +-
 ambari-web/app/utils/config.js                  |  36 +-
 ambari-web/app/views.js                         |   1 +
 .../configs/service_config_layout_tab_view.js   |  23 ++
 .../views/common/configs/service_config_view.js |  44 ++-
 .../main/service/info/config_test.js            |   7 +
 .../test/mappers/configs/themes_mapper_test.js  | 125 ++++---
 21 files changed, 782 insertions(+), 279 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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
index b756230..a5c778f 100644
--- a/ambari-web/app/assets/data/configurations/theme.json
+++ b/ambari-web/app/assets/data/configurations/theme.json
@@ -1,174 +1,232 @@
 {
-  "Theme": {
-    "name": "default",
-    "service_name": "YARN",
-    "description": "Default theme for YARN service",
-    "configuration": {
-      "layouts": [
+  "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/YARN/artifacts/theme",
+  "Artifacts" : {
+    "artifact_name" : "theme",
+    "service_name" : "YARN",
+    "stack_name" : "HDP",
+    "stack_version" : "2.2"
+  },
+  "artifact_data" : {
+    "Theme" : {
+      "description" : "Default theme for YARN service",
+      "name" : "default",
+      "widgets" : [
         {
-          "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": []
-                  }
-                ]
+          "config" : "yarn-site/yarn.nodemanager.resource.memory-mb",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "MB"
               }
-            }
-          ]
-        }
-      ]
-    },
-    "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-site/yarn.nodemanager.vmem-pmem-ratio",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "float"
+              }
+            ]
+          }
         },
         {
-          "config": "yarn.nodemanager.resource.percentage-physical-cpu-limit",
-          "section-name": "section-nm-sizing"
+          "config" : "yarn-site/yarn.nodemanager.resource.percentage-physical-cpu-limit",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "percent"
+              }
+            ]
+          }
         },
         {
-          "config": "yarn.nodemanager.resource.cpu-vcores",
-          "section-name": "section-nm-sizing"
+          "config" : "yarn-site/yarn.nodemanager.resource.cpu-vcores",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "int"
+              }
+            ]
+          }
         },
         {
-          "config": "yarn.scheduler.minimum-allocation-mb",
-          "section-name": "section-scheduler-defaults"
+          "config" : "yarn-site/yarn.scheduler.minimum-allocation-mb",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "MB"
+              }
+            ]
+          }
         },
         {
-          "config": "yarn.scheduler.maximum-allocation-mb",
-          "section-name": "section-scheduler-defaults"
+          "config" : "yarn-site/yarn.scheduler.maximum-allocation-mb",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "MB"
+              }
+            ]
+          }
         },
         {
-          "config": "yarn.scheduler.minimum-allocation-vcores",
-          "section-name": "section-scheduler-defaults"
+          "config" : "yarn-site/yarn.scheduler.minimum-allocation-vcores",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "int"
+              }
+            ]
+          }
         },
         {
-          "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-site/yarn.scheduler.maximum-allocation-vcores",
+          "widget" : {
+            "type" : "slider",
+            "units" : [
+              {
+                "unit-name" : "int"
+              }
+            ]
+          }
         }
+      ],
+      "configuration" : {
+        "layouts" : [
+          {
+            "name" : "default",
+            "tabs" : [
+              {
+                "name" : "settings",
+                "display-name" : "Settings",
+                "layout" : {
+                  "tab-columns" : "3",
+                  "tab-rows" : "2",
+                  "sections" : [
+                    {
+                      "name" : "section-nm-sizing",
+                      "display-name" : "NodeManager Sizing",
+                      "row-index" : "0",
+                      "column-index" : "0",
+                      "row-span" : "1",
+                      "column-span" : "2",
+                      "section-columns" : "2",
+                      "section-rows" : "1",
+                      "subsections" : [
+                        {
+                          "name" : "subsection-nm-sizing-col1",
+                          "row-index" : "0",
+                          "column-index" : "0",
+                          "row-span" : "1",
+                          "column-span" : "1"
+                        },
+                        {
+                          "name" : "subsection-nm-sizing-col2",
+                          "row-index" : "0",
+                          "column-index" : "1",
+                          "row-span" : "1",
+                          "column-span" : "1"
+                        }
+                      ]
+                    },
+                    {
+                      "name" : "section-yarn-platform-features",
+                      "display-name" : "YARN Platform Features",
+                      "row-index" : "0",
+                      "column-index" : "1",
+                      "row-span" : "1",
+                      "column-span" : "1",
+                      "section-columns" : "1",
+                      "section-rows" : "1",
+                      "subsections" : [
+                        {
+                          "name" : "subsection-yarn-platform-features-col1",
+                          "row-index" : "0",
+                          "column-index" : "0",
+                          "row-span" : "1",
+                          "column-span" : "1"
+                        }
+                      ]
+                    },
+                    {
+                      "name" : "section-container-sizing",
+                      "display-name" : "Container Sizing",
+                      "row-index" : "1",
+                      "column-index" : "0",
+                      "row-span" : "1",
+                      "column-span" : "2",
+                      "section-columns" : "2",
+                      "section-rows" : "1",
+                      "subsections" : [
+                        {
+                          "name" : "subsection-container-sizing-col1",
+                          "row-index" : "0",
+                          "column-index" : "0",
+                          "row-span" : "1",
+                          "column-span" : "1"
+                        },
+                        {
+                          "name" : "subsection-container-sizing-col2",
+                          "row-index" : "0",
+                          "column-index" : "1",
+                          "row-span" : "1",
+                          "column-span" : "1"
+                        }
+                      ]
+                    }
+                  ]
+                }
+              }
+            ]
+          }
+        ]
       },
-      {
-        "config":"yarn.scheduler.maximum-allocation-vcores",
-        "widget":{
-          "type":"slider",
-          "units":[
-            {
-              "unit-name":"int"
-            }
-          ]
-        }
+      "placement" : {
+        "configs" : [
+          {
+            "config" : "yarn-site/yarn.nodemanager.resource.memory-mb",
+            "subsection-name" : "subsection-nm-sizing-col1"
+          },
+          {
+            "config" : "yarn-site/yarn.nodemanager.vmem-pmem-ratio",
+            "subsection-name" : "subsection-nm-sizing-col1"
+          },
+          {
+            "config" : "yarn-site/yarn.nodemanager.resource.percentage-physical-cpu-limit",
+            "subsection-name" : "subsection-nm-sizing-col2"
+          },
+          {
+            "config" : "yarn-site/yarn.nodemanager.resource.cpu-vcores",
+            "subsection-name" : "subsection-nm-sizing-col2"
+          },
+          {
+            "config" : "yarn-site/yarn.scheduler.minimum-allocation-mb",
+            "subsection-name" : "subsection-container-sizing-col1"
+          },
+          {
+            "config" : "yarn-site/yarn.scheduler.maximum-allocation-mb",
+            "subsection-name" : "subsection-container-sizing-col1"
+          },
+          {
+            "config" : "yarn-site/yarn.scheduler.minimum-allocation-vcores",
+            "subsection-name" : "subsection-container-sizing-col2"
+          },
+          {
+            "config" : "yarn-site/yarn.scheduler.maximum-allocation-vcores",
+            "subsection-name" : "subsection-container-sizing-col2"
+          }
+        ],
+        "configuration-layout" : "default"
       }
-    ]
+    }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/assets/data/configurations/theme_services.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/configurations/theme_services.json b/ambari-web/app/assets/data/configurations/theme_services.json
new file mode 100644
index 0000000..7a200f4
--- /dev/null
+++ b/ambari-web/app/assets/data/configurations/theme_services.json
@@ -0,0 +1,247 @@
+{
+  "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services?StackServices/service_name.in(YARN)&artifacts/Artifacts/artifact_name=theme&fields=artifacts/*",
+  "items" : [
+    {
+      "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/YARN",
+      "StackServices" : {
+        "service_name" : "YARN",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2"
+      },
+      "artifacts" : [
+        {
+          "href" : "http://c6401.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/YARN/artifacts/theme",
+          "Artifacts" : {
+            "artifact_name" : "theme",
+            "service_name" : "YARN",
+            "stack_name" : "HDP",
+            "stack_version" : "2.2"
+          },
+          "artifact_data" : {
+            "Theme" : {
+              "description" : "Default theme for YARN service",
+              "name" : "default",
+              "widgets" : [
+                {
+                  "config" : "yarn-site/yarn.nodemanager.resource.memory-mb",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "MB"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.nodemanager.vmem-pmem-ratio",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "float"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.nodemanager.resource.percentage-physical-cpu-limit",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "percent"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.nodemanager.resource.cpu-vcores",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "int"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.scheduler.minimum-allocation-mb",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "MB"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.scheduler.maximum-allocation-mb",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "MB"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.scheduler.minimum-allocation-vcores",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "int"
+                      }
+                    ]
+                  }
+                },
+                {
+                  "config" : "yarn-site/yarn.scheduler.maximum-allocation-vcores",
+                  "widget" : {
+                    "type" : "slider",
+                    "units" : [
+                      {
+                        "unit-name" : "int"
+                      }
+                    ]
+                  }
+                }
+              ],
+              "configuration" : {
+                "layouts" : [
+                  {
+                    "name" : "default",
+                    "tabs" : [
+                      {
+                        "name" : "settings",
+                        "display-name" : "Settings",
+                        "layout" : {
+                          "tab-columns" : "3",
+                          "tab-rows" : "2",
+                          "sections" : [
+                            {
+                              "name" : "section-nm-sizing",
+                              "display-name" : "NodeManager Sizing",
+                              "row-index" : "0",
+                              "column-index" : "0",
+                              "row-span" : "1",
+                              "column-span" : "2",
+                              "section-columns" : "2",
+                              "section-rows" : "1",
+                              "subsections" : [
+                                {
+                                  "name" : "subsection-nm-sizing-col1",
+                                  "row-index" : "0",
+                                  "column-index" : "0",
+                                  "row-span" : "1",
+                                  "column-span" : "1"
+                                },
+                                {
+                                  "name" : "subsection-nm-sizing-col2",
+                                  "row-index" : "0",
+                                  "column-index" : "1",
+                                  "row-span" : "1",
+                                  "column-span" : "1"
+                                }
+                              ]
+                            },
+                            {
+                              "name" : "section-yarn-platform-features",
+                              "display-name" : "YARN Platform Features",
+                              "row-index" : "0",
+                              "column-index" : "1",
+                              "row-span" : "1",
+                              "column-span" : "1",
+                              "section-columns" : "1",
+                              "section-rows" : "1",
+                              "subsections" : [
+                                {
+                                  "name" : "subsection-yarn-platform-features-col1",
+                                  "row-index" : "0",
+                                  "column-index" : "0",
+                                  "row-span" : "1",
+                                  "column-span" : "1"
+                                }
+                              ]
+                            },
+                            {
+                              "name" : "section-container-sizing",
+                              "display-name" : "Container Sizing",
+                              "row-index" : "1",
+                              "column-index" : "0",
+                              "row-span" : "1",
+                              "column-span" : "2",
+                              "section-columns" : "2",
+                              "section-rows" : "1",
+                              "subsections" : [
+                                {
+                                  "name" : "subsection-container-sizing-col1",
+                                  "row-index" : "0",
+                                  "column-index" : "0",
+                                  "row-span" : "1",
+                                  "column-span" : "1"
+                                },
+                                {
+                                  "name" : "subsection-container-sizing-col2",
+                                  "row-index" : "0",
+                                  "column-index" : "1",
+                                  "row-span" : "1",
+                                  "column-span" : "1"
+                                }
+                              ]
+                            }
+                          ]
+                        }
+                      }
+                    ]
+                  }
+                ]
+              },
+              "placement" : {
+                "configs" : [
+                  {
+                    "config" : "yarn-site/yarn.nodemanager.resource.memory-mb",
+                    "subsection-name" : "subsection-nm-sizing-col1"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.nodemanager.vmem-pmem-ratio",
+                    "subsection-name" : "subsection-nm-sizing-col1"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.nodemanager.resource.percentage-physical-cpu-limit",
+                    "subsection-name" : "subsection-nm-sizing-col2"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.nodemanager.resource.cpu-vcores",
+                    "subsection-name" : "subsection-nm-sizing-col2"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.scheduler.minimum-allocation-mb",
+                    "subsection-name" : "subsection-container-sizing-col1"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.scheduler.maximum-allocation-mb",
+                    "subsection-name" : "subsection-container-sizing-col1"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.scheduler.minimum-allocation-vcores",
+                    "subsection-name" : "subsection-container-sizing-col2"
+                  },
+                  {
+                    "config" : "yarn-site/yarn.scheduler.maximum-allocation-vcores",
+                    "subsection-name" : "subsection-container-sizing-col2"
+                  }
+                ],
+                "configuration-layout" : "default"
+              }
+            }
+          }
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index f3839c1..f17364d 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -281,6 +281,10 @@ App.ClusterController = Em.Controller.extend({
 
         updater.updateServiceMetric(function () {
           App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName'));
+          if (App.get('supports.enhancedConfigs')) {
+            App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName'));
+          }
+
           updater.updateComponentConfig(function () {
             self.updateLoadStatus('componentConfigs');
           });

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index 26f6ac4..f1a0720 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -656,18 +656,13 @@ App.InstallerController = App.WizardController.extend({
     ],
     '7': [
       {
-        type: 'sync',
+        type: 'async',
         callback: function () {
-          if (App.get('supports.enhancedConfigs')) {
-            var serviceNames = App.StackService.find().filter(function(s) {
-              return s.get('isSelected');
-            }).mapProperty('serviceName');
-            App.themesMapper.generateAdvancedTabs(serviceNames);
-          }
           this.loadServiceConfigGroups();
           this.loadServiceConfigProperties();
           this.loadCurrentHostGroups();
           this.loadRecommendationsConfigs();
+          return this.loadConfigThemes();
         }
       }
     ]
@@ -714,4 +709,3 @@ App.InstallerController = App.WizardController.extend({
     }
   }
 });
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/controllers/main/service/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/add_controller.js b/ambari-web/app/controllers/main/service/add_controller.js
index 87c1700..d3d3a37 100644
--- a/ambari-web/app/controllers/main/service/add_controller.js
+++ b/ambari-web/app/controllers/main/service/add_controller.js
@@ -119,11 +119,15 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
               var serviceNames = App.StackService.find().filter(function(s) {
                 return s.get('isSelected') || s.get('isInstalled');
               }).mapProperty('serviceName');
-              App.themesMapper.generateAdvancedTabs(serviceNames);
+              self.loadConfigThemes().then(function() {
+                dfd.resolve();
+              });
+            }
+            else {
+              dfd.resolve();
             }
             self.loadServiceConfigGroups();
             self.loadServiceConfigProperties();
-            dfd.resolve();
           });
           return dfd.promise();
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 1552505..0314afc 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -254,8 +254,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
    */
   loadStep: function () {
     console.log("TRACE: Loading configure for service");
+    var self = this;
     if (App.get('supports.enhancedConfigs')) {
-      App.themesMapper.generateAdvancedTabs([this.get('content.serviceName')]);
+      App.config.loadConfigTheme(this.get('content.serviceName')).then(function() {
+        App.themesMapper.generateAdvancedTabs([self.get('content.serviceName')]);
+      });
     }
     this.clearStep();
     this.loadClusterEnvSite();

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index bebf1d6..dd1ea41 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -1148,5 +1148,34 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     if (this.get('content.skipSlavesStep')) {
       this.get('isStepDisabled').findProperty('step', step).set('value', this.get('content.skipSlavesStep'));
     }
+  },
+
+  /**
+   * Load config themes for enhanced config layout.
+   *
+   * @method loadConfigThemes
+   * @return {$.Deferred}
+   */
+   loadConfigThemes: function() {
+    var self = this;
+    var dfd = $.Deferred();
+    if (App.get('supports.enhancedConfigs') && !this.get('stackConfigsLoaded')) {
+      var serviceNames = App.StackService.find().filter(function(s) {
+        return s.get('isSelected') || s.get('isInstalled');
+      }).mapProperty('serviceName');
+      // Load stack configs before loading themes
+      App.config.loadConfigsFromStack(serviceNames).done(function() {
+        App.config.loadConfigThemeForServices(serviceNames).always(function() {
+          self.set('stackConfigsLoaded', true);
+          App.themesMapper.generateAdvancedTabs(serviceNames);
+          dfd.resolve();
+        });
+      });
+    }
+    else {
+      dfd.resolve();
+      this.set('stackConfigsLoaded', true);
+    }
+    return dfd.promise();
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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
index 62f4d31..48ee991 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -8,7 +8,6 @@
  * 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.
@@ -61,9 +60,9 @@ App.themesMapper = App.QuickDataMapper.create({
 
   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 (Em.get(json, "artifact_data.Theme.configuration.layouts")) {
+      var serviceName = Em.get(json, "Artifacts.service_name");
+      Em.get(json, "artifact_data.Theme.configuration.layouts").forEach(function(layout) {
 
         if (layout.tabs) {
           layout.tabs.forEach(function(tab) {
@@ -97,17 +96,17 @@ App.themesMapper = App.QuickDataMapper.create({
             }
 
             tabs.push(parsedTab);
-          }, this)
+          }, this);
         }
 
       }, this);
     }
-
+    // TODO  Foreign key reference below throw some unclear error
     /**
      * 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) {
+    if (Em.get(json, "artifact_data.Theme.placement.configs")) {
+      Em.get(json, "artifact_data.Theme.placement.configs").forEach(function(configLink) {
 
         var configId = this.getConfigId(configLink);
         var subSectionId = configLink["subsection-name"];
@@ -126,8 +125,8 @@ App.themesMapper = App.QuickDataMapper.create({
     /**
      * add widget object to <code>stackConfigProperty<code>
      */
-    if (Em.get(json, "Theme.configuration.widgets")) {
-      Em.get(json, "Theme.configuration.widgets").forEach(function(widget) {
+    if (Em.get(json, "artifact_data.Theme.widgets")) {
+      Em.get(json, "artifact_data.Theme.widgets").forEach(function(widget) {
         var configId = this.getConfigId(widget);
 
         var configProperty = App.StackConfigProperty.find(configId);

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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
index 0365ffb..1396f34 100644
--- a/ambari-web/app/models/configs/tab.js
+++ b/ambari-web/app/models/configs/tab.js
@@ -26,9 +26,17 @@ App.Tab = DS.Model.extend({
   rows: DS.attr('number', {defaultValue: 1}),
   isAdvanced: DS.attr('boolean', {defaultValue: false}),
   serviceName: DS.attr('string'),
-  sections: DS.hasMany('App.Section')
+  sections: DS.hasMany('App.Section'),
+  /**
+   * Class name used for tab switching
+   *
+   * @type {String}
+   * @property headingClass
+   */
+  headingClass: function() {
+    return '.' + this.get('id');
+  }.property('id')
 });
 
 
 App.Tab.FIXTURES = [];
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/routes/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index 04b2dc0..7af829f 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -235,6 +235,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         servicesMasters: [],
         isInitialLayout: true
       });
+      controller.set('stackConfigsLoaded', false);
       controller.setCurrentStep('5');
       controller.loadAllPriorSteps().done(function () {
         controller.connectOutlet('wizardStep5', controller.get('content'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 0466f59..e102f9e 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -5550,4 +5550,9 @@ input[type="checkbox"].align-checkbox {
     left: 45%;
     position: absolute;
   }
+}
+
+.config-section, .config-sub-section {
+  width: 100%;
+  height: 100%;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/templates/common/configs/service_config.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config.hbs b/ambari-web/app/templates/common/configs/service_config.hbs
index 120a985..6ec3d85 100644
--- a/ambari-web/app/templates/common/configs/service_config.hbs
+++ b/ambari-web/app/templates/common/configs/service_config.hbs
@@ -86,29 +86,29 @@
   {{#if view.supportsConfigLayout}}
     <ul class="nav nav-tabs">
       {{#each tab in view.tabs}}
-        <li {{bindAttr class="tab.isActive:active" }}><a href="#" {{bindAttr data-target="tab.className"}} data-toggle="tab">{{tab.displayName}}</a></li>
+        <li {{bindAttr class="tab.isActive:active" }}><a href="#" {{bindAttr data-target="tab.headingClass"}} data-toggle="tab">{{tab.displayName}}</a></li>
       {{/each}}
     </ul>
-
-    {{#each tab in view.tabs}}
-      <div {{bindAttr class=":tab-pane tab.isActive:active tab.id"}}>
-        {{#if tab.isAdvanced}}
-          {{#each category in selectedService.configCategories}}
-            <div class="accordion">
-              {{#if category.isCustomView}}
-                {{view category.customView categoryBinding="category" serviceBinding="selectedService" canEditBinding="view.canEdit" serviceConfigsBinding="selectedService.configs"}}
-              {{else}}
-                {{view App.ServiceConfigsByCategoryView categoryBinding="category" canEditBinding="view.canEdit" serviceBinding="selectedService" serviceConfigsBinding="selectedService.configs" supportsHostOverridesBinding="view.supportsHostOverrides"}}
-              {{/if}}
-            </div>
-          {{/each}}
-        {{else}}
-          {{!
-            @TODO Fancy Config view goes here
-            }}
-        {{/if}}
-      </div>
-    {{/each}}
+    <div class="tab-content">
+      {{#each tab in view.tabs}}
+        <div {{bindAttr class=":tab-pane tab.isActive:active tab.id"}}>
+          {{#if tab.isAdvanced}}
+            {{#each category in selectedService.configCategories}}
+              <div class="accordion">
+                {{#if category.isCustomView}}
+                  {{view category.customView categoryBinding="category" serviceBinding="selectedService" canEditBinding="view.canEdit" serviceConfigsBinding="selectedService.configs"}}
+                {{else}}
+                  {{view App.ServiceConfigsByCategoryView categoryBinding="category" canEditBinding="view.canEdit" serviceBinding="selectedService" serviceConfigsBinding="selectedService.configs" supportsHostOverridesBinding="view.supportsHostOverrides"}}
+                {{/if}}
+              </div>
+            {{/each}}
+          {{else}}
+            {{! Render Enhanced Config Section }}
+            {{view App.ServiceConfigLayoutTabView contentBinding="tab"}}
+          {{/if}}
+        </div>
+      {{/each}}
+    </div>
   {{else}}
     {{#each category in selectedService.configCategories}}
       <div class="accordion">

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
new file mode 100644
index 0000000..bd27107
--- /dev/null
+++ b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
@@ -0,0 +1,38 @@
+{{!
+* 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.
+}}
+
+<table class="config-section" border="1">
+  {{#each row in tab.sectionRows}}
+    <tr>
+      {{#each section in row}}
+      <td {{bindAttr colspan="section.columnSpan" rowspan="section.rowSpan"}}>
+        {{section.displayName}}
+          <table class="config-sub-section" border="1">
+            {{#each subRow in section.subsectionRows}}
+              <tr>
+                {{#each subsection in subRow}}
+                  <td>{{subsection.name}}</td>
+                {{/each}}
+              </tr>
+            {{/each}}
+          </table>
+      </td>
+      {{/each}}
+    </tr>
+  {{/each}}
+</table>

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/templates/common/configs/service_config_wizard.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config_wizard.hbs b/ambari-web/app/templates/common/configs/service_config_wizard.hbs
index 576c548..f464a78 100644
--- a/ambari-web/app/templates/common/configs/service_config_wizard.hbs
+++ b/ambari-web/app/templates/common/configs/service_config_wizard.hbs
@@ -51,25 +51,25 @@
 {{#if view.supportsConfigLayout}}
   <ul class="nav nav-tabs">
     {{#each tab in view.tabs}}
-      <li {{bindAttr class="tab.isActive:active" }}><a href="#" {{bindAttr data-target="tab.className"}} data-toggle="tab">{{tab.displayName}}</a></li>
+      <li {{bindAttr class="tab.isActive:active" }}><a href="#" {{bindAttr data-target="tab.headingClass"}} data-toggle="tab">{{tab.displayName}}</a></li>
     {{/each}}
   </ul>
-
-  {{#each tab in view.tabs}}
-    <div {{bindAttr class=":tab-pane tab.isActive:active tab.id"}}>
-      {{#if tab.isAdvanced}}
-        <div class="accordion">
-          {{#each catView in view.serviceConfigsByCategoryView.childViews}}
-            {{view catView}}
-          {{/each}}
-        </div>
-      {{else}}
-        {{!
-          @TODO Fancy Config view goes here
-        }}
-      {{/if}}
-    </div>
-  {{/each}}
+  <div class="tab-content">
+    {{#each tab in view.tabs}}
+      <div {{bindAttr class=":tab-pane tab.isActive:active tab.id"}}>
+        {{#if tab.isAdvanced}}
+          <div class="accordion">
+            {{#each catView in view.serviceConfigsByCategoryView.childViews}}
+              {{view catView}}
+            {{/each}}
+          </div>
+        {{else}}
+          {{! Render Enhanced Config Section }}
+          {{view App.ServiceConfigLayoutTabView contentBinding="tab"}}
+        {{/if}}
+      </div>
+    {{/each}}
+  </div>
 {{else}}
   <div class="accordion">
     {{#each catView in view.serviceConfigsByCategoryView.childViews}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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 61392a8..df31bac 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -609,7 +609,12 @@ var urls = {
     'real': '{stackVersionUrl}/services/{serviceName}/artifacts/theme',
     'mock': '/data/configurations/theme.json'
   },
-  
+
+  'configs.theme.services': {
+    'real': '{stackVersionUrl}/services?StackServices/service_name.in({serviceNames})&artifacts/Artifacts/artifact_name=theme&fields=artifacts/*',
+    'mock': '/data/configurations/theme_services.json'
+  },
+
   /*************************CONFIG GROUPS***************************************/
 
   'configs.config_groups.load.all': {

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 488d4ac..68ed021 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -1975,7 +1975,8 @@ App.config = Em.Object.create({
       name: 'configs.theme',
       sender: this,
       data: {
-        serviceName: serviceName
+        serviceName: serviceName,
+        stackVersionUrl: App.get('stackVersionURL')
       },
       success: 'saveThemeToModel'
     });
@@ -1987,5 +1988,38 @@ App.config = Em.Object.create({
    */
   saveThemeToModel: function(data) {
     App.themesMapper.map(data);
+  },
+
+  /**
+   * Load themes for specified services by one API call.
+   *
+   * @method loadConfigThemeForServices
+   * @param {String|String[]} serviceNames
+   * @returns {$.Deferred}
+   */
+  loadConfigThemeForServices: function (serviceNames) {
+    var data = {
+      serviceNames: Em.isArray(serviceNames) ? serviceNames.join(',') : serviceNames,
+      stackVersionUrl: App.get('stackVersionURL')
+    };
+    return App.ajax.send({
+      name: 'configs.theme.services',
+      sender: this,
+      data: data,
+      success: 'loadConfigThemeForServicesSuccess',
+      error: 'loadConfigThemeForServicesError'
+    });
+  },
+
+  loadConfigThemeForServicesSuccess: function(data) {
+    if (!data.items.length) return;
+    data.items.mapProperty('artifacts.firstObject').forEach(function(item) {
+      App.themesMapper.map(item);
+    });
+  },
+
+  loadConfigThemeForServicesError: function(request, ajaxOptions, error, opt, params) {
+    console.log('ERROR: failed to load theme configs for', params.serviceNames);
   }
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 1e0bbe2..3ac3161 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -55,6 +55,7 @@ require('views/common/configs/widgets/config_widget_view');
 require('views/common/configs/widgets/list_config_widget_view');
 require('views/common/configs/widgets/slider_config_widget_view');
 require('views/common/configs/widgets/time_interval_spinner_view');
+require('views/common/configs/service_config_layout_tab_view');
 require('views/common/filter_combobox');
 require('views/common/filter_combo_cleanable');
 require('views/common/table_view');

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
new file mode 100644
index 0000000..2fa35b6
--- /dev/null
+++ b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js
@@ -0,0 +1,23 @@
+/**
+ * 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.ServiceConfigLayoutTabView = Em.View.extend({
+  templateName: require('templates/common/configs/service_config_layout_tab')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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 1070ac7..8c32494 100644
--- a/ambari-web/app/views/common/configs/service_config_view.js
+++ b/ambari-web/app/views/common/configs/service_config_view.js
@@ -43,11 +43,14 @@ App.ServiceConfigView = Em.View.extend({
    */
   supportsConfigLayout: function() {
     var supportedControllers = ['wizardStep7Controller', 'mainServiceInfoConfigsController'];
-    var unSupportedServices = ['MISC'];
     if (!App.get('supports.enhancedConfigs')) {
       return false;
     }
-    return supportedControllers.contains(this.get('controllerName')) || !unSupportedServices.contains(this.get('controller.selectedService.serviceName'));
+    if (App.Tab.find().someProperty('serviceName', this.get('controller.selectedService.serviceName')) && supportedControllers.contains(this.get('controller.name'))) {
+      return !Em.isEmpty(App.Tab.find().filterProperty('serviceName', this.get('controller.selectedService.serviceName')).filterProperty('isAdvanced', false));
+    } else {
+      return false;
+    }
   }.property('controller.name', 'controller.selectedService'),
 
   showConfigHistoryFeature: false,
@@ -98,7 +101,42 @@ App.ServiceConfigView = Em.View.extend({
     }
     var tabs = App.Tab.find().filterProperty('serviceName', this.get('controller.selectedService.serviceName'));
     // make first tab active
+    this.processTabs(tabs);
     tabs.get('firstObject').set('isActive', true);
     return tabs;
-  }.property('controller.selectedService.serviceName')
+  }.property('controller.selectedService.serviceName'),
+
+  /**
+   * Data reordering before rendering.
+   * Reorder all sections/subsections into rows based on their rowIndex
+   * @param tabs
+   */
+  processTabs: function (tabs) {
+    for (var i = 0; i < tabs.length; i++) {
+      var tab = tabs[i];
+
+      // process sections
+      var sectionRows = [];
+      var sections = tab.get('sections');
+      for (var j = 0; j < sections.get('length'); j++) {
+        var section = sections.objectAt(j);
+        var sectionRow = sectionRows[section.get('rowIndex')];
+        if (!sectionRow) { sectionRow = sectionRows[section.get('rowIndex')] = []; }
+        sectionRow.push(section);
+
+        //process subsections
+        var subsections = section.get('subSections');
+        var subsectionRows = [];
+        for (var k = 0; k < subsections.get('length'); k++) {
+          var subsection = subsections.objectAt(k);
+          var subsectionRow = subsectionRows[subsection.get('rowIndex')];
+          if (!subsectionRow) { subsectionRow = subsectionRows[subsection.get('rowIndex')] = []; }
+          subsectionRow.push(subsection);
+        }
+        section.set('subsectionRows', subsectionRows);
+      }
+      tab.set('sectionRows', sectionRows);
+    }
+  }
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/ambari-web/test/controllers/main/service/info/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js
index b299187..a6785ee 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -23,9 +23,16 @@ var mainServiceInfoConfigsController = null;
 describe("App.MainServiceInfoConfigsController", function () {
 
   beforeEach(function () {
+    sinon.stub(App.config, 'loadConfigTheme').returns($.Deferred().resolve().promise());
+    sinon.stub(App.themesMapper, 'generateAdvancedTabs').returns(Em.K);
     mainServiceInfoConfigsController = App.MainServiceInfoConfigsController.create({});
   });
 
+  afterEach(function() {
+    App.config.loadConfigTheme.restore();
+    App.themesMapper.generateAdvancedTabs.restore();
+  });
+
   describe("#showSavePopup", function () {
     var tests = [
       {

http://git-wip-us.apache.org/repos/asf/ambari/blob/34a89e8b/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
index 195a62f..1dc901a 100644
--- a/ambari-web/test/mappers/configs/themes_mapper_test.js
+++ b/ambari-web/test/mappers/configs/themes_mapper_test.js
@@ -32,6 +32,7 @@ describe('App.themeMapper', function () {
     App.resetDsStoreTypeMap(App.StackConfigProperty);
     sinon.stub(App.store, 'commit', Em.K);
   });
+
   afterEach(function () {
     App.store.commit.restore();
   });
@@ -39,67 +40,58 @@ describe('App.themeMapper', function () {
   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"
-              },
+      "Artifacts": {
+        "service_name": "HDFS"
+      },
+      "artifact_data": {
+        "Theme": {
+          "name": "default",
+          "description": "Default theme for HDFS service",
+          "configuration": {
+            "layouts": [
               {
-                "config": "c1/p2",
-                "subsection-name": "subsection1"
+                "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"
+                        }
+                      ]
+                    }
+                  }
+                ]
               }
-            ]
+            ],
           },
           "widgets": [
             {
@@ -127,7 +119,20 @@ describe('App.themeMapper', function () {
                 ]
               }
             }
-          ]
+          ],
+          "placement": {
+            "configuration-layout": "default",
+            "configs": [
+              {
+                "config": "c1/p1",
+                "subsection-name": "subsection1"
+              },
+              {
+                "config": "c1/p2",
+                "subsection-name": "subsection1"
+              }
+            ]
+          }
         }
       }
     };