You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2015/09/30 16:46:00 UTC
[40/50] [abbrv] ambari git commit: AMBARI-13263. Create a Ranger
theme with Ranger Admin. (jaimin)
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 <ja...@hortonworks.com>
Authored: Mon Sep 28 20:22:26 2015 -0700
Committer: Jaimin Jetly <ja...@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