ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nc...@apache.org
Subject [40/50] [abbrv] ambari git commit: AMBARI-13263. Create a Ranger theme with Ranger Admin. (jaimin)
Date Wed, 30 Sep 2015 14:46:00 GMT
AMBARI-13263. Create a Ranger theme with Ranger Admin. (jaimin)


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

Branch: refs/heads/branch-dev-patch-upgrade
Commit: 61540bbb54d023b52ce7e59fee81a067a1cbdcc8
Parents: 2b34016
Author: Jaimin Jetly <jaimin@hortonworks.com>
Authored: Mon Sep 28 20:22:26 2015 -0700
Committer: Jaimin Jetly <jaimin@hortonworks.com>
Committed: Mon Sep 28 20:23:52 2015 -0700

----------------------------------------------------------------------
 .../server/state/ValueAttributesInfo.java       |  16 +
 .../server/state/theme/ConfigCondition.java     |  87 +++++
 .../server/state/theme/ConfigPlacement.java     |  26 ++
 .../ambari/server/state/theme/Subsection.java   |  28 ++
 .../ambari/server/state/theme/Widget.java       |  23 +-
 .../0.4.0/configuration/admin-properties.xml    |  12 +
 .../RANGER/0.4.0/configuration/ranger-env.xml   |   3 +-
 .../RANGER/configuration/admin-properties.xml   |  58 +++
 .../RANGER/configuration/ranger-env.xml         |  21 +-
 .../stacks/HDP/2.3/services/RANGER/metainfo.xml |   7 +
 .../HDP/2.3/services/RANGER/themes/theme.json   | 294 +++++++++++++++
 ambari-web/app/app.js                           |   2 +
 .../controllers/main/service/info/configs.js    |   9 +-
 .../app/controllers/wizard/step7_controller.js  |   2 +-
 ambari-web/app/data/HDP2.2/site_properties.js   |  13 +-
 ambari-web/app/data/HDP2.3/site_properties.js   |  44 +--
 ambari-web/app/mappers/configs/themes_mapper.js |  84 ++++-
 ambari-web/app/models.js                        |   1 +
 .../app/models/configs/config_condition.js      |  60 +++
 ambari-web/app/models/configs/section.js        |   6 +-
 .../app/models/configs/stack_config_property.js |  10 +
 ambari-web/app/models/configs/sub_section.js    |  21 +-
 .../configs/service_config_layout_tab.hbs       |  10 +-
 .../widgets/test_db_connection_widget.hbs       |  35 ++
 ambari-web/app/utils/config.js                  |  43 ++-
 ambari-web/app/views.js                         |   1 +
 .../configs/service_config_layout_tab_view.js   |  24 +-
 .../configs/widgets/config_widget_view.js       |  50 +++
 .../widgets/password_config_widget_view.js      |   1 +
 .../widgets/test_db_connection_widget_view.js   | 364 +++++++++++++++++++
 .../test/mappers/configs/themes_mapper_test.js  |   2 +
 ambari-web/test/models/configs/section_test.js  |  12 +-
 32 files changed, 1278 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
index e8cd074..3f7f756 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ValueAttributesInfo.java
@@ -43,6 +43,10 @@ public class ValueAttributesInfo {
   @JsonProperty("empty_value_valid")
   private Boolean emptyValueValid;
 
+  @XmlElement(name = "ui-only-property")
+  @JsonProperty("ui_only_property")
+  private Boolean uiOnlyProperty;
+
   @XmlElement(name = "read-only")
   @JsonProperty("read_only")
   private Boolean readOnly;
@@ -194,6 +198,14 @@ public class ValueAttributesInfo {
     this.showPropertyName = isPropertyNameVisible;
   }
 
+  public Boolean getUiOnlyProperty() {
+    return uiOnlyProperty;
+  }
+
+  public void setUiOnlyProperty(Boolean isUiOnlyProperty) {
+    this.uiOnlyProperty = isUiOnlyProperty;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -216,6 +228,8 @@ public class ValueAttributesInfo {
       return false;
     if (showPropertyName != null ? !showPropertyName.equals(that.showPropertyName) : that.showPropertyName != null)
       return false;
+    if (uiOnlyProperty != null ? !uiOnlyProperty.equals(that.uiOnlyProperty) : that.uiOnlyProperty != null)
+      return false;
     if (maximum != null ? !maximum.equals(that.maximum) : that.maximum != null) return false;
     if (minimum != null ? !minimum.equals(that.minimum) : that.minimum != null) return false;
     if (selectionCardinality != null ? !selectionCardinality.equals(that.selectionCardinality) : that.selectionCardinality != null)
@@ -245,6 +259,7 @@ public class ValueAttributesInfo {
     result = 31 * result + (editableOnlyAtInstall != null ? editableOnlyAtInstall.hashCode() : 0);
     result = 31 * result + (overridable != null ? overridable.hashCode() : 0);
     result = 31 * result + (showPropertyName != null ? showPropertyName.hashCode() : 0);
+    result = 31 * result + (uiOnlyProperty != null ? uiOnlyProperty.hashCode() : 0);
     return result;
   }
 
@@ -263,6 +278,7 @@ public class ValueAttributesInfo {
       ", editableOnlyAtInstall='" + editableOnlyAtInstall + '\'' +
       ", overridable='" + overridable + '\'' +
       ", showPropertyName='" + showPropertyName + '\'' +
+      ", uiOnlyProperty='" + uiOnlyProperty + '\'' +
       ", incrementStep='" + incrementStep + '\'' +
       ", entriesEditable=" + entriesEditable +
       ", selectionCardinality='" + selectionCardinality + '\'' +

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigCondition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigCondition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigCondition.java
new file mode 100644
index 0000000..2d98660
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigCondition.java
@@ -0,0 +1,87 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+
+package org.apache.ambari.server.state.theme;
+
+import org.apache.ambari.server.state.ValueAttributesInfo;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.List;
+
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ConfigCondition {
+  @JsonProperty("configs")
+  private List<String> configs;
+  @JsonProperty("if")
+  private String ifLabel;
+  @JsonProperty("then")
+  private ConfigConditionResult then;
+  @JsonProperty("else")
+  private ConfigConditionResult elseLabel;
+
+  public List<String> getConfigs() {
+    return configs;
+  }
+
+  public void setConfigs(List<String> configs) {
+    this.configs = configs;
+  }
+
+  public String getIfLabel() {
+    return ifLabel;
+  }
+
+  public void setIfLabel(String ifLabel) {
+    this.ifLabel = ifLabel;
+  }
+
+  public ConfigConditionResult getThen() {
+    return then;
+  }
+
+  public void setThen(ConfigConditionResult then) {
+    this.then = then;
+  }
+
+  public ConfigConditionResult getElseLabel() {
+    return elseLabel;
+  }
+
+  public void setElseLabel(ConfigConditionResult elseLabel) {
+    this.elseLabel = elseLabel;
+  }
+
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public class ConfigConditionResult {
+    @JsonProperty("property_value_attributes")
+    private ValueAttributesInfo propertyValueAttributes;
+
+    public ValueAttributesInfo getPropertyValueAttributes() {
+      return propertyValueAttributes;
+    }
+
+    public void setPropertyValueAttributes(ValueAttributesInfo propertyValueAttributes) {
+      this.propertyValueAttributes = propertyValueAttributes;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigPlacement.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigPlacement.java b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigPlacement.java
index c20cd8e..56d2ea2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigPlacement.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/ConfigPlacement.java
@@ -18,10 +18,13 @@
 
 package org.apache.ambari.server.state.theme;
 
+import org.apache.ambari.server.state.ValueAttributesInfo;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
+import java.util.List;
+
 @JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class ConfigPlacement {
@@ -30,6 +33,13 @@ public class ConfigPlacement {
 	@JsonProperty("subsection-name")
 	private String subsectionName;
 
+  @JsonProperty("property_value_attributes")
+  private ValueAttributesInfo propertyValueAttributes;
+
+  @JsonProperty("depends-on")
+  private List<ConfigCondition> dependsOn;
+
+
   public String getConfig() {
     return config;
   }
@@ -46,6 +56,22 @@ public class ConfigPlacement {
     this.subsectionName = subsectionName;
   }
 
+  public ValueAttributesInfo getPropertyValueAttributes() {
+    return propertyValueAttributes;
+  }
+
+  public void setPropertyValueAttributes(ValueAttributesInfo propertyValueAttributes) {
+    this.propertyValueAttributes = propertyValueAttributes;
+  }
+
+  public List<ConfigCondition> getDependsOn() {
+    return dependsOn;
+  }
+
+  public void setDependsOn(List<ConfigCondition> dependsOn) {
+    this.dependsOn = dependsOn;
+  }
+
   public boolean isRemoved() {
     return subsectionName == null;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Subsection.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Subsection.java b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Subsection.java
index b86b51f..0397545 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Subsection.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Subsection.java
@@ -23,6 +23,8 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
+import java.util.List;
+
 
 @JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
 @JsonIgnoreProperties(ignoreUnknown = true)
@@ -41,6 +43,10 @@ public class Subsection {
 	private String columnIndex;
   @JsonProperty("border")
 	private String border;
+  @JsonProperty("left-vertical-splitter")
+  private Boolean leftVerticalSplitter;
+  @JsonProperty("depends-on")
+  private List<ConfigCondition> dependsOn;
 
 
   public String getRowIndex() {
@@ -99,6 +105,22 @@ public class Subsection {
     this.border = border;
   }
 
+  public Boolean getLeftVerticalSplitter() {
+    return leftVerticalSplitter;
+  }
+
+  public void setLeftVerticalSplitter(Boolean leftVerticalSplitter) {
+    this.leftVerticalSplitter = leftVerticalSplitter;
+  }
+
+  public List<ConfigCondition> getDependsOn() {
+    return dependsOn;
+  }
+
+  public void setDependsOn(List<ConfigCondition> dependsOn) {
+    this.dependsOn = dependsOn;
+  }
+
   public boolean isRemoved() {
     return rowIndex == null && rowSpan == null && columnIndex == null && columnSpan == null;
   }
@@ -122,5 +144,11 @@ public class Subsection {
     if (border == null) {
       border = parent.border;
     }
+    if (leftVerticalSplitter == null) {
+      leftVerticalSplitter = parent.leftVerticalSplitter;
+    }
+    if (dependsOn == null) {
+      dependsOn = parent.dependsOn;
+    }
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Widget.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Widget.java b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Widget.java
index 7b1e09c..c8176ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Widget.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/theme/Widget.java
@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 import java.util.List;
+import java.util.Map;
 
 
 @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@@ -33,6 +34,10 @@ public class Widget{
 	private String type;
 	@JsonProperty("units")
 	private List<Unit> units;
+  @JsonProperty("required-properties")
+  private Map<String,String> requiredProperties;
+  @JsonProperty("display-name")
+  private String displayName;
 
   public String getType() {
     return type;
@@ -49,4 +54,20 @@ public class Widget{
   public void setUnits(List<Unit> units) {
     this.units = units;
   }
-}
\ No newline at end of file
+
+  public Map<String, String> getRequiredProperties() {
+    return requiredProperties;
+  }
+
+  public void setRequiredProperties(Map<String, String> requiredProperties) {
+    this.requiredProperties = requiredProperties;
+  }
+
+  public String getDisplayName() {
+    return displayName;
+  }
+
+  public void setDisplayName(String displayName) {
+    this.displayName = displayName;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/admin-properties.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/admin-properties.xml b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/admin-properties.xml
index 936c332..c7e3ff9 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/admin-properties.xml
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/admin-properties.xml
@@ -28,6 +28,18 @@
     <description>The database type to be used (mysql/oracle)</description>
     <value-attributes>
       <overridable>false</overridable>
+      <type>value-list</type>
+      <entries>
+        <entry>
+          <value>MYSQL</value>
+          <label>MYSQL</label>
+        </entry>
+        <entry>
+          <value>ORACLE</value>
+          <label>ORACLE</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
     </value-attributes>
   </property>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
index 95c3b50..97c2b9f 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/configuration/ranger-env.xml
@@ -58,6 +58,7 @@
     <name>ranger_admin_username</name>
     <value>amb_ranger_admin</value>
     <property-type>TEXT</property-type>
+    <display-name>Ranger Admin username for Ambari</display-name>
     <description>This is the ambari user created for creating repositories and policies in Ranger Admin for each plugin</description>
   </property>
 
@@ -102,6 +103,6 @@
     <name>ranger_pid_dir</name>
     <value>/var/run/ranger</value>
     <description></description>
-  </property>    
+  </property>
 
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/admin-properties.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/admin-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/admin-properties.xml
index 114c3ab..5d7f7ce 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/admin-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/admin-properties.xml
@@ -22,6 +22,64 @@
 <configuration supports_final="false">
 
   <property>
+    <name>DB_FLAVOR</name>
+    <value>MYSQL</value>
+    <display-name>DB FLAVOR</display-name>
+    <description>The database type to be used (mysql/oracle)</description>
+    <value-attributes>
+      <overridable>false</overridable>
+      <type>value-list</type>
+      <entries>
+        <entry>
+          <value>MYSQL</value>
+          <label>MYSQL</label>
+        </entry>
+        <entry>
+          <value>ORACLE</value>
+          <label>ORACLE</label>
+        </entry>
+        <entry>
+          <value>POSTGRES</value>
+          <label>POSTGRES</label>
+        </entry>
+        <entry>
+          <value>MSSQL</value>
+          <label>MSSQL</label>
+        </entry>
+        <entry>
+          <value>SQLA</value>
+          <label>SQL Anywhere</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
+    </value-attributes>
+  </property>
+
+  <property>
+    <name>db_root_user</name>
+    <value>root</value>
+    <display-name>Ranger DB root user</display-name>
+    <description>Database admin user</description>
+    <value-attributes>
+      <overridable>false</overridable>
+      <visible>false</visible>
+    </value-attributes>
+  </property>
+
+  <property require-input="true">
+    <name>db_root_password</name>
+    <value></value>
+    <property-type>PASSWORD</property-type>
+    <display-name>Ranger DB root password</display-name>
+    <description>Database password for the database admin user-id</description>
+    <value-attributes>
+      <overridable>false</overridable>
+      <visible>false</visible>
+    </value-attributes>
+  </property>
+
+
+  <property>
     <name>policymgr_http_enabled</name>
     <deleted>true</deleted>
   </property>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
index 8308865..7f3e6e0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-env.xml
@@ -28,9 +28,24 @@
 
   <property>
     <name>create_db_dbuser</name>
-    <value>true</value>
-    <display-name>Setup DB and DB user</display-name>
-    <description>Setup Ranger Database and Database User?</description>
+    <value>false</value>
+    <display-name>Setup Database and Databse User</display-name>
+    <description>If set to Yes, Ranger will Setup Database and Databse User. This will require to specify Database root user and password</description>
+    <value-attributes>
+      <type>value-list</type>
+      <overridable>false</overridable>
+      <entries>
+        <entry>
+          <value>true</value>
+          <label>Yes</label>
+        </entry>
+        <entry>
+          <value>false</value>
+          <label>No</label>
+        </entry>
+      </entries>
+      <selection-cardinality>1</selection-cardinality>
+    </value-attributes>
   </property>
 
   <property>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/metainfo.xml
index a13fabf..69d908b 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/metainfo.xml
@@ -52,6 +52,13 @@
         </osSpecific>
       </osSpecifics>
 
+      <themes>
+        <theme>
+          <fileName>theme.json</fileName>
+          <default>true</default>
+        </theme>
+      </themes>
+
       <configuration-dependencies>
         <config-type>ranger-admin-site</config-type>
         <config-type>ranger-ugsync-site</config-type>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/themes/theme.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/themes/theme.json b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/themes/theme.json
new file mode 100644
index 0000000..7160a4f
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/themes/theme.json
@@ -0,0 +1,294 @@
+{
+  "name": "default",
+  "description": "Default theme for Ranger service",
+  "configuration": {
+    "layouts": [
+      {
+        "name": "default",
+        "tabs": [
+          {
+            "name": "ranger_admin_settings",
+            "display-name": "Ranger Admin",
+            "layout": {
+              "tab-columns": "2",
+              "tab-rows": "2",
+              "sections": [
+                {
+                  "name": "section-ranger-admin",
+                  "display-name": "Ranger Admin",
+                  "row-index": "0",
+                  "column-index": "0",
+                  "row-span": "4",
+                  "column-span": "2",
+                  "section-columns": "2",
+                  "section-rows": "4",
+                  "subsections": [
+                    {
+                      "name": "subsection-ranger-db-row1-col1",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "subsection-ranger-db-row1-col2",
+                      "row-index": "0",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "subsection-ranger-db-row2-col1",
+                      "row-index": "1",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "subsection-ranger-db-row2-col2",
+                      "row-index": "1",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1",
+                      "left-vertical-splitter": false
+                    },
+                    {
+                      "name": "subsection-ranger-db-row3",
+                      "row-index": "2",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "2"
+                    },
+                    {
+                      "name": "subsection-ranger-db-row4-col1",
+                      "row-index": "3",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1",
+                      "depends-on": [
+                        {
+                          "configs":[
+                            "ranger-env/create_db_dbuser"
+                          ],
+                          "if": "${ranger-env/create_db_dbuser}",
+                          "then": {
+                            "property_value_attributes": {
+                              "visible": true
+                            }
+                          },
+                          "else": {
+                            "property_value_attributes": {
+                              "visible": false
+                            }
+                          }
+                        }
+                      ]
+                    },
+                    {
+                      "name": "subsection-ranger-db-row4-col2",
+                      "row-index": "3",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1",
+                      "depends-on": [
+                        {
+                          "configs":[
+                            "ranger-env/create_db_dbuser"
+                          ],
+                          "if": "${ranger-env/create_db_dbuser}",
+                          "then": {
+                            "property_value_attributes": {
+                              "visible": true
+                            }
+                          },
+                          "else": {
+                            "property_value_attributes": {
+                              "visible": false
+                            }
+                          }
+                        }
+                      ],
+                      "left-vertical-splitter": false
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    ],
+    "placement": {
+      "configuration-layout": "default",
+      "configs": [
+        {
+          "config": "admin-properties/DB_FLAVOR",
+          "subsection-name": "subsection-ranger-db-row1-col1"
+        },
+        {
+          "config": "admin-properties/db_name",
+          "subsection-name": "subsection-ranger-db-row1-col1"
+        },
+        {
+          "config": "ranger-admin-site/ranger.jpa.jdbc.url",
+          "subsection-name": "subsection-ranger-db-row1-col1"
+        },
+        {
+          "config": "admin-properties/db_host",
+          "subsection-name": "subsection-ranger-db-row1-col2"
+        },
+        {
+          "config": "ranger-admin-site/ranger.jpa.jdbc.driver",
+          "subsection-name": "subsection-ranger-db-row1-col2"
+        },
+        {
+          "config": "admin-properties/db_user",
+          "subsection-name": "subsection-ranger-db-row2-col1"
+        },
+        {
+          "config": "admin-properties/db_password",
+          "subsection-name": "subsection-ranger-db-row2-col2"
+        },
+        {
+          "config": "ranger-env/test_db_connection",
+          "subsection-name": "subsection-ranger-db-row2-col2",
+          "property_value_attributes": {
+            "ui_only_property": true
+          },
+          "depends-on": [
+            {
+              "configs":[
+                "ranger-env/create_db_dbuser"
+              ],
+              "if": "${ranger-env/create_db_dbuser}",
+              "then": {
+                "property_value_attributes": {
+                  "visible": false
+                }
+              },
+              "else": {
+                "property_value_attributes": {
+                  "visible": true
+                }
+              }
+            }
+          ]
+        },
+        {
+          "config": "ranger-env/create_db_dbuser",
+          "subsection-name": "subsection-ranger-db-row3"
+        },
+        {
+          "config": "admin-properties/db_root_user",
+          "subsection-name": "subsection-ranger-db-row4-col1"
+        },
+        {
+          "config": "admin-properties/db_root_password",
+          "subsection-name": "subsection-ranger-db-row4-col2"
+        },
+        {
+          "config": "ranger-env/test_root_db_connection",
+          "subsection-name": "subsection-ranger-db-row4-col2",
+          "property_value_attributes": {
+            "ui_only_property": true
+          }
+        }
+      ]
+    },
+    "widgets": [
+      {
+        "config": "admin-properties/DB_FLAVOR",
+        "widget": {
+          "type": "combo"
+        }
+      },
+      {
+        "config": "admin-properties/db_user",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "admin-properties/db_name",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "ranger-admin-site/ranger.jpa.jdbc.url",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "ranger-admin-site/ranger.jpa.jdbc.driver",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "admin-properties/db_host",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "admin-properties/db_password",
+        "widget": {
+          "type": "password"
+        }
+      },
+      {
+        "config": "ranger-env/test_db_connection",
+        "widget": {
+          "type": "test-db-connection",
+          "display-name": "Test Connection",
+          "required-properties": {
+            "jdbc.driver.class": "ranger-admin-site/ranger.jpa.jdbc.driver",
+            "jdbc.driver.url": "ranger-admin-site/ranger.jpa.jdbc.url",
+            "db.connection.source.host": "ranger-site/ranger_admin_hosts",
+            "db.type": "admin-properties/DB_FLAVOR",
+            "db.connection.destination.host": "admin-properties/db_host",
+            "db.connection.user": "admin-properties/db_user",
+            "db.connection.password": "admin-properties/db_password"
+          }
+        }
+      },
+      {
+        "config": "ranger-env/create_db_dbuser",
+        "widget": {
+          "type": "toggle"
+        }
+      },
+      {
+        "config": "admin-properties/db_root_user",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "admin-properties/db_root_password",
+        "widget": {
+          "type": "password"
+        }
+      },
+      {
+        "config": "ranger-env/test_root_db_connection",
+        "widget": {
+          "type": "test-db-connection",
+          "display-name": "Test Connection",
+          "required-properties": {
+            "jdbc.driver.class": "ranger-admin-site/ranger.jpa.jdbc.driver",
+            "jdbc.driver.url": "ranger-admin-site/ranger.jpa.jdbc.url",
+            "db.connection.source.host": "ranger-site/ranger_admin_hosts",
+            "db.type": "admin-properties/DB_FLAVOR",
+            "db.connection.destination.host": "admin-properties/db_host",
+            "db.connection.user": "admin-properties/db_root_user",
+            "db.connection.password": "admin-properties/db_root_password"
+          }
+        }
+      }
+    ]
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index f7c86b1..16bcc28 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -184,6 +184,8 @@ module.exports = Em.Application.create({
 
   allHostNames: [],
 
+  uiOnlyConfigDerivedFromTheme: [],
+
   currentStackVersionNumber: function () {
     var regExp = new RegExp(this.get('currentStackName') + '-');
     return (this.get('currentStackVersion') || this.get('defaultStackVersion')).replace(regExp, '');

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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 db5f1ed..3252fa3 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -135,7 +135,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     }).filter(function(config) {
       return !config.get('isValid') || (config.get('overrides') || []).someProperty('isValid', false);
     }).filterProperty('isVisible').length;
-  }.property('selectedService.configs.@each.isValid', 'selectedService.configs.@each.overrideErrorTrigger'),
+  }.property('selectedService.configs.@each.isValid', 'selectedService.configs.@each.isVisible', 'selectedService.configs.@each.overrideErrorTrigger'),
 
   /**
    * Determines if Save-button should be disabled
@@ -302,17 +302,18 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method loadStep
    */
   loadStep: function () {
+    var self = this;
     var serviceName = this.get('content.serviceName');
     this.clearStep();
     this.set('dependentServiceNames', App.StackService.find(serviceName).get('dependentServiceNames'));
     if (App.get('isClusterSupportsEnhancedConfigs')) {
       this.loadConfigTheme(serviceName).always(function() {
         App.themesMapper.generateAdvancedTabs([serviceName]);
+        // Theme mapper has UI only configs that needs to be merged with current service version configs
+        // This requires calling  `loadCurrentVersions` after theme has loaded
+        self.loadCurrentVersions();
       });
     }
-    if (!this.get('preSelectedConfigVersion')) {
-      this.loadCurrentVersions();
-    }
     this.loadServiceConfigVersions();
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/controllers/wizard/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js
index bedd164..ff0e2ce 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -128,7 +128,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     }).filter(function(config) {
       return !config.get('isValid') || (config.get('overrides') || []).someProperty('isValid', false);
     }).filterProperty('isVisible').length;
-  }.property('selectedService.configs.@each.isValid', 'selectedService.configs.@each.overrideErrorTrigger'),
+  }.property('selectedService.configs.@each.isValid', 'selectedService.configs.@each.isVisible','selectedService.configs.@each.overrideErrorTrigger'),
 
   /**
    * Should Next-button be disabled

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/data/HDP2.2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2.2/site_properties.js b/ambari-web/app/data/HDP2.2/site_properties.js
index 7341387..397e748 100644
--- a/ambari-web/app/data/HDP2.2/site_properties.js
+++ b/ambari-web/app/data/HDP2.2/site_properties.js
@@ -210,16 +210,25 @@ hdp22properties.push(
   },
   /**********************************************RANGER***************************************/
   {
+    "name": "ranger_admin_username",
+    "serviceName": "RANGER",
+    "filename": "ranger-env.xml",
+    "category": "RANGER_ADMIN",
+    "index": 0
+  },
+  {
     "name": "ranger_admin_password",
     "serviceName": "RANGER",
     "filename": "ranger-env.xml",
-    "category": "RANGER_ADMIN"
+    "category": "RANGER_ADMIN",
+    "index": 1
   },
   {
     "name": "SQL_CONNECTOR_JAR",
     "serviceName": "RANGER",
     "filename": "admin-properties.xml",
-    "category": "RANGER_ADMIN"
+    "category": "RANGER_ADMIN",
+    "index": 2
   },
   {
     "name": "DB_FLAVOR",

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/data/HDP2.3/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2.3/site_properties.js b/ambari-web/app/data/HDP2.3/site_properties.js
index adf8cae..8041bc6 100644
--- a/ambari-web/app/data/HDP2.3/site_properties.js
+++ b/ambari-web/app/data/HDP2.3/site_properties.js
@@ -23,6 +23,8 @@ var hdp22properties = require('data/HDP2.2/site_properties').configProperties;
 var excludedConfigs = [
   'DB_FLAVOR',
   'db_name',
+  'db_user',
+  'db_password',
   'db_root_user',
   'db_root_password',
   'nimbus.host',
@@ -67,48 +69,8 @@ var hdp23properties = hdp22properties.filter(function (item) {
 });
 
 hdp23properties.push({
-    "name": "DB_FLAVOR",
-    "options": [
-      {
-        displayName: 'MYSQL'
-      },
-      {
-        displayName: 'ORACLE'
-      },
-      {
-        displayName: 'POSTGRES'
-      },
-      {
-        displayName: 'MSSQL'
-      },
-      {
-        displayName: 'SQLA',
-        hidden: App.get('currentStackName') !== 'SAPHD' && App.get('currentStackName') !== 'HDP'
-      }
-    ],
-    "displayType": "radio button",
-    "radioName": "RANGER DB_FLAVOR",
-    "serviceName": "RANGER",
-    "filename": "admin-properties.xml",
-    "category": "DBSettings",
-    "index": 1
-  },
-  {
-    "name": "db_host",
-    "serviceName": "RANGER",
-    "filename": "admin-properties.xml",
-    "category": "DBSettings",
-    "index": 2
-  },
-  {
-    "name": "create_db_dbuser",
-    "displayType": "checkbox",
-    "filename": "ranger-env.xml",
-    "category": "Advanced ranger-env",
-    "serviceName": "RANGER"
-  },
   /**************************************** RANGER - HDFS Plugin ***************************************/
-  {
+
     "name": "xasecure.audit.destination.db",
     "displayType": "checkbox",
     "filename": "ranger-hdfs-audit.xml",

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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 e632860..b55a695 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -21,6 +21,7 @@ App.themesMapper = App.QuickDataMapper.create({
   tabModel: App.Tab,
   sectionModel: App.Section,
   subSectionModel: App.SubSection,
+  configConditionModel: App.ConfigCondition,
 
   tabConfig: {
     "id": "name",
@@ -55,7 +56,9 @@ App.themesMapper = App.QuickDataMapper.create({
     "column_span": "column-span",
     "row_span": "row-span",
     "configProperties": "config_properties",
-    "section_id": "section_id"
+    "section_id": "section_id",
+    "depends_on": "depends-on",
+    "left_vertical_splitter": "left-vertical-splitter"
   },
 
   map: function (json) {
@@ -123,22 +126,85 @@ App.themesMapper = App.QuickDataMapper.create({
    * @param {Object} json - json to parse
    */
   mapThemeConfigs: function(json) {
+    var serviceName = Em.get(json, "ThemeInfo.service_name");
     Em.getWithDefault(json, "ThemeInfo.theme_data.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);
+      var subSectionDependsOnConfigs = subSection.get('dependsOn');
+      var configDependsOnOtherConfigs =  configLink["depends-on"] || [];
+      var dependsOnConfigs = configDependsOnOtherConfigs.concat(subSectionDependsOnConfigs);
 
-      if (configProperty && subSection) {
+      if (configProperty.get('id') && subSection) {
         subSection.get('configProperties').pushObject(configProperty);
         configProperty.set('subSection', subSection);
       } else {
-        console.warn('there is no such property: ' + configId + '. Or subsection: ' + subSectionId);
+        console.log('there is no such property: ' + configId + '. Or subsection: ' + subSectionId);
+        var valueAttributes = configLink["property_value_attributes"];
+        if (valueAttributes) {
+          var isUiOnlyProperty = valueAttributes["ui_only_property"];
+          // UI only configs are mentioned in the themes for supporting widgets that is not intended for setting a value
+          // And thus is affiliated witha fake config peperty termed as ui only config property
+          if (isUiOnlyProperty && subSection) {
+            var split = configLink.config.split("/");
+            var fileName =  split[0] + '.xml';
+            var configName = split[1];
+            var uiOnlyConfig = App.uiOnlyConfigDerivedFromTheme.filterProperty('filename', fileName).findProperty('name', configName);
+            if (!uiOnlyConfig) {
+              var coreObject = {
+                id: configName + '_' + split[0],
+                isRequiredByAgent: false,
+                showLabel: false,
+                isOverridable: false,
+                recommendedValue: true,
+                name: configName,
+                isUserProperty: false,
+                filename: fileName,
+                serviceName: serviceName,
+                subSection: subSection
+              };
+              var uiOnlyConfigDerivedFromTheme = Em.Object.create(App.config.createDefaultConfig(configName, serviceName, fileName, false, coreObject));
+              App.uiOnlyConfigDerivedFromTheme.pushObject(uiOnlyConfigDerivedFromTheme);
+            }
+          }
+        }
+      }
+
+      // map all the configs which conditionally affect the value attributes of a config
+      if (dependsOnConfigs && dependsOnConfigs.length) {
+        this.mapThemeConfigConditions(dependsOnConfigs, uiOnlyConfigDerivedFromTheme || configProperty);
       }
+
     }, this);
   },
 
   /**
+   *
+   * @param configConditions: Array
+   * @param configProperty: DS.Model Object (App.StackConfigProperty)
+   */
+  mapThemeConfigConditions: function(configConditions, configProperty) {
+    var configConditionsCopy = [];
+    configConditions.forEach(function(_configCondition, index){
+      var configCondition = $.extend({},_configCondition);
+      configCondition.id = configProperty.get('id') + '_' + index;
+      configCondition.config_name =  configProperty.get('name');
+      configCondition.file_name =  configProperty.get('filename');
+      configCondition.configs =  _configCondition.configs.map(function(item) {
+        var result = {};
+        result.fileName = item.split('/')[0] + '.xml';
+        result.configName = item.split('/')[1];
+        return result;
+      });
+      configConditionsCopy.pushObject(configCondition);
+    }, this);
+
+    App.store.loadMany(this.get("configConditionModel"), configConditionsCopy);
+    App.store.commit();
+  },
+
+  /**
    * add widget object to <code>stackConfigProperty<code>
    *
    * @param {Object} json - json to parse
@@ -148,10 +214,18 @@ App.themesMapper = App.QuickDataMapper.create({
       var configId = this.getConfigId(widget);
       var configProperty = App.StackConfigProperty.find(configId);
 
-      if (configProperty) {
+      if (configProperty.get('id')) {
         configProperty.set('widget', widget.widget);
       } else {
-        console.warn('there is no such property: ' + configId);
+        var split = widget.config.split("/");
+        var fileName =  split[0] + '.xml';
+        var configName = split[1];
+        var uiOnlyProperty = App.uiOnlyConfigDerivedFromTheme.filterProperty('filename',fileName).findProperty('name',configName);
+        if (uiOnlyProperty) {
+          uiOnlyProperty.set('widget', widget.widget);
+        } else {
+          console.warn('there is no such property: ' + configId);
+        }
       }
     }, this);
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/models.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models.js b/ambari-web/app/models.js
index 77918e5..1b34b0c 100644
--- a/ambari-web/app/models.js
+++ b/ambari-web/app/models.js
@@ -60,6 +60,7 @@ require('models/master_component');
 require('models/host_stack_version');
 require('models/root_service');
 require('models/upgrade_entity');
+require('models/configs/config_condition');
 require('models/configs/service_config_version');
 require('models/configs/stack_config_property');
 require('models/configs/config_group');

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/models/configs/config_condition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/config_condition.js b/ambari-web/app/models/configs/config_condition.js
new file mode 100644
index 0000000..26cf219
--- /dev/null
+++ b/ambari-web/app/models/configs/config_condition.js
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+
+/**
+ * THIS IS NOT USED FOR NOW
+ * FOR CONFIG GROUPS WE ARE USING OLD MODELS AND LOGIC
+ */
+
+var App = require('app');
+
+App.ConfigCondition = DS.Model.extend({
+  /**
+   * unique id generated as <code>config_name<code><code>filename<code>
+   * @property {string}
+   */
+  id: DS.attr('string'),
+
+  /**
+   * Name of the config that is being affected with the condition
+   */
+  configName: DS.attr('string'),
+
+  /**
+   * File name to which the config getting affected belongs
+   */
+  fileName: DS.attr('string'),
+
+  /**
+   * List of configs whose values affect the config
+   * Each Object in an array consists of configName and fileName
+   */
+  configs: DS.attr('array', {defaultValue: []}),
+
+  /**
+   * conditional String which can be evaluated to boolean result.
+   * If evaluated result of this staring is true then use the statement provided by `then` attribute.
+   * Otherwise use the attribute provided by `else` attributes
+   */
+  if: DS.attr('string'),
+  then: DS.attr('object', {defaultValue: null}),
+  else: DS.attr('object', {defaultValue: null})
+
+});
+
+App.ConfigCondition.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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
index 8f45757..c04665e 100644
--- a/ambari-web/app/models/configs/section.js
+++ b/ambari-web/app/models/configs/section.js
@@ -77,9 +77,9 @@ App.Section = DS.Model.extend({
    * @type {number}
    */
   errorsCount: function () {
-    var errors = this.get('subSections').mapProperty('errorsCount');
+    var errors = this.get('subSections').filterProperty('isSectionVisible').mapProperty('errorsCount');
     return errors.length ? errors.reduce(Em.sum) : 0;
-  }.property('subSections.@each.errorsCount'),
+  }.property('subSections.@each.errorsCount', 'subSections.@each.isSectionVisible'),
 
   /**
    * @type {boolean}
@@ -128,7 +128,7 @@ App.Section = DS.Model.extend({
    * @type {boolean}
    */
   isHiddenByFilter: function () {
-    return this.get('subSections').everyProperty('isHiddenByFilter', true);
+    return !this.get('subSections').someProperty('isSectionVisible', true);
   }.property('subSections.@each.isHiddenByFilter')
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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 1289662..76e3b5f 100644
--- a/ambari-web/app/models/configs/stack_config_property.js
+++ b/ambari-web/app/models/configs/stack_config_property.js
@@ -284,3 +284,13 @@ App.StackConfigProperty = DS.Model.extend({
 
 
 App.StackConfigProperty.FIXTURES = [];
+
+App.StackConfigValAttributesMap = {
+  'overridable': 'isOverridable' ,
+  'visible': 'isVisible' ,
+  'empty_value_valid':'isRequired' ,
+  'editable_only_at_install': 'isReconfigurable' ,
+  'show_property_name': 'showLabel',
+  'read_only': 'isEditable',
+  'ui_only_property': 'isRequiredByAgent'
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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
index d33fbb9..b7abb4f 100644
--- a/ambari-web/app/models/configs/sub_section.js
+++ b/ambari-web/app/models/configs/sub_section.js
@@ -67,6 +67,13 @@ App.SubSection = DS.Model.extend({
    */
   configProperties: DS.hasMany('App.StackConfigProperty'),
 
+  dependsOn: DS.attr('array', {defaultValue: []}),
+
+  /**
+   * @type {boolean}
+   */
+  leftVerticalSplitter: DS.attr('boolean', {defaultValue: true}),
+
   /**
    * @type {App.ServiceConfigProperty[]}
    */
@@ -86,8 +93,8 @@ App.SubSection = DS.Model.extend({
    * @type {boolean}
    */
   addLeftVerticalSplitter: function() {
-    return !this.get('isFirstColumn');
-  }.property('isFirstColumn'),
+    return !this.get('isFirstColumn') && this.get('leftVerticalSplitter');
+  }.property('isFirstColumn', 'leftVerticalSplitter'),
 
   /**
    * @type {boolean}
@@ -153,7 +160,15 @@ App.SubSection = DS.Model.extend({
   isHiddenByFilter: function () {
     var configs = this.get('configs');
     return configs.length ? configs.everyProperty('isHiddenByFilter', true) : false;
-  }.property('configs.@each.isHiddenByFilter')
+  }.property('configs.@each.isHiddenByFilter'),
+
+  /**
+   * Determines if subsection is visible
+   * @type {boolean}
+   */
+  isSectionVisible: function () {
+    return !this.get('isHiddenByFilter') && this.get('configs').someProperty('isVisible', true);
+  }.property('isHiddenByFilter', 'configs.@each.isVisible')
 });
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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
index ac1dcc7..69de315 100644
--- a/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
+++ b/ambari-web/app/templates/common/configs/service_config_layout_tab.hbs
@@ -29,7 +29,7 @@
                 {{#each subRow in section.subsectionRows}}
                   <tr>
                     {{#each subsection in subRow}}
-                      <td {{bindAttr class="subsection.isHiddenByFilter:invisible subsection.showTopSplitter:top-horizontal-splitter:no-horizontal-splitter :config-subsection" colspan="subsection.columnSpan" rowspan="subsection.rowSpan"}}>
+                      <td {{bindAttr class="subsection.isSectionVisible::invisible subsection.showTopSplitter:top-horizontal-splitter:no-horizontal-splitter :config-subsection" colspan="subsection.columnSpan" rowspan="subsection.rowSpan"}}>
                         <div {{bindAttr class="subsection.addLeftVerticalSplitter:vertical-splitter-l"}}>
                           <div {{bindAttr class="subsection.border:with-border"}}>
                             <h5 class="subsection-display-name">
@@ -40,9 +40,11 @@
                             </h5>
                             {{#each config in subsection.configs}}
                               {{#if config.widget}}
-                                {{#unless config.isHiddenByFilter}}
-                                  {{view config.widget configBinding="config" canEditBinding="view.canEdit" sectionBinding="section" subSectionBinding="subsection" tabBinding="tab"}}
-                                {{/unless}}
+                                {{#if config.isVisible}}
+                                  {{#unless config.isHiddenByFilter}}
+                                    {{view config.widget configBinding="config" canEditBinding="view.canEdit" sectionBinding="section" subSectionBinding="subsection" tabBinding="tab"}}
+                                  {{/unless}}
+                                {{/if}}
                               {{/if}}
                             {{/each}}
                           </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/templates/common/configs/widgets/test_db_connection_widget.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/widgets/test_db_connection_widget.hbs b/ambari-web/app/templates/common/configs/widgets/test_db_connection_widget.hbs
new file mode 100644
index 0000000..1cd4aaf
--- /dev/null
+++ b/ambari-web/app/templates/common/configs/widgets/test_db_connection_widget.hbs
@@ -0,0 +1,35 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+<div class="entry-row db-connection">
+  <span class="control-label"></span>
+
+  <div class="controls">
+    <div class="control-group">
+      <div class="span9">
+        <span {{bindAttr class=":pull-left :btn :btn-primary view.isBtnDisabled:disabled"}} {{action connectToDatabase target="view"}}>{{view.btnCaption}}</span>
+
+        <div class="pull-left connection-result mll">
+          <a {{bindAttr class="view.isConnectionSuccess:mute:action"}} {{action showLogsPopup target="view"}}>{{view.responseCaption}}</a>
+        </div>
+        <div {{bindAttr class=":spinner :mll :pull-left view.isConnecting::hide"}}></div>
+        <i {{bindAttr class=":pull-right view.isConnectionSuccess:icon-ok-sign:icon-warning-sign view.isRequestResolved::hide"}}></i>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 51dfd8c..fc47221 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -208,16 +208,17 @@ App.config = Em.Object.create({
 
   /**
    * generates config objects
-   * @param configCategories
+   * @param configGroups
    * @param serviceName
    * @param selectedConfigGroup
    * @param canEdit
    * @returns {Array}
    */
-  mergePredefinedWithSaved: function (configCategories, serviceName, selectedConfigGroup, canEdit) {
+  mergePredefinedWithSaved: function (configGroups, serviceName, selectedConfigGroup, canEdit) {
     var configs = [];
+    var serviceConfigProperty;
 
-    configCategories.forEach(function (siteConfig) {
+    configGroups.forEach(function (siteConfig) {
       var service = this.getServiceByConfigType(siteConfig.type);
       if (service && serviceName != 'MISC') {
         serviceName = service.get('serviceName');
@@ -227,11 +228,22 @@ App.config = Em.Object.create({
       var finalAttributes = attributes.final || {};
       var properties = siteConfig.properties || {};
 
+      var uiOnlyConfigsObj = {};
+      var uiOnlyConfigDerivedFromTheme = App.uiOnlyConfigDerivedFromTheme.toArray();
+      uiOnlyConfigDerivedFromTheme.forEach(function(item) {
+        if (filename === item.filename) {
+          uiOnlyConfigsObj[item.name] = item.value;
+        }
+      });
+      properties = $.extend({}, properties, uiOnlyConfigsObj);
+
       for (var index in properties) {
         var id = this.configId(index, siteConfig.type);
-        var configsPropertyDef = this.get('preDefinedSitePropertiesMap')[id];
+        var preDefinedPropertyDef = this.get('preDefinedSitePropertiesMap')[id];
+        var uiOnlyConfigFromTheme = uiOnlyConfigDerivedFromTheme.findProperty('name', index);
+        var configsPropertyDef =  preDefinedPropertyDef  || uiOnlyConfigFromTheme;
         var advancedConfig = App.StackConfigProperty.find(id);
-        var isStackProperty = !!advancedConfig.get('id') || !!configsPropertyDef;
+        var isStackProperty = !!advancedConfig.get('id') || !!preDefinedPropertyDef;
         var template = this.createDefaultConfig(index, serviceName, filename, isStackProperty, configsPropertyDef);
         var serviceConfigObj = isStackProperty ? this.mergeStaticProperties(template, advancedConfig) : template;
 
@@ -340,8 +352,10 @@ App.config = Em.Object.create({
   mergeStaticProperties: function(coreObject, stackProperty, preDefined, propertiesToSkip) {
     propertiesToSkip = propertiesToSkip || ['name', 'filename', 'value', 'savedValue', 'isFinal', 'savedIsFinal'];
     for (var k in coreObject) {
-      if (!propertiesToSkip.contains(k)) {
-        coreObject[k] = this.getPropertyIfExists(k, coreObject[k], stackProperty, preDefined);
+      if (coreObject.hasOwnProperty(k)) {
+        if (!propertiesToSkip.contains(k)) {
+          coreObject[k] = this.getPropertyIfExists(k, coreObject[k], stackProperty, preDefined);
+        }
       }
     }
     return coreObject;
@@ -522,19 +536,22 @@ App.config = Em.Object.create({
     }).reduce(function(p,c) { return p.concat(c); }).concat(['cluster-env', 'alert_notification'])
       .uniq().compact().filter(function(configType) { return !!configType; });
 
+    // ui only required configs from theme are required to show configless widgets (widget that are not related to a config)
     var predefinedIds = Object.keys(this.get('preDefinedSitePropertiesMap'));
+    var uiOnlyConfigDerivedFromTheme =  App.uiOnlyConfigDerivedFromTheme.mapProperty('name');
     var stackIds = App.StackConfigProperty.find().filterProperty('isValueDefined').mapProperty('id');
 
-    var configIds = stackIds.concat(predefinedIds).uniq();
+    var configIds = stackIds.concat(predefinedIds).concat(uiOnlyConfigDerivedFromTheme).uniq();
 
     configIds.forEach(function(id) {
 
       var preDefined = this.get('preDefinedSitePropertiesMap')[id];
+      var isUIOnlyFromTheme = App.uiOnlyConfigDerivedFromTheme.findProperty('name',id);
       var advanced = App.StackConfigProperty.find(id);
 
-      var name = preDefined ? preDefined.name : advanced.get('name');
-      var filename = preDefined ? preDefined.filename : advanced.get('filename');
-      var isUIOnly = Em.getWithDefault(preDefined || {}, 'isRequiredByAgent', true) === false;
+      var name = preDefined ? preDefined.name : isUIOnlyFromTheme ? isUIOnlyFromTheme.get('name') : advanced.get('name');
+      var filename = preDefined ? preDefined.filename : isUIOnlyFromTheme ? isUIOnlyFromTheme.get('filename') : advanced.get('filename');
+      var isUIOnly = (Em.getWithDefault(preDefined || {}, 'isRequiredByAgent', true) === false) || isUIOnlyFromTheme;
       /*
         Take properties that:
           - UI specific only, marked with <code>isRequiredByAgent: false</code>
@@ -546,9 +563,9 @@ App.config = Em.Object.create({
       if (!(uiPersistentProperties.contains(id) || isUIOnly || advanced.get('id')) && filename != 'alert_notification') {
         return;
       }
-      var serviceName = preDefined ? preDefined.serviceName : advanced.get('serviceName');
+      var serviceName = preDefined ? preDefined.serviceName : isUIOnlyFromTheme ? isUIOnlyFromTheme.get('serviceName') : advanced.get('serviceName');
       if (configTypes.contains(this.getConfigTagFromFileName(filename))) {
-        var configData = this.createDefaultConfig(name, serviceName, filename, true, preDefined || {});
+        var configData = this.createDefaultConfig(name, serviceName, filename, true, preDefined || isUIOnlyFromTheme || {});
         if (configData.recommendedValue) {
           configData.value = configData.recommendedValue;
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 3e12998..33403a3 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -67,6 +67,7 @@ require('views/common/configs/widgets/string_config_widget_view');
 require('views/common/configs/widgets/textfield_config_widget_view');
 require('views/common/configs/widgets/time_interval_spinner_view');
 require('views/common/configs/widgets/toggle_config_widget_view');
+require('views/common/configs/widgets/test_db_connection_widget_view');
 require('views/common/configs/widgets/overrides/config_widget_override_view');
 require('views/common/configs/widgets/comparison/config_widget_comparison_view');
 require('views/common/configs/service_config_layout_tab_view');

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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
index b3d69ee..6815a0d 100644
--- 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
@@ -64,7 +64,8 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, {
     'text-field': App.TextFieldConfigWidgetView,
     'time-interval-spinner': App.TimeIntervalSpinnerView,
     toggle: App.ToggleConfigWidgetView,
-    'text-area': App.StringConfigWidgetView
+    'text-area': App.StringConfigWidgetView,
+    'test-db-connection': App.TestDbConnectionWidgetView
   },
 
   /**
@@ -83,8 +84,11 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, {
       row.forEach(function (section) {
         section.get('subsectionRows').forEach(function (subRow) {
           subRow.forEach(function (subsection) {
+            var subsectionName = subsection.get('name');
+            var uiOnlyConfigs = App.uiOnlyConfigDerivedFromTheme.filterProperty('subSection.name', subsectionName);
+
             subsection.set('configs', []);
-            subsection.get('configProperties').forEach(function (config) {
+            subsection.get('configProperties').toArray().concat(uiOnlyConfigs).forEach(function (config) {
 
               var service = self.get('controller.stepConfigs').findProperty('serviceName', serviceName);
               if (!service) return;
@@ -95,10 +99,22 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, {
               var configWidgetType = config.get('widget.type');
               var widget = widgetTypeMap[configWidgetType];
               Em.assert('Unknown config widget view for config ' + configProperty.get('id') + ' with type ' + configWidgetType, widget);
-              configProperty.setProperties({
+
+              var additionalProperties = {
                 widget: widget,
                 stackConfigProperty: config
-              });
+              };
+
+              var configConditions = App.ConfigCondition.find().filter(function(_configCondition){
+                var conditionalConfigs = _configCondition.get('configs').filterProperty('fileName', config.get('filename')).filterProperty('configName', config.get('name'));
+                return (conditionalConfigs && conditionalConfigs.length);
+              }, this);
+
+              if (configConditions && configConditions.length) {
+                additionalProperties.configConditions = configConditions;
+              }
+              configProperty.setProperties(additionalProperties);
+
               if (configProperty.get('overrides')) {
                 configProperty.get('overrides').setEach('stackConfigProperty', config);
               }

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/views/common/configs/widgets/config_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/widgets/config_widget_view.js b/ambari-web/app/views/common/configs/widgets/config_widget_view.js
index 354a44e..30c942b 100644
--- a/ambari-web/app/views/common/configs/widgets/config_widget_view.js
+++ b/ambari-web/app/views/common/configs/widgets/config_widget_view.js
@@ -375,6 +375,56 @@ App.ConfigWidgetView = Em.View.extend(App.SupportsDependentConfigs, App.WidgetPo
     this.initIncompatibleWidgetAsTextBox();
   },
 
+  willInsertElement: function() {
+    var configConditions = this.get('config.configConditions');
+    if (configConditions && configConditions.length) {
+      this.configValueObserver();
+      this.addObserver('config.value', this, this.configValueObserver);
+    }
+  },
+
+  willDestroyElement: function() {
+    if (this.get('config.configConditions')) {
+      this.removeObserver('config.value', this, this.configValueObserver);
+    }
+  },
+
+  configValueObserver: function() {
+    var configConditions = this.get('config.configConditions');
+    var serviceName = this.get('config.serviceName');
+    var serviceConfigs = this.get('controller.stepConfigs').findProperty('serviceName',serviceName).get('configs');
+    configConditions.forEach(function(configCondition){
+      var ifCondition =  configCondition.get("if");
+      var conditionalConfigName = configCondition.get("configName");
+      var conditionalConfigFileName = configCondition.get("fileName");
+      var parseIfConditionVal = ifCondition;
+      var regex = /\$\{.*?\}/g;
+      var configStrings = ifCondition.match(regex);
+      configStrings.forEach(function(_configString){
+        var configObject = _configString.substring(2, _configString.length-1).split("/");
+        var config = serviceConfigs.filterProperty('filename',configObject[0] + '.xml').findProperty('name', configObject[1]);
+        if (config) {
+          var configValue = config.get('value');
+          parseIfConditionVal = parseIfConditionVal.replace(_configString, configValue);
+        }
+      }, this);
+
+      var isConditionTrue =  Boolean(window.eval(parseIfConditionVal));
+      var action = isConditionTrue ? configCondition.get("then") : configCondition.get("else");
+      var valueAttributes = action.property_value_attributes;
+      for (var key in valueAttributes) {
+        if (valueAttributes.hasOwnProperty(key)) {
+          var valueAttribute = App.StackConfigValAttributesMap[key] || key;
+          var conditionalConfig = serviceConfigs.filterProperty('filename',conditionalConfigFileName).findProperty('name', conditionalConfigName);
+          if (conditionalConfig) {
+            conditionalConfig.set(valueAttribute, valueAttributes[key]);
+          }
+        }
+      }
+    }, this);
+  },
+
+
   /**
    * set widget value same as config value
    * useful for widgets that work with intermediate config value, not original

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js b/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js
index d33cd13..fe3cf89 100644
--- a/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js
+++ b/ambari-web/app/views/common/configs/widgets/password_config_widget_view.js
@@ -30,6 +30,7 @@ App.PasswordConfigWidgetView = App.ConfigWidgetView.extend({
   }),
 
   didInsertElement: function() {
+    this._super();
     this.set('config.displayType', this.get('config.stackConfigProperty.widget.type'));
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/app/views/common/configs/widgets/test_db_connection_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/widgets/test_db_connection_widget_view.js b/ambari-web/app/views/common/configs/widgets/test_db_connection_widget_view.js
new file mode 100644
index 0000000..d22cb1f
--- /dev/null
+++ b/ambari-web/app/views/common/configs/widgets/test_db_connection_widget_view.js
@@ -0,0 +1,364 @@
+/**
+ * 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.
+ */
+
+require('views/common/controls_view');
+
+var App = require('app');
+
+App.TestDbConnectionWidgetView = App.ConfigWidgetView.extend({
+  templateName: require('templates/common/configs/widgets/test_db_connection_widget'),
+  classNames: ['widget'],
+
+  /** @property {string} btnCaption - text for button **/
+  btnCaption: function () {
+    return this.get('config.stackConfigProperty.widget.display-name');
+  }.property('config.stackConfigProperty.widget.display-name'),
+  /** @property {string} responseCaption - text for status link **/
+  responseCaption: null,
+  /** @property {boolean} isConnecting - is request to server activated **/
+  isConnecting: false,
+  /** @property {boolean} isValidationPassed - check validation for required fields **/
+  isValidationPassed: null,
+  /** @property {string} db_type- name of current database **/
+  db_type: null,
+  /** @property {boolean} isRequestResolved - check for finished request to server **/
+  isRequestResolved: false,
+  /** @property {boolean} isConnectionSuccess - check for successful connection to database **/
+  isConnectionSuccess: null,
+  /** @property {string} responseFromServer - message from server response **/
+  responseFromServer: null,
+  /** @property {Object} ambariRequiredProperties - properties that need for custom action request **/
+  ambariRequiredProperties: null,
+  /** @property {Number} currentRequestId - current custom action request id **/
+  currentRequestId: null,
+  /** @property {Number} currentTaskId - current custom action task id **/
+  currentTaskId: null,
+  /** @property {jQuery.Deferred} request - current $.ajax request **/
+  request: null,
+  /** @property {Number} pollInterval - timeout interval for ajax polling **/
+  pollInterval: 3000,
+  /** @property {Object} logsPopup - popup with DB connection check info **/
+  logsPopup: null,
+  /** @property {Array} or {String} masterHostName: The name of hosts from which the db connection will happen**/
+  masterHostName: null,
+  /** @property {String} db_connection_url: The jdbc urlfor performing db connection**/
+  db_connection_url: null,
+  /** @property {String} user_name: The user name to be used for performing db connection**/
+  user_name: null,
+  /** @property {String} user_passwd: password for the  user name to be used for performing db connection**/
+  user_passwd: null,
+
+  /** @property {boolean} isBtnDisabled - disable button on failed validation or active request **/
+  isBtnDisabled: function () {
+    return !this.get('requiredProperties').everyProperty('isValid') || this.get('isConnecting');
+  }.property('requiredProperties.@each.isValid', 'isConnecting'),
+  /** @property {object} requiredProperties - properties that necessary for database connection **/
+  requiredProperties: [],
+
+  /** Check validation and load ambari properties **/
+  didInsertElement: function () {
+    var requiredProperties = this.get('config.stackConfigProperty.widget.required-properties');
+    var serviceName = this.get('config.serviceName');
+    var serviceConfigs = this.get('controller.stepConfigs').findProperty('serviceName',serviceName).get('configs');
+    var requiredServiceConfigs = Object.keys(requiredProperties).map(function(key){
+      var split = requiredProperties[key].split('/');
+      var fileName =  split[0] + '.xml';
+      var configName = split[1];
+      return serviceConfigs.filterProperty('filename',fileName).findProperty('name', configName);
+    }, this);
+
+    this.set('requiredProperties', requiredServiceConfigs);
+    this.setDbProperties(requiredProperties);
+    this.getAmbariProperties();
+  },
+
+  /** On view destroy **/
+  willDestroyElement: function () {
+    this.set('isConnecting', false);
+    this._super();
+  },
+
+
+  /**
+   *  This function is used to set Database name and master host name
+   * @param requiredProperties
+   */
+  setDbProperties: function(requiredProperties) {
+    var dbInfo = require('data/db_properties_info');
+    var dbProperties = {
+      'db.connection.source.host' : 'masterHostName',
+      'db.type' : 'db_type',
+      'db.connection.user': 'user_name',
+      'db.connection.password': 'user_passwd',
+      'jdbc.driver.url': 'db_connection_url'
+    };
+
+    for (var key in dbProperties) {
+      var masterHostNameProperty = requiredProperties[key];
+      var split = masterHostNameProperty.split('/');
+      var fileName =  split[0] + '.xml';
+      var configName =  split[1];
+      var dbConfig = this.get('requiredProperties').filterProperty('filename',fileName).findProperty('name', configName);
+      if (key === 'db.type') {
+        dbConfig = dbInfo.dpPropertiesMap[dbConfig.value].db_type.toUpperCase();
+      }
+      this.set(dbProperties[key], dbConfig);
+    }
+  },
+
+
+  /**
+   * Set up ambari properties required for custom action request
+   *
+   * @method getAmbariProperties
+   **/
+  getAmbariProperties: function () {
+    var clusterController = App.router.get('clusterController');
+    var _this = this;
+    if (!App.isEmptyObject(App.db.get('tmp', 'ambariProperties')) && !this.get('ambariProperties')) {
+      this.set('ambariProperties', App.db.get('tmp', 'ambariProperties'));
+      return;
+    }
+    if (App.isEmptyObject(clusterController.get('ambariProperties'))) {
+      clusterController.loadAmbariProperties().done(function (data) {
+        _this.formatAmbariProperties(data.RootServiceComponents.properties);
+      });
+    } else {
+      this.formatAmbariProperties(clusterController.get('ambariProperties'));
+    }
+  },
+
+  formatAmbariProperties: function (properties) {
+    var defaults = {
+      threshold: "60",
+      ambari_server_host: location.hostname,
+      check_execute_list: "db_connection_check"
+    };
+    var properties = App.permit(properties, ['jdk.name', 'jdk_location', 'java.home']);
+    var renameKey = function (oldKey, newKey) {
+      if (properties[oldKey]) {
+        defaults[newKey] = properties[oldKey];
+        delete properties[oldKey];
+      }
+    };
+    renameKey('java.home', 'java_home');
+    renameKey('jdk.name', 'jdk_name');
+    $.extend(properties, defaults);
+    App.db.set('tmp', 'ambariProperties', properties);
+    this.set('ambariProperties', properties);
+  },
+  /**
+   * `Action` method for starting connect to current database.
+   *
+   * @method connectToDatabase
+   **/
+  connectToDatabase: function () {
+    if (this.get('isBtnDisabled')) return;
+    this.set('isRequestResolved', false);
+    this.setConnectingStatus(true);
+    if (App.get('testMode')) {
+      this.startPolling();
+    } else {
+      this.runCheckConnection();
+    }
+  },
+
+  /**
+   * runs check connections methods depending on service
+   * @return {void}
+   * @method runCheckConnection
+   */
+  runCheckConnection: function () {
+    this.createCustomAction();
+  },
+
+
+  /**
+   * Run custom action for database connection.
+   *
+   * @method createCustomAction
+   **/
+  createCustomAction: function () {
+    var connectionProperties = this.getProperties('db_connection_url','user_name', 'user_passwd');
+    for (var key in connectionProperties) {
+      if (connectionProperties.hasOwnProperty(key)) {
+        connectionProperties[key] = connectionProperties[key].value;
+      }
+    }
+    var params = $.extend(true, {}, {db_name: this.get('db_type').toLowerCase()}, connectionProperties, this.get('ambariProperties'));
+    var filteredHosts =  Array.isArray(this.get('masterHostName.value')) ? this.get('masterHostName.value') : [this.get('masterHostName.value')];
+    App.ajax.send({
+      name: 'custom_action.create',
+      sender: this,
+      data: {
+        requestInfo: {
+          parameters: params
+        },
+        filteredHosts: filteredHosts
+      },
+      success: 'onCreateActionSuccess',
+      error: 'onCreateActionError'
+    });
+  },
+  /**
+   * Run updater if task is created successfully.
+   *
+   * @method onConnectActionS
+   **/
+  onCreateActionSuccess: function (data) {
+    this.set('currentRequestId', data.Requests.id);
+    App.ajax.send({
+      name: 'custom_action.request',
+      sender: this,
+      data: {
+        requestId: this.get('currentRequestId')
+      },
+      success: 'setCurrentTaskId'
+    });
+  },
+
+  setCurrentTaskId: function (data) {
+    this.set('currentTaskId', data.items[0].Tasks.id);
+    this.startPolling();
+  },
+
+  startPolling: function () {
+    if (this.get('isConnecting'))
+      this.getTaskInfo();
+  },
+
+  getTaskInfo: function () {
+    var request = App.ajax.send({
+      name: 'custom_action.request',
+      sender: this,
+      data: {
+        requestId: this.get('currentRequestId'),
+        taskId: this.get('currentTaskId')
+      },
+      success: 'getTaskInfoSuccess'
+    });
+    this.set('request', request);
+  },
+
+  getTaskInfoSuccess: function (data) {
+    var task = data.Tasks;
+    this.set('responseFromServer', {
+      stderr: task.stderr,
+      stdout: task.stdout
+    });
+    if (task.status === 'COMPLETED') {
+      var structuredOut = task.structured_out.db_connection_check;
+      if (structuredOut.exit_code != 0) {
+        this.set('responseFromServer', {
+          stderr: task.stderr,
+          stdout: task.stdout,
+          structuredOut: structuredOut.message
+        });
+        this.setResponseStatus('failed');
+      } else {
+        this.setResponseStatus('success');
+      }
+    }
+    if (task.status === 'FAILED') {
+      this.setResponseStatus('failed');
+    }
+    if (/PENDING|QUEUED|IN_PROGRESS/.test(task.status)) {
+      Em.run.later(this, function () {
+        this.startPolling();
+      }, this.get('pollInterval'));
+    }
+  },
+
+  onCreateActionError: function (jqXhr, status, errorMessage) {
+    this.setResponseStatus('failed');
+    this.set('responseFromServer', errorMessage);
+  },
+
+  setResponseStatus: function (isSuccess) {
+    var isSuccess = isSuccess == 'success';
+    this.setConnectingStatus(false);
+    this.set('responseCaption', isSuccess ? Em.I18n.t('services.service.config.database.connection.success') : Em.I18n.t('services.service.config.database.connection.failed'));
+    this.set('isConnectionSuccess', isSuccess);
+    this.set('isRequestResolved', true);
+    if (this.get('logsPopup')) {
+      var statusString = isSuccess ? 'common.success' : 'common.error';
+      this.set('logsPopup.header', Em.I18n.t('services.service.config.connection.logsPopup.header').format(this.get('db_type'), Em.I18n.t(statusString)));
+    }
+  },
+  /**
+   * Switch captions and statuses for active/non-active request.
+   *
+   * @method setConnectionStatus
+   * @param {Boolean} [active]
+   */
+  setConnectingStatus: function (active) {
+    if (active) {
+      this.set('responseCaption', Em.I18n.t('services.service.config.database.connection.inProgress'));
+    }
+    this.set('controller.testConnectionInProgress', !!active);
+    this.set('btnCaption', !!active ? Em.I18n.t('services.service.config.database.btn.connecting') : Em.I18n.t('services.service.config.database.btn.idle'));
+    this.set('isConnecting', !!active);
+  },
+  /**
+   * Set view to init status.
+   *
+   * @method restore
+   **/
+  restore: function () {
+    if (this.get('request')) {
+      this.get('request').abort();
+      this.set('request', null);
+    }
+    this.set('responseCaption', null);
+    this.set('responseFromServer', null);
+    this.setConnectingStatus(false);
+    this.set('isRequestResolved', false);
+  },
+  /**
+   * `Action` method for showing response from server in popup.
+   *
+   * @method showLogsPopup
+   **/
+  showLogsPopup: function () {
+    if (this.get('isConnectionSuccess')) return;
+    var _this = this;
+    var statusString = this.get('isRequestResolved') ? 'common.error' : 'common.testing';
+    var popup = App.showAlertPopup(Em.I18n.t('services.service.config.connection.logsPopup.header').format(this.get('db_type'), Em.I18n.t(statusString)), null, function () {
+      _this.set('logsPopup', null);
+    });
+    popup.reopen({
+      onClose: function () {
+        this._super();
+        _this.set('logsPopup', null);
+      }
+    });
+    if (typeof this.get('responseFromServer') == 'object') {
+      popup.set('bodyClass', Em.View.extend({
+        checkDBConnectionView: _this,
+        templateName: require('templates/common/error_log_body'),
+        openedTask: function () {
+          return this.get('checkDBConnectionView.responseFromServer');
+        }.property('checkDBConnectionView.responseFromServer.stderr', 'checkDBConnectionView.responseFromServer.stdout', 'checkDBConnectionView.responseFromServer.structuredOut')
+      }));
+    } else {
+      popup.set('body', this.get('responseFromServer'));
+    }
+    this.set('logsPopup', popup);
+    return popup;
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/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 7e6d35f..99456e0 100644
--- a/ambari-web/test/mappers/configs/themes_mapper_test.js
+++ b/ambari-web/test/mappers/configs/themes_mapper_test.js
@@ -188,6 +188,8 @@ describe('App.themeMapper', function () {
         "row_index": "0",
         "row_span": "1",
         "column_index": "0",
+        "depends_on": [],
+        "left_vertical_splitter": true,
         "column_span": "1",
         "section_id": "Section-1"
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/61540bbb/ambari-web/test/models/configs/section_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/configs/section_test.js b/ambari-web/test/models/configs/section_test.js
index c8f2ebf..055c532 100644
--- a/ambari-web/test/models/configs/section_test.js
+++ b/ambari-web/test/models/configs/section_test.js
@@ -56,24 +56,24 @@ describe('App.Section', function () {
         },
         {
           subSections: [
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: false}, {isHiddenByFilter: false}]}),
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: false}, {isHiddenByFilter: false}]})
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: false, isVisible: true}, {isHiddenByFilter: false, isVisible: true}]}),
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: false, isVisible: true}, {isHiddenByFilter: false, isVisible: true}]})
           ],
           m: 'no subsections are hidden',
           e: false
         },
         {
           subSections: [
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: true}, {isHiddenByFilter: true}]}),
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: false}, {isHiddenByFilter: false}]})
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: true, isVisible: true}, {isHiddenByFilter: true, isVisible: true}]}),
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: false, isVisible: true}, {isHiddenByFilter: false, isVisible: true}]})
           ],
           m: 'one subsection is hidden',
           e: false
         },
         {
           subSections: [
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: true}, {isHiddenByFilter: true}]}),
-            App.SubSection.createRecord({configs: [{isHiddenByFilter: true}, {isHiddenByFilter: true}]})
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: true, isVisible: true}, {isHiddenByFilter: true, isVisible: true}]}),
+            App.SubSection.createRecord({configs: [{isHiddenByFilter: true, isVisible: true}, {isHiddenByFilter: true, isVisible: true}]})
           ],
           m: 'all subsections are hidden',
           e: true


Mime
View raw message