You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2016/03/22 18:49:45 UTC
[2/2] ambari git commit: AMBARI-15503. Hive interactive component
should be created/deleted when interactive query is enabled/disabled.
(jaimin)
AMBARI-15503. Hive interactive component should be created/deleted when interactive query is enabled/disabled. (jaimin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/da7f00c4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/da7f00c4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/da7f00c4
Branch: refs/heads/trunk
Commit: da7f00c4432d3299be8895243a867af7a5fcb57f
Parents: 6b933cc
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Tue Mar 22 10:49:20 2016 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Tue Mar 22 10:49:20 2016 -0700
----------------------------------------------------------------------
.../stacks/HDP/2.6/role_command_order.json | 10 +
.../HIVE/configuration/hive-interactive-env.xml | 131 ++++
.../configuration/hive-interactive-site.xml | 301 +++++++--
.../services/HIVE/configuration/llap-env.xml | 72 --
.../stacks/HDP/2.6/services/HIVE/metainfo.xml | 2 +-
.../HDP/2.6/services/HIVE/themes/theme.json | 76 ---
.../services/HIVE/themes/theme_version_2.json | 666 +++++++++++++++++++
.../controllers/main/service/info/configs.js | 20 +-
.../wizard/step7/assign_master_controller.js | 222 +++++--
.../app/controllers/wizard/step7_controller.js | 52 +-
ambari-web/app/mappers/configs/themes_mapper.js | 6 +
ambari-web/app/messages.js | 6 +-
ambari-web/app/mixins.js | 1 +
.../app/mixins/common/configs/configs_saver.js | 30 +-
.../configs/component_actions_by_configs.js | 277 ++++++++
.../mixins/wizard/assign_master_components.js | 46 +-
.../app/models/configs/theme/config_action.js | 35 +-
.../common/assign_master_components.hbs | 2 +-
.../configs/widgets/label_config_widget.hbs | 24 +
ambari-web/app/utils/ajax/ajax.js | 22 +
ambari-web/app/utils/configs/theme/theme.js | 2 +-
ambari-web/app/views.js | 1 +
.../common/assign_master_components_view.js | 2 +
.../configs/service_config_layout_tab_view.js | 8 +
.../configs/widgets/config_widget_view.js | 65 +-
.../configs/widgets/label_config_widget_view.js | 38 ++
.../widgets/time_interval_spinner_view.js | 2 +-
.../views/wizard/step7/assign_master_view.js | 18 +
.../test/controllers/wizard/step5_test.js | 71 +-
.../wizard/assign_master_components_test.js | 6 +-
30 files changed, 1864 insertions(+), 350 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json b/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
new file mode 100644
index 0000000..613a076
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/role_command_order.json
@@ -0,0 +1,10 @@
+{
+ "_comment" : "Record format:",
+ "_comment" : "blockedRole-blockedCommand: [blockerRole1-blockerCommand1, blockerRole2-blockerCommand2, ...]",
+ "general_deps" : {
+ "_comment" : "dependencies for all cases",
+ "HIVE_SERVER_INTERACTIVE-START": ["NODEMANAGER-START", "MYSQL_SERVER-START"],
+ "HIVE_SERVER_INTERACTIVE-RESTART": ["NODEMANAGER-RESTART", "MYSQL_SERVER-RESTART"],
+ "HIVE_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START", "HIVE_METASTORE-START", "WEBHCAT_SERVER-START", "HIVE_SERVER_INTERACTIVE-START"]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
new file mode 100644
index 0000000..d518c8b
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-env.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<configuration supports_adding_forbidden="true">
+ <property>
+ <name>enable_hive_interactive</name>
+ <value>false</value>
+ <description>Enable or disable interactive query in this cluster.</description>
+ <display-name>Enable Interactive Query</display-name>
+ <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>
+ <name>hive_server_interactive_host</name>
+ <value>localhost</value>
+ <description>HiveServer2 Interactive Host</description>
+ <display-name>HiveServer2 Interactive Host</display-name>
+ <value-attributes>
+ <overridable>false</overridable>
+ </value-attributes>
+ </property>
+ <property>
+ <name>llap_queue_capacity</name>
+ <value>0</value>
+ <description>Percentage of the cluster dedicated to interactive query.</description>
+ <display-name>% of Cluster Capacity</display-name>
+ <value-attributes>
+ <type>int</type>
+ <minimum>0</minimum>
+ <maximum>100</maximum>
+ <increment-step>1</increment-step>
+ </value-attributes>
+ </property>
+ <property>
+ <name>num_llap_nodes</name>
+ <value>1</value>
+ <description>The number of Hive LLAP daemons to run.</description>
+ <display-name>Number of Daemon Instances</display-name>
+ <value-attributes>
+ <type>int</type>
+ <minimum>0</minimum>
+ <maximum>8</maximum>
+ <increment-step>1</increment-step>
+ </value-attributes>
+ </property>
+
+ <!-- hive-env.sh -->
+ <property>
+ <name>content</name>
+ <description>This is the jinja template for hive-env.sh file</description>
+ <value>
+ if [ "$SERVICE" = "cli" ]; then
+ if [ -z "$DEBUG" ]; then
+ export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:+UseParNewGC -XX:-UseGCOverheadLimit"
+ else
+ export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-UseGCOverheadLimit"
+ fi
+ fi
+
+ # The heap size of the jvm stared by hive shell script can be controlled via:
+
+ if [ "$SERVICE" = "metastore" ]; then
+ export HADOOP_HEAPSIZE={{hive_metastore_heapsize}} # Setting for HiveMetastore
+ else
+ export HADOOP_HEAPSIZE={{hive_heapsize}} # Setting for HiveServer2 and Client
+ fi
+
+ export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Xmx${HADOOP_HEAPSIZE}m"
+
+ # Larger heap size may be required when running queries over large number of files or partitions.
+ # By default hive shell scripts use a heap size of 256 (MB). Larger heap size would also be
+ # appropriate for hive server (hwi etc).
+
+
+ # Set HADOOP_HOME to point to a specific hadoop install directory
+ HADOOP_HOME=${HADOOP_HOME:-{{hadoop_home}}}
+
+ # Hive Configuration Directory can be controlled by:
+ export HIVE_CONF_DIR={{hive_server_interactive_conf_dir}}
+
+ # Folder containing extra ibraries required for hive compilation/execution can be controlled by:
+ # if [ "${HIVE_AUX_JARS_PATH}" != "" ]; then
+ # export HIVE_AUX_JARS_PATH=${HIVE_AUX_JARS_PATH}
+ # elif [ -d "/usr/lib/hive-hcatalog/" ]; then
+ # export HIVE_AUX_JARS_PATH=/usr/lib/hive-hcatalog/share/hcatalog/hive-hcatalog-core-*.jar
+ # else
+ # export HIVE_AUX_JARS_PATH=/usr/lib/hcatalog/share/hcatalog/hcatalog-core.jar
+ # fi
+ export METASTORE_PORT={{hive_metastore_port}}
+
+ export HADOOP_CLASSPATH={{atlas_conf_dir}}:{{atlas_home_dir}}/hook/hive:${HADOOP_CLASSPATH}
+
+ </value>
+ <value-attributes>
+ <type>content</type>
+ </value-attributes>
+ </property>
+
+</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
index fb55d2d..face571 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
@@ -74,7 +74,7 @@ limitations under the License.
</description>
</property>
- <property>
+ <property>
<name>hive.heapsize</name>
<value>1024</value>
<display-name>HiveServer2 heap size</display-name>
@@ -201,8 +201,11 @@ limitations under the License.
<property>
<name>hive.metastore.uris</name>
- <value>thrift://localhost:9083</value>
+ <value></value>
<description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description>
+ <value-attributes>
+ <empty-value-valid>true</empty-value-valid>
+ </value-attributes>
</property>
<property>
@@ -363,7 +366,7 @@ limitations under the License.
<property>
<name>hive.server2.enable.doAs</name>
- <value>true</value>
+ <value>false</value>
<description>
Setting this property to true will have HiveServer2 execute
Hive operations as the user making the calls to it.
@@ -441,13 +444,6 @@ limitations under the License.
</property>
<property>
- <name>hive.server2.enable.impersonation</name>
- <value>true</value>
- <deleted>true</deleted>
- <description>Enable user impersonation for HiveServer2</description>
- </property>
-
- <property>
<name>fs.hdfs.impl.disable.cache</name>
<value>true</value>
<description>Disable HDFS filesystem cache.</description>
@@ -523,39 +519,6 @@ limitations under the License.
</property>
<property>
- <name>hive.enforce.bucketing</name>
- <value>true</value>
- <description>Whether bucketing is enforced. If true, while inserting into the table, bucketing is enforced.</description>
- <display-name>Enforce bucketing</display-name>
- <value-attributes>
- <type>value-list</type>
- <entries>
- <entry>
- <value>true</value>
- <label>True</label>
- </entry>
- <entry>
- <value>false</value>
- <label>False</label>
- </entry>
- </entries>
- <selection-cardinality>1</selection-cardinality>
- </value-attributes>
- <depends-on>
- <property>
- <type>hive-env</type>
- <name>hive_txn_acid</name>
- </property>
- </depends-on>
- </property>
-
- <property>
- <name>hive.enforce.sorting</name>
- <value>true</value>
- <description>Whether sorting is enforced. If true, while inserting into the table, sorting is enforced.</description>
- </property>
-
- <property>
<name>hive.enforce.sortmergebucketmapjoin</name>
<value>true</value>
<description>If the user asked for sort-merge bucketed map-side join, and it cannot be performed, should the query fail or not ?</description>
@@ -1143,6 +1106,7 @@ limitations under the License.
</property>
<property>
+ <!-- This is different for Hive batch and interactive -->
<name>hive.prewarm.enabled</name>
<value>false</value>
<description>Enables container prewarm for Tez (Hadoop 2 only)</description>
@@ -1261,7 +1225,7 @@ limitations under the License.
<selection-cardinality>1</selection-cardinality>
</value-attributes>
<depends-on>
- <property>
+ <property>
<type>hive-site</type>
<name>hive.cbo.enable</name>
</property>
@@ -1270,12 +1234,12 @@ limitations under the License.
<property>
<name>hive.tez.container.size</name>
- <value>682</value>
+ <value>341</value>
<description>By default, Tez uses the java options from map tasks. Use this property to override that value.</description>
<display-name>Tez Container Size</display-name>
<value-attributes>
<type>int</type>
- <minimum>682</minimum>
+ <minimum>341</minimum>
<maximum>6820</maximum>
<unit>MB</unit>
<increment-step>682</increment-step>
@@ -1300,8 +1264,11 @@ limitations under the License.
<property>
<name>hive.tez.java.opts</name>
- <value>-server -Xmx545m -Djava.net.preferIPv4Stack=true -XX:NewRatio=8 -XX:+UseNUMA -XX:+UseParallelGC -XX:+PrintGCDetails -verbose:gc -XX:+PrintGCTimeStamps</value>
+ <value></value>
<description>Java command line options for Tez. The -Xmx parameter value is generally 80% of hive.tez.container.size.</description>
+ <value-attributes>
+ <empty-value-valid>true</empty-value-valid>
+ </value-attributes>
</property>
<property>
@@ -1462,7 +1429,7 @@ limitations under the License.
<property>
<name>hive.vectorized.execution.reduce.enabled</name>
- <value>false</value>
+ <value>true</value>
<description>
This flag should be set to true to enable vectorized mode of the reduce-side of
query execution.
@@ -1573,11 +1540,9 @@ limitations under the License.
<name>hive.server2.tez.sessions.per.default.queue</name>
<value>1</value>
<description>
- A positive integer that determines the number of Tez sessions that should be
- launched on each of the queues specified by "hive.server2.tez.default.queues".
- Determines the parallelism on each queue.
+ The maximum number of queries this Hive LLAP cluster will be able to handle concurrently.
</description>
- <display-name>Session per queue</display-name>
+ <display-name>Maximum Concurrent Queries</display-name>
<value-attributes>
<type>int</type>
<minimum>1</minimum>
@@ -1588,7 +1553,7 @@ limitations under the License.
<property>
<name>hive.server2.tez.initialize.default.sessions</name>
- <value>false</value>
+ <value>true</value>
<description>
This flag is used in HiveServer2 to enable a user to use HiveServer2 without
turning on Tez for HiveServer2. The user could potentially want to run queries
@@ -1612,6 +1577,29 @@ limitations under the License.
</property>
<property>
+ <name>hive.driver.parallel.compilation</name>
+ <value>true</value>
+ <description>
+ This flag allows HiveServer2 to compile queries in parallel.
+ </description>
+ <display-name>Compile queries in parallel</display-name>
+ <value-attributes>
+ <type>value-list</type>
+ <entries>
+ <entry>
+ <value>true</value>
+ <label>True</label>
+ </entry>
+ <entry>
+ <value>false</value>
+ <label>False</label>
+ </entry>
+ </entries>
+ <selection-cardinality>1</selection-cardinality>
+ </value-attributes>
+ </property>
+
+ <property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager</value>
<description/>
@@ -1830,6 +1818,12 @@ limitations under the License.
</property>
<property>
+ <name>hive.server2.webui.port </name>
+ <value>10502</value>
+ <description>Web UI port address</description>
+ </property>
+
+ <property>
<name>hive.server2.allow.user.substitution</name>
<value>true</value>
<description>Allow alternate user to be specified as part of HiveServer2 open connection request.</description>
@@ -1932,7 +1926,7 @@ limitations under the License.
<property>
<name>hive.server2.zookeeper.namespace</name>
- <value>hiveserver2</value>
+ <value>hiveserver2-hive2</value>
<description>The parent node in ZooKeeper used by HiveServer2 when supporting dynamic service discovery.</description>
</property>
@@ -2038,4 +2032,203 @@ limitations under the License.
</description>
</property>
+ <property>
+ <name>hive.llap.daemon.queue.name</name>
+ <value>default</value>
+ <description>Choose the YARN queue in this cluster that is dedicated to interactive query.</description>
+ <display-name>Interactive Query Queue</display-name>
+ <value-attributes>
+ <type>combo</type>
+ <entries>
+ <entry>
+ <value>default</value>
+ <label>Default</label>
+ </entry>
+ </entries>
+ <selection-cardinality>1</selection-cardinality>
+ </value-attributes>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.yarn.shuffle.port</name>
+ <value>15551</value>
+ </property>
+
+ <property>
+ <name>hive.execution.mode</name>
+ <value>llap</value>
+ </property>
+
+ <property>
+ <name>hive.llap.execution.mode</name>
+ <value>all</value>
+ </property>
+
+ <property>
+ <name>hive.llap.io.enabled</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.llap.io.use.lrfu</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.llap.auto.allow.uber</name>
+ <value>false</value>
+ </property>
+
+ <property>
+ <name>hive.llap.object.cache.enabled</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.tez.input.generate.consistent.splits</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.llap.client.consistent.splits</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.llap.task.scheduler.locality.delay</name>
+ <value>-1</value>
+ </property>
+
+ <property>
+ <name>hive.exec.orc.split.strategy</name>
+ <value>HYBRID</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.service.hosts</name>
+ <value>@llap0</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.allow.permanent.fns</name>
+ <value>false</value>
+ </property>
+
+ <property>
+ <name>hive.llap.io.memory.size</name>
+ <display-name>Cache Size</display-name>
+ <description>The amount of data reserved for Hive's optimized in-memory cache.</description>
+ <value>20000000</value>
+ <value-attributes>
+ <type>int</type>
+ <minimum>0</minimum>
+ <maximum>268435456</maximum>
+ <unit>MB</unit>
+ <increment-step>256</increment-step>
+ <overridable>false</overridable>
+ </value-attributes>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.num.executors</name>
+ <display-name>Number of Executors</display-name>
+ <description>Number of execution threads per Hive LLAP daemon. Generally this should be set to number of CPU cores.</description>
+ <value>1</value>
+ <value-attributes>
+ <type>int</type>
+ <minimum>0</minimum>
+ <maximum>8</maximum>
+ <increment-step>1</increment-step>
+ </value-attributes>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.memory.per.instance.mb</name>
+ <value>250</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.vcpus.per.instance</name>
+ <value>${hive.llap.daemon.num.executors}</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.yarn.container.mb</name>
+ <display-name>Total Daemon Size</display-name>
+ <description>The memory per node to be used by Hive LLAP.</description>
+ <value>341</value>
+ <value-attributes>
+ <type>int</type>
+ <minimum>0</minimum>
+ <maximum>268435456</maximum>
+ <unit>MB</unit>
+ <increment-step>256</increment-step>
+ <overridable>false</overridable>
+ </value-attributes>
+ </property>
+
+ <property>
+ <name>llap.shuffle.connection-keep-alive.enable</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>llap.shuffle.connection-keep-alive.timeout</name>
+ <value>60</value>
+ </property>
+
+ <property>
+ <name>hive.llap.io.threadpool.size</name>
+ <value>4</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.rpc.port</name>
+ <value>15001</value>
+ </property>
+ <property>
+ <name>hive.llap.management.rpc.port</name>
+ <value>15004</value>
+ </property>
+
+ <property>
+ <name>hive.llap.daemon.task.scheduler.enable.preemption</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.tez.exec.print.summary</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.vectorized.execution.mapjoin.native.enabled</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.vectorized.execution.mapjoin.minmax.enabled</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.vectorized.execution.mapjoin.native.fast.hashtable.enabled</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.mapjoin.hybridgrace.hashtable</name>
+ <value>false</value>
+ </property>
+
+ <property>
+ <name>hive.tez.bucket.pruning</name>
+ <value>true</value>
+ </property>
+
+ <property>
+ <name>hive.optimize.dynamic.partition.hashjoin</name>
+ <value>true</value>
+ </property>
+
</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
deleted file mode 100644
index 24a95cf..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/llap-env.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
-<!--
-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.
--->
-<configuration supports_final="false" supports_adding_forbidden="true">
- <property>
- <name>enable_hive_interactive</name>
- <value>false</value>
- <description>Enable or disable interactive query in this cluster.</description>
- <display-name>Enable Interactive Query</display-name>
- <value-attributes>
- <type>value-list</type>
- <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>
- <name>llap_queue_name</name>
- <value>default</value>
- <description>LLAP Queue Name.</description>
- <display-name>LLAP Queue Name</display-name>
- <value-attributes>
- <type>combo</type>
- <entries>
- <entry>
- <value>default</value>
- <label>Default</label>
- </entry>
- </entries>
- <selection-cardinality>1</selection-cardinality>
- </value-attributes>
- </property>
- <property>
- <name>llap_am_queue_name</name>
- <value>default</value>
- <description>LLAP AM Queue Name.</description>
- <display-name>LLAP AM Queue Name</display-name>
- <value-attributes>
- <type>combo</type>
- <entries>
- <entry>
- <value>default</value>
- <label>Default</label>
- </entry>
- </entries>
- <selection-cardinality>1</selection-cardinality>
- </value-attributes>
- </property>
-</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
index ff0f318..f0918c5 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/metainfo.xml
@@ -99,7 +99,7 @@
</components>
<themes>
<theme>
- <fileName>theme.json</fileName>
+ <fileName>theme_version_2.json</fileName>
<default>true</default>
</theme>
</themes>
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
deleted file mode 100644
index 26b9532..0000000
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "configuration" : {
- "placement" : {
- "configs" : [
- {
- "config": "llap-env/enable_hive_interactive",
- "subsection-name": "interactive-query-row1-col1"
- },
- {
- "config": "llap-env/llap_queue_name",
- "subsection-name": "interactive-query-row1-col1",
- "depends-on": [
- {
- "configs":[
- "llap-env/enable_hive_interactive"
- ],
- "if": "${llap-env/enable_hive_interactive}",
- "then": {
- "property_value_attributes": {
- "visible": true
- }
- },
- "else": {
- "property_value_attributes": {
- "visible": false
- }
- }
- }
- ]
- },
- {
- "config": "llap-env/llap_am_queue_name",
- "subsection-name": "interactive-query-row1-col1",
- "depends-on": [
- {
- "configs":[
- "llap-env/enable_hive_interactive"
- ],
- "if": "${llap-env/enable_hive_interactive}",
- "then": {
- "property_value_attributes": {
- "visible": true
- }
- },
- "else": {
- "property_value_attributes": {
- "visible": false
- }
- }
- }
- ]
- }
- ]
- },
- "widgets" : [
- {
- "config": "llap-env/enable_hive_interactive",
- "widget": {
- "type": "toggle"
- }
- },
- {
- "config": "llap-env/llap_queue_name",
- "widget": {
- "type": "list"
- }
- },
- {
- "config": "llap-env/llap_am_queue_name",
- "widget": {
- "type": "list"
- }
- }
- ]
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
new file mode 100644
index 0000000..64450a8
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/themes/theme_version_2.json
@@ -0,0 +1,666 @@
+{
+ "name": "default",
+ "description": "Default theme for HIVE service",
+ "configuration": {
+ "layouts": [
+ {
+ "name": "default",
+ "tabs": [
+ {
+ "name": "settings",
+ "display-name": "Settings",
+ "layout": {
+ "tab-rows": 6,
+ "tab-columns": 3,
+ "sections": [
+ {
+ "name": "acid-transactions",
+ "display-name": "ACID Transactions",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1",
+ "section-columns": "1",
+ "section-rows": "1",
+ "subsections": [
+ {
+ "name": "acid-transactions-row1-col1-1",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1"
+ }
+ ]
+ },
+ {
+ "name": "interactive-query",
+ "display-name": "Interactive Query",
+ "row-index": "0",
+ "column-index": "1",
+ "row-span": "1",
+ "column-span": "1",
+ "section-columns": "1",
+ "section-rows": "1",
+ "subsections": [
+ {
+ "name": "interactive-query-row1-col1",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1"
+ }
+ ]
+ },
+ {
+ "name": "security",
+ "display-name": "Security",
+ "row-index": "0",
+ "column-index": "2",
+ "row-span": "1",
+ "column-span": "1",
+ "section-columns": "1",
+ "section-rows": "1",
+ "subsections": [
+ {
+ "name": "security-row1-col1",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1"
+ }
+ ]
+ },
+ {
+ "name": "optimization",
+ "display-name": "Optimization",
+ "row-index": "1",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "3",
+ "section-columns": "3",
+ "section-rows": "2",
+ "subsections": [
+ {
+ "name": "optimization-row1-col1",
+ "display-name": "Tez",
+ "row-index": "0",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1"
+ },
+ {
+ "name": "optimization-row1-col2",
+ "display-name": "",
+ "row-index": "0",
+ "column-index": "1",
+ "row-span": "1",
+ "column-span": "1"
+ },
+ {
+ "name": "optimization-row1-col3",
+ "display-name": "CBO",
+ "row-index": "0",
+ "column-index": "2",
+ "row-span": "1",
+ "column-span": "1"
+ },
+ {
+ "name": "optimization-row2-col1",
+ "display-name": "Storage",
+ "row-index": "1",
+ "column-index": "0",
+ "row-span": "1",
+ "column-span": "1"
+ },
+ {
+ "name": "optimization-row2-col2",
+ "display-name": "",
+ "row-index": "1",
+ "column-index": "1",
+ "row-span": "1",
+ "column-span": "1"
+ },
+ {
+ "name": "optimization-row2-col3",
+ "display-name": "Memory",
+ "row-index": "1",
+ "column-index": "2",
+ "row-span": "1",
+ "column-span": "1"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "placement": {
+ "configuration-layout": "default",
+ "configs": [
+ {
+ "config": "hive-site/hive.exec.orc.default.stripe.size",
+ "subsection-name": "optimization-row2-col1"
+ },
+ {
+ "config": "hive-site/hive.exec.orc.default.compress",
+ "subsection-name": "optimization-row2-col1"
+ },
+ {
+ "config": "hive-env/hive_exec_orc_storage_strategy",
+ "subsection-name": "optimization-row2-col1"
+ },
+ {
+ "config": "hive-env/hive.heapsize",
+ "subsection-name": "optimization-row2-col2"
+ },
+ {
+ "config": "hive-env/hive.metastore.heapsize",
+ "subsection-name": "optimization-row2-col2"
+ },
+ {
+ "config": "hive-env/hive.client.heapsize",
+ "subsection-name": "optimization-row2-col2"
+ },
+ {
+ "config": "hive-site/hive.auto.convert.join.noconditionaltask.size",
+ "subsection-name": "optimization-row2-col3"
+ },
+ {
+ "config": "hive-site/hive.exec.reducers.bytes.per.reducer",
+ "subsection-name": "optimization-row2-col3"
+ },
+ {
+ "config": "hive-env/hive_txn_acid",
+ "subsection-name": "acid-transactions-row1-col1-1"
+ },
+ {
+ "config": "hive-site/hive.compactor.initiator.on",
+ "subsection-name": "acid-transactions-row1-col1-1"
+ },
+ {
+ "config": "hive-site/hive.compactor.worker.threads",
+ "subsection-name": "acid-transactions-row1-col1-1"
+ },
+ {
+ "config": "hive-interactive-env/enable_hive_interactive",
+ "subsection-name": "interactive-query-row1-col1"
+ },
+ {
+ "config": "hive-interactive-env/hive_server_interactive_host",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.queue.name",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-env/llap_queue_capacity",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-env/num_llap_nodes",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.yarn.container.mb",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.io.memory.size",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.num.executors",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-interactive-site/hive.server2.tez.sessions.per.default.queue",
+ "subsection-name": "interactive-query-row1-col1",
+ "depends-on": [
+ {
+ "configs":[
+ "hive-interactive-env/enable_hive_interactive"
+ ],
+ "if": "${hive-interactive-env/enable_hive_interactive}",
+ "then": {
+ "property_value_attributes": {
+ "visible": true
+ }
+ },
+ "else": {
+ "property_value_attributes": {
+ "visible": false
+ }
+ }
+ }
+ ]
+ },
+ {
+ "config": "hive-site/hive.execution.engine",
+ "subsection-name": "optimization-row1-col1"
+ },
+ {
+ "config": "hive-site/hive.tez.container.size",
+ "subsection-name": "optimization-row1-col1"
+ },
+ {
+ "config": "hive-site/hive.prewarm.enabled",
+ "subsection-name": "optimization-row1-col2"
+ },
+ {
+ "config": "hive-site/hive.prewarm.numcontainers",
+ "subsection-name": "optimization-row1-col2"
+ },
+ {
+ "config": "hive-site/hive.cbo.enable",
+ "subsection-name": "optimization-row1-col3"
+ },
+ {
+ "config": "hive-site/hive.stats.fetch.column.stats",
+ "subsection-name": "optimization-row1-col3"
+ },
+ {
+ "config": "hive-env/hive_security_authorization",
+ "subsection-name": "security-row1-col1"
+ },
+ {
+ "config": "hive-site/hive.server2.enable.doAs",
+ "subsection-name": "security-row1-col1"
+ },
+ {
+ "config": "hive-site/hive.server2.authentication",
+ "subsection-name": "security-row1-col1"
+ },
+ {
+ "config": "hive-site/hive.server2.use.SSL",
+ "subsection-name": "security-row1-col1"
+ }
+ ]
+ },
+ "widgets": [
+ {
+ "config": "hive-site/hive.exec.orc.default.stripe.size",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.exec.orc.default.compress",
+ "widget": {
+ "type": "combo"
+ }
+ },
+ {
+ "config": "hive-env/hive_exec_orc_storage_strategy",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-env/hive.heapsize",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-env/hive.metastore.heapsize",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-env/hive.client.heapsize",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.auto.convert.join.noconditionaltask.size",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.exec.reducers.bytes.per.reducer",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-env/hive_txn_acid",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-site/hive.compactor.initiator.on",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-site/hive.compactor.worker.threads",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-env/enable_hive_interactive",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-interactive-env/hive_server_interactive_host",
+ "widget": {
+ "type": "label"
+ }
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.queue.name",
+ "widget": {
+ "type": "list"
+ }
+ },
+ {
+ "config": "hive-interactive-env/num_llap_nodes",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-env/llap_queue_capacity",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "percent"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.yarn.container.mb",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "GB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.io.memory.size",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "GB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-site/hive.llap.daemon.num.executors",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-interactive-site/hive.server2.tez.sessions.per.default.queue",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.execution.engine",
+ "widget": {
+ "type": "combo"
+ }
+ },
+ {
+ "config": "hive-site/hive.tez.container.size",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "MB"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.prewarm.enabled",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-site/hive.prewarm.numcontainers",
+ "widget": {
+ "type": "slider",
+ "units": [
+ {
+ "unit-name": "int"
+ }
+ ]
+ }
+ },
+ {
+ "config": "hive-site/hive.cbo.enable",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-site/hive.stats.fetch.column.stats",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-site/hive.server2.enable.doAs",
+ "widget": {
+ "type": "toggle"
+ }
+ },
+ {
+ "config": "hive-env/hive_security_authorization",
+ "widget": {
+ "type": "combo"
+ }
+ },
+ {
+ "config": "hive-site/hive.server2.authentication",
+ "widget": {
+ "type": "combo"
+ }
+ },
+ {
+ "config": "hive-site/hive.server2.use.SSL",
+ "widget": {
+ "type": "toggle"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/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 93775fb..8c855fc 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -20,7 +20,7 @@ var App = require('app');
var batchUtils = require('utils/batch_scheduled_requests');
var databaseUtils = require('utils/configs/database');
-App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.VersionsMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, {
+App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.VersionsMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, App.ComponentActionsByConfigs, {
name: 'mainServiceInfoConfigsController',
@@ -301,8 +301,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
// This requires calling `loadCurrentVersions` after theme has loaded
self.loadCurrentVersions();
});
- }
- else {
+ } else {
this.loadCurrentVersions();
}
this.loadServiceConfigVersions();
@@ -558,6 +557,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
serviceConfig.get('configs').push(App.ServiceConfigProperty.create(hProperty));
}
}, this);
+
+ App.ConfigAction.find().forEach(function(item){
+ var hostComponentConfig = item.get('hostComponentConfig');
+ var config = serviceConfig.get('configs').filterProperty('filename', hostComponentConfig.fileName).findProperty('name', hostComponentConfig.configName);
+ if (config){
+ var componentHostName = App.HostComponent.find().findProperty('componentName', item.get('componentName')) ;
+ if (componentHostName) {
+ var setConfigValue = !config.get('value');
+ if (setConfigValue) {
+ config.set('value', componentHostName.get('hostName'));
+ config.set('recommendedValue', componentHostName.get('hostName'));
+ }
+ }
+ }
+ }, this);
},
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step7/assign_master_controller.js b/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
index 496968b..57230c4 100644
--- a/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
+++ b/ambari-web/app/controllers/wizard/step7/assign_master_controller.js
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+var stringUtils = require('utils/string_utils');
+
App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App.AssignMasterComponents, {
name:"assignMasterOnStep7Controller",
@@ -24,7 +26,13 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
showInstalledMastersFirst: false,
- deferred: null,
+ configWidgetContext: {},
+
+ configActionComponent: {},
+
+ content: function() {
+ return (this.get('configWidgetContext.controller.content') || {});
+ }.property('configWidgetContext.controller.content'),
popup: null,
@@ -32,35 +40,46 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
markSavedComponentsAsInstalled: true,
- execute: function(context) {
- var dfd = $.Deferred();
- this.set('content', context.get('content'));
- var allConfigs = context.get('stepConfigs').mapProperty('configs').filter(function(item) {
- return item.length;
- }).reduce(function(p, c) {
- if (p) {
- return p.concat(c);
- }
- });
- var storedConfigs = this.get('content.serviceConfigProperties');
- var configThemeActions = App.configTheme.getConfigThemeActions(allConfigs, storedConfigs || []);
-
- if (configThemeActions['add'].length) {
- this.showAssignComponentPopup(dfd, configThemeActions['add']);
- } else {
- if (configThemeActions['delete'].length) {
- this.removeMasterComponent(configThemeActions['delete']);
- }
- dfd.resolve();
+ /**
+ * Marks component add/delete action to be performed ahead.
+ * @param context {Object} Context of the calling function
+ * @param action {String} ADD|DELETE
+ * @param hostComponent {Object}
+ * @public
+ * @method {execute}
+ */
+ execute: function(context, action, hostComponent) {
+ this.set('configWidgetContext', context);
+ this.set('content', context.get('controller.content'));
+ this.set('configActionComponent',hostComponent);
+ this.set('mastersToCreate', [hostComponent.componentName]);
+ var missingDependentServices = this.getAllMissingDependentServices();
+ var isNonWizardPage = !this.get('content.controllerName');
+ switch(action) {
+ case 'ADD':
+ if (missingDependentServices.length && isNonWizardPage) {
+ this.showInstallServicesPopup(missingDependentServices);
+ } else {
+ this.showAssignComponentPopup();
+ }
+ break;
+ case 'DELETE':
+ this.removeMasterComponent();
+ break;
}
- return dfd.promise();
},
- showAssignComponentPopup: function(dfd, componentsToAdd) {
+ /**
+ * Assign Master page will be displayed in the popup
+ * @private
+ * @method
+ */
+ showAssignComponentPopup: function() {
var self = this;
- this.set('deferred', dfd);
- this.set('mastersToCreate', componentsToAdd);
-
+ // Master component hosts should be loaded only when content.controller name is not defined i.e non-wizard pages
+ if (!this.get('content.controllerName')) {
+ this.loadMasterComponentHosts();
+ }
var popup = App.ModalPopup.show({
classNames: ['full-width-modal', 'add-service-wizard-modal'],
header: Em.I18n.t('admin.highAvailability.wizard.step2.header'),
@@ -70,38 +89,159 @@ App.AssignMasterOnStep7Controller = Em.Controller.extend(App.BlueprintMixin, App
primary: Em.I18n.t('form.cancel'),
showFooter: false,
secondary: null,
- onClose: function () {
- this.hide();
- },
+ showCloseButton: false,
didInsertElement: function () {
this._super();
this.fitHeight();
+ self.set('configWidgetContext.controller.saveInProgress', false);
}
});
this.set('popup', popup);
},
- removeMasterComponent: function(componentsToDelete) {
- var parentController = App.router.get(this.get('content.controllerName'));
- var masterComponentHosts = this.get('content.masterComponentHosts');
- componentsToDelete.forEach(function(_componentName) {
- masterComponentHosts = masterComponentHosts.rejectProperty('component',_componentName);
- }, this);
- this.get('content').set('masterComponentHosts', masterComponentHosts);
- parentController.setDBProperty('masterComponentHosts', masterComponentHosts);
+ /**
+ * Displays the popup to install required service dependencies for being added component with this config change
+ * @param missingDependentServices {String[]} Array of service display names
+ */
+ showInstallServicesPopup: function(missingDependentServices) {
+ var self = this;
+ var displayServices = stringUtils.getFormattedStringFromArray(missingDependentServices);
+ var configWidgetContext = this.get('configWidgetContext');
+ var config = self.get('configWidgetContext.config');
+ var configDisplayName = config.get('displayName').toLowerCase();
+ App.ModalPopup.show({
+ header: Em.I18n.t('installer.step7.missing.service.header'),
+ body: Em.I18n.t('installer.step7.missing.service.body').format(displayServices, configDisplayName),
+ primaryClass: 'btn-danger',
+ onPrimary: function () {
+ var value = config.get('initialValue');
+ config.set('value', value);
+ configWidgetContext.setValue(value);
+ this._super();
+ },
+ secondary: null,
+ showCloseButton: false,
+ didInsertElement: function () {
+ this._super();
+ configWidgetContext.set('controller.saveInProgress', false);
+ }
+ });
+ },
+
+ /**
+ * This method is used while installing or adding a service
+ * Removes the masterComponent that was previously being tracked to be added to the cluster
+ * @private
+ * @method {removeMasterComponent}
+ */
+ removeMasterComponent: function() {
+ var componentsToDelete = this.get('mastersToCreate');
+ if (this.get('content.controllerName')) {
+ var parentController = App.router.get(this.get('content.controllerName'));
+ var masterComponentHosts = this.get('content.masterComponentHosts');
+ componentsToDelete.forEach(function (_componentName) {
+ masterComponentHosts = masterComponentHosts.rejectProperty('component', _componentName);
+ }, this);
+ this.get('content').set('masterComponentHosts', masterComponentHosts);
+ parentController.setDBProperty('masterComponentHosts', masterComponentHosts);
+ }
+ var configActionComponent = this.get('configActionComponent');
+ this.get('configWidgetContext.config').set('configActionComponent', configActionComponent);
+ },
+
+ /**
+ * Load active host list to <code>hosts</code> variable
+ * @override
+ * @method renderHostInfo
+ */
+ renderHostInfo: function () {
+ var numberUtils = require('utils/number_utils');
+ var parentController = this.get('content.controllerName');
+ if (parentController) {
+ this._super();
+ } else {
+ var hosts = App.Host.find().toArray();
+ var result = [];
+ for (var p = 0; p < hosts.length; p++) {
+ result.push(Em.Object.create({
+ host_name: hosts[p].get('hostName'),
+ cpu: hosts[p].get('cpu'),
+ memory: hosts[p].get('memory'),
+ disk_info: hosts[p].get('diskInfo'),
+ host_info: Em.I18n.t('installer.step5.hostInfo').fmt(hosts[p].get('hostName'), numberUtils.bytesToSize(hosts[p].get('memory'), 1, 'parseFloat', 1024), hosts[p].get('cpu'))
+ }));
+ }
+
+ this.set("hosts", result);
+ this.sortHosts(this.get('hosts'));
+ this.set('isLoaded', true);
+ }
},
/**
+ * This method is called on Service->config page and is responsible to load the "Assign Master popup"
+ * with the installed master component hosts.
+ * @private
+ * @method {loadMasterComponentHosts}
+ */
+ loadMasterComponentHosts: function () {
+ var stackMasterComponents = App.get('components.masters').uniq();
+ var masterComponentHosts = [];
+ App.HostComponent.find().filter(function(component) {
+ return stackMasterComponents.contains(component.get('componentName'));
+ }).forEach(function (item) {
+ masterComponentHosts.push({
+ component: item.get('componentName'),
+ hostName: item.get('hostName'),
+ isInstalled: true,
+ serviceId: item.get('service.id'),
+ display_name: item.get('displayName')
+ })
+ });
+ this.set("masterComponentHosts", masterComponentHosts);
+ },
+
+ /**
+ * Returns array of dependent services that are yet not installed in the cluster
+ * @private
+ * @method getAllMissingDependentServices
+ * @return missingDependentServices {Array}
+ */
+ getAllMissingDependentServices: function() {
+ var context = this.get('configWidgetContext');
+ var configActionComponentName = this.get('configActionComponent').componentName;
+ var componentStackService = App.StackServiceComponent.find(configActionComponentName).get('stackService');
+ var dependentServices = componentStackService.get('requiredServices');
+ var missingDependentServices = dependentServices.filter(function(item) {
+ return !App.Service.find().findProperty('serviceName', item);
+ }).map(function(item){
+ return App.StackService.find(item).get('displayName');
+ });
+ return missingDependentServices;
+ },
+
+
+ /**
* Submit button click handler
* @method submit
*/
submit: function () {
- if (this.get('deferred')) {
- this.get('popup').hide();
+ this.get('popup').hide();
+ if (this.get('content.controllerName')) {
var controller = App.router.get(this.get('content.controllerName'));
controller.saveMasterComponentHosts(this);
- this.get('deferred').resolve();
- this.set('deferred', null);
}
+ var selectedServicesMasters = this.get('selectedServicesMasters');
+ var context = this.get('configWidgetContext');
+ var configActionComponent = this.get('configActionComponent');
+ var componentHostName = selectedServicesMasters.findProperty('component_name',configActionComponent.componentName).selectedHost;
+
+ var hostComponentConfig = context.get('config.configAction.hostComponentConfig');
+ var serviceConfigs = context.get('controller.stepConfigs').findProperty('serviceName', context.get('config.serviceName')).get('configs');
+ var config = serviceConfigs.filterProperty('filename', hostComponentConfig.fileName).findProperty('name', hostComponentConfig.configName);
+ config.set('value', componentHostName);
+ config.set('recommendedValue', componentHostName);
+ configActionComponent.hostName = componentHostName;
+ this.get('configWidgetContext.config').set('configActionComponent', configActionComponent);
}
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/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 06488b1..9113ea2 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -526,11 +526,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
var service = App.config.get('serviceByConfigTypeMap')[App.config.getConfigTagFromFileName(serviceConfigProperty.get('filename'))];
serviceConfigProperty.set('isEditable', service && !this.get('installedServiceNames').contains(service.get('serviceName')));
} else {
- serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
+ serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isEditable') && serviceConfigProperty.get('isReconfigurable'));
}
- } else if (Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') == this.get('selectedConfigGroup.name')) {
- serviceConfigProperty.set('isEditable', true);
- } else {
+ } else if (!(Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') == this.get('selectedConfigGroup.name'))) {
serviceConfigProperty.set('isEditable', false);
}
}
@@ -690,8 +688,11 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
var stepConfigs = this.createStepConfigs();
var serviceConfigs = this.renderConfigs(stepConfigs, configs);
// if HA is enabled -> Make some reconfigurations
- if (this.get('wizardController.name') === 'addServiceController' && App.get('isHaEnabled')) {
- serviceConfigs = this._reconfigureServicesOnNnHa(serviceConfigs);
+ if (this.get('wizardController.name') === 'addServiceController') {
+ this.updateComponentActionConfigs(configs, serviceConfigs);
+ if (App.get('isHaEnabled')) {
+ serviceConfigs = this._reconfigureServicesOnNnHa(serviceConfigs);
+ }
}
this.set('stepConfigs', serviceConfigs);
this.checkHostOverrideInstaller();
@@ -704,6 +705,31 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
this.loadConfigRecommendations(null, this.completeConfigLoading.bind(this));
},
+ /**
+ *
+ * Makes installed service's configs resulting into component actions (add/delete) non editable on Add Service Wizard
+ * @param configs Object[]
+ * @param stepConfigs Object[]
+ * @private
+ * @method updateComponentActionConfigs
+ */
+ updateComponentActionConfigs: function(configs, stepConfigs) {
+ App.ConfigAction.find().forEach(function(item){
+ var configName = item.get('configName');
+ var fileName = item.get('fileName');
+ var config = configs.filterProperty('filename', fileName).findProperty('name', configName);
+ if (config) {
+ var isServiceInstalled = App.Service.find().findProperty('serviceName', config.serviceName);
+ if (isServiceInstalled) {
+ var serviceConfigs = stepConfigs.findProperty('serviceName', config.serviceName).get('configs');
+ var serviceConfig = serviceConfigs.filterProperty('filename', fileName).findProperty('name', configName);
+ serviceConfig.set('isEditable', false);
+ config.isEditable = false;
+ }
+ }
+ }, this);
+ },
+
completeConfigLoading: function() {
this.clearRecommendationsByServiceName(App.StackService.find().filterProperty('isSelected').mapProperty('serviceName'));
console.timeEnd('wizard loadStep: ');
@@ -1270,7 +1296,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
var isEditable = config.get('isEditable'),
isServiceInstalled = this.get('installedServiceNames').contains(this.get('selectedService.serviceName'));
if (isServiceInstalled) {
- isEditable = (!isEditable && !config.get('isReconfigurable')) ? false : selectedGroup.get('isDefault');
+ isEditable = (!isEditable || !config.get('isReconfigurable')) ? false : selectedGroup.get('isDefault');
}
else {
isEditable = selectedGroup.get('isDefault');
@@ -1620,24 +1646,18 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
* @method submit
*/
submit: function () {
- var self = this;
if (this.get('isSubmitDisabled') || App.router.nextBtnClickInProgress) {
return false;
}
- var assignMasterOnStep7Controller = App.router.get('assignMasterOnStep7Controller');
- var dfdPromise = assignMasterOnStep7Controller.execute(self);
-
if (this.get('supportsPreInstallChecks')) {
var preInstallChecksController = App.router.get('preInstallChecksController');
if (preInstallChecksController.get('preInstallChecksWhereRun')) {
- return dfdPromise.done(self.postSubmit.bind(self));
+ return this.postSubmit();
}
- return dfdPromise.done(function() {
- preInstallChecksController.notRunChecksWarnPopup(self.postSubmit.bind(self));
- });
+ return preInstallChecksController.notRunChecksWarnPopup(this.postSubmit.bind(this));
}
- return dfdPromise.done(self.postSubmit.bind(self));
+ return this.postSubmit();
},
postSubmit: function () {
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/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 3e68e67..6cba017 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -130,7 +130,9 @@ App.themesMapper = App.QuickDataMapper.create({
var type = 'subsectionTab';
this.mapThemeConditions(subSectionTabConditions, type);
}
+ App.store.commit();
App.store.loadMany(this.get("subSectionTabModel"), subSectionTabs);
+ App.store.commit();
parsedSubSection.sub_section_tabs = subSectionTabs.mapProperty("id");
}
if (parsedSubSection['depends_on']) {
@@ -142,14 +144,18 @@ App.themesMapper = App.QuickDataMapper.create({
var type = 'subsection';
this.mapThemeConditions(subSectionConditions, type);
}
+ App.store.commit();
App.store.loadMany(this.get("subSectionModel"), subSections);
+ App.store.commit();
parsedSection.sub_sections = subSections.mapProperty("id");
}
sections.push(parsedSection);
}, this);
+ App.store.commit();
App.store.loadMany(this.get("sectionModel"), sections);
+ App.store.commit();
parsedTab.sections = sections.mapProperty("id");
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 421143a..52e3b8e 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -321,6 +321,7 @@ Em.I18n.translations = {
'common.levels': 'Levels',
'common.extension': 'Extension',
'common.logs': 'Logs',
+ 'common.warn.message': '<div class="alert alert-warn">{0}</div>',
'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on {1}",
'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -853,7 +854,10 @@ Em.I18n.translations = {
'installer.step7.preInstallChecks.checksPopup.header':'Pre Install Checks',
- 'installer.step7.assign.master.body':'Assign {0} to {1} you want to run {2} on.',
+ 'installer.step7.assign.master.body':'Assign <strong>{0}</strong> to {1} you want to run {2} on.',
+ 'installer.step7.assign.master.dependent.component.body':'If not present {0} will also be installed on the selected host. ',
+ 'installer.step7.missing.service.header':'Missing Service',
+ 'installer.step7.missing.service.body': '{0} service should be added to the cluster to {1}.',
'installer.step8.header': 'Review',
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index 0a686b3..23d447b 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -39,6 +39,7 @@ require('mixins/main/service/themes_mapping');
require('mixins/main/service/versions_mapping');
require('mixins/main/service/configs/config_overridable');
require('mixins/main/service/configs/widget_popover_support');
+require('mixins/main/service/configs/component_actions_by_configs');
require('mixins/routers/redirections');
require('mixins/wizard/wizardProgressPageController');
require('mixins/wizard/wizardDeployProgressController');
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js
index 82741fa..ece8a2d 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -608,7 +608,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
* @method doPUTClusterConfigurationSiteSuccessCallback
*/
doPUTClusterConfigurationSiteSuccessCallback: function () {
- this.onDoPUTClusterConfigurations();
+ var doConfigActions = true;
+ this.onDoPUTClusterConfigurations(doConfigActions);
},
/**
@@ -617,16 +618,17 @@ App.ConfigsSaverMixin = Em.Mixin.create({
*/
doPUTClusterConfigurationSiteErrorCallback: function () {
this.set('saveConfigsFlag', false);
- this.doPUTClusterConfigurationSiteSuccessCallback();
+ this.onDoPUTClusterConfigurations();
},
/**
* On save configs handler. Open save configs popup with appropriate message
* and clear config dependencies list.
+ * @param {Boolean} doConfigActions
* @private
* @method onDoPUTClusterConfigurations
*/
- onDoPUTClusterConfigurations: function () {
+ onDoPUTClusterConfigurations: function (doConfigActions) {
var header, message, messageClass, value, status = 'unknown', urlParams = '',
result = {
flag: this.get('saveConfigsFlag'),
@@ -667,7 +669,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
// update configs for service actions
App.router.get('mainServiceItemController').loadConfigs();
- this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams);
+ this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams, doConfigActions);
this.clearAllRecommendations();
},
@@ -677,11 +679,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
* @private
* @method showSaveConfigsPopup
*/
- showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams) {
+ showSaveConfigsPopup: function (header, flag, message, messageClass, value, status, urlParams, doConfigActions) {
var self = this;
- if (flag) {
- self.loadStep();
- }
return App.ModalPopup.show({
header: header,
primary: Em.I18n.t('ok'),
@@ -767,12 +766,12 @@ App.ConfigsSaverMixin = Em.Mixin.create({
switch (status) {
case 'unknown':
response.items.filter(function (item) {
- return (item.ServiceComponentInfo.total_count > item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count);
+ return (item.ServiceComponentInfo.total_count > (item.ServiceComponentInfo.started_count + item.ServiceComponentInfo.installed_count));
}).forEach(function (item) {
var total = item.ServiceComponentInfo.total_count,
started = item.ServiceComponentInfo.started_count,
installed = item.ServiceComponentInfo.installed_count,
- unknown = total - started + installed;
+ unknown = total - (started + installed);
components = setComponents(item, components);
count += unknown;
});
@@ -796,7 +795,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
this.set('isLoaded', true);
},
didInsertElement: function () {
- return App.ajax.send({
+ var dfd = App.ajax.send({
name: 'components.filter_by_status',
sender: this,
data: {
@@ -806,6 +805,15 @@ App.ConfigsSaverMixin = Em.Mixin.create({
success: 'componentsFilterSuccessCallback',
error: 'componentsFilterErrorCallback'
});
+
+ dfd.done(function() {
+ if (doConfigActions && self.doConfigActions) {
+ self.doConfigActions.bind(self)();
+ if (flag) {
+ self.loadStep();
+ }
+ }
+ });
},
getDisplayMessage: function () {
var displayMsg = [];
http://git-wip-us.apache.org/repos/asf/ambari/blob/da7f00c4/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
new file mode 100644
index 0000000..7857411
--- /dev/null
+++ b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js
@@ -0,0 +1,277 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var stringUtils = require('utils/string_utils');
+
+/**
+ * Mixin with methods for component actions that needs to be done when a config with specific value is saved
+ * Used in the service config controller
+ * @type {Em.Mixin}
+ */
+App.ComponentActionsByConfigs = Em.Mixin.create({
+
+ /**
+ * Do component add/delete actions as inferred from value of service configs
+ * @public
+ * @method doConfigActions
+ */
+ doConfigActions: function() {
+ var serviceConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
+ var configActionComponents = serviceConfigs.filterProperty('configActionComponent');
+
+ this.doComponentDeleteActions(configActionComponents);
+ this.doComponentAddActions(configActionComponents);
+ },
+
+ /**
+ * Do component Delete actions as inferred from value of service config
+ * @param configActionComponents Object[]
+ * @private
+ * @method {configActionComponents}
+ */
+ doComponentDeleteActions: function(configActionComponents) {
+ var self = this;
+ var componentsToDelete = configActionComponents.filterProperty('configActionComponent.action', 'delete').map(function(item){
+ return item.configActionComponent;
+ }).filter(function(_componentToDelete){
+ return App.HostComponent.find().filterProperty('componentName',_componentToDelete.componentName).someProperty('hostName', _componentToDelete.hostName);
+ }, this);
+
+ if (componentsToDelete.length) {
+ componentsToDelete.forEach(function(_componentToDelete){
+ var displayName = App.StackServiceComponent.find().findProperty('componentName', _componentToDelete.componentName).get('displayName');
+ var context = Em.I18n.t('requestInfo.stop').format(displayName);
+ this.installHostComponents( _componentToDelete.hostName, _componentToDelete.componentName, context).done(function(data){
+ self.isRequestCompleted(data).done(function() {
+ self.deleteHostComponent(_componentToDelete.hostName, _componentToDelete.componentName);
+ });
+ });
+ }, this);
+ }
+ },
+
+ /**
+ * Do component Add actions as inferred from value of service config
+ * @param configActionComponents Object[]
+ * @private
+ * @method {doComponentAddActions}
+ */
+ doComponentAddActions: function(configActionComponents) {
+ var self = this;
+ var componentsToAdd = configActionComponents.filterProperty('configActionComponent.action', 'add').map(function(item){
+ return item.configActionComponent;
+ }).filter(function(_componentToAdd){
+ return !App.HostComponent.find().filterProperty('componentName',_componentToAdd.componentName).someProperty('hostName', _componentToAdd.hostName);
+ }, this);
+
+ var dependentComponents = [];
+ if (componentsToAdd.length) {
+ componentsToAdd.forEach(function(_component) {
+ var dependencies = App.StackServiceComponent.find(_component.componentName).get('dependencies').filterProperty('scope', 'host').map(function(_dependency){
+ return {
+ componentName: _dependency.componentName,
+ hostName: _component.hostName,
+ isClient: App.StackServiceComponent.find(_dependency.componentName).get('isClient')
+ }
+ }, this);
+ var dependenciesToInstall = dependencies.filter(function (_dependencyToAdd) {
+ var isInstalled = App.HostComponent.find().filterProperty('componentName', _dependencyToAdd.componentName).someProperty('hostName', _dependencyToAdd.hostName);
+ var isAddedToInstall = dependentComponents.filterProperty('componentName',_dependencyToAdd.componentName).someProperty('hostName', _dependencyToAdd.hostName);
+ return !(isInstalled || isAddedToInstall);
+ }, this);
+ dependentComponents = dependentComponents.concat(dependenciesToInstall);
+ }, this);
+ var allComponentsToAdd = componentsToAdd.concat(dependentComponents);
+ var allComponentsToAddHosts = allComponentsToAdd.mapProperty('hostName').uniq();
+ allComponentsToAddHosts.forEach(function(_hostName, index){
+ var hostComponents = allComponentsToAdd.filterProperty('hostName', _hostName).mapProperty('componentName').uniq();
+ var masterHostComponents = allComponentsToAdd.filterProperty('hostName', _hostName).filterProperty('isClient', false).mapProperty('componentName').uniq();
+ this.createHostComponents(_hostName, hostComponents).done(function(data){
+ self.installHostComponents(_hostName, hostComponents).done(function(data){
+ self.isRequestCompleted(data).done(function() {
+ var displayNames = masterHostComponents.map(function(item) {
+ return App.StackServiceComponent.find().findProperty('componentName', item).get('displayName');
+ });
+ var displayStr = stringUtils.getFormattedStringFromArray(displayNames);
+ var context = Em.I18n.t('requestInfo.start').format(displayStr);
+ self.startHostComponents(_hostName, masterHostComponents, context);
+ });
+ });
+ });
+ }, this);
+ }
+ },
+
+ /**
+ * Calls the API to create multiple components on a host
+ * @param hostName {String}
+ * @param components {String[]}|{String}
+ * @return {Object} Deferred promise
+ */
+ createHostComponents: function(hostName, components) {
+ var query = "Hosts/host_name.in(" + hostName + ")";
+ components = (Array.isArray(components)) ? components : [components];
+ var hostComponent = components.map(function(_componentName){
+ return {
+ "HostRoles":{
+ "component_name":_componentName
+ }
+ }
+ }, this);
+ return App.ajax.send({
+ name: 'common.host.host_components.create',
+ sender: this,
+ data: {
+ query: query,
+ host_components: hostComponent,
+ type: ''
+ }
+ });
+ },
+
+ /**
+ * Calls the API to install multiple components on a host
+ * @param hostName {String}
+ * @param components {String[]}
+ * @param context {String} Optional
+ * @return {Object} Deferred promise
+ */
+ installHostComponents: function(hostName, components, context) {
+ context = context || Em.I18n.t('requestInfo.installComponents');
+ return this.updateHostComponents(hostName, components, App.HostComponentStatus.stopped, context);
+ },
+
+ /**
+ * Calls the API to start multiple components on a host
+ * @param hostName {String}
+ * @param components {String[]}
+ * @param context {String} Optional
+ * @return {Object} Deferred promise
+ */
+ startHostComponents: function(hostName, components, context) {
+ context = context || Em.I18n.t('requestInfo.startHostComponents');
+ return this.updateHostComponents(hostName, components, App.HostComponentStatus.started, context);
+ },
+
+ /**
+ * Calls the API to start/stop multiple components on a host
+ * @param hostName {String}
+ * @param components
+ * @param desiredState
+ * @param context {String}
+ * @private
+ * @method {updateHostComponents}
+ * @return {Object} Deferred promise
+ */
+ updateHostComponents: function(hostName, components, desiredState, context) {
+ var data = {
+ hostName: hostName,
+ context: context,
+ HostRoles: {
+ state: desiredState
+ }
+ };
+ components = (Array.isArray(components)) ? components : [components];
+ data.query = "HostRoles/component_name.in(" + components.join(',') + ")";
+
+ return App.ajax.send({
+ name: 'common.host.host_components.update',
+ sender: this,
+ data: data
+ });
+ },
+
+ /**
+ * Calls the API to delete component on a host
+ * @param hostName {String}
+ * @param component {String}
+ * @return {Object} Deferred
+ */
+ deleteHostComponent: function(hostName, component) {
+ return App.ajax.send({
+ name: 'common.delete.host_component',
+ sender: this,
+ data: {
+ hostName: hostName,
+ componentName: component
+ }
+ });
+ },
+
+ /**
+ * Fetched the Request Id to poll and starts the polling to check
+ * if the request is ongoing or completed until deferred is resolved
+ * @param data {Object} Json
+ * @private
+ * @method {isRequestCompleted}
+ * @return {Object} Deferred promise
+ */
+ isRequestCompleted: function(data) {
+ var dfd = $.Deferred();
+ if (!data) {
+ dfd.resolve();
+ } else {
+ var requestId = data.Requests.id;
+ this.getRequestStatus(requestId, dfd);
+ }
+ return dfd.promise();
+ },
+
+ /**
+ * keeps checking on requestId if the request is ongoing or completed until deferred is resolved
+ * @param requestId {Integer}
+ * @param requestCompletedDfd {Object} Deferred Object to resolve when the requestId shows that the request is completed
+ * @private
+ * @method {isRequestCompleted}
+ */
+ getRequestStatus: function(requestId, requestCompletedDfd) {
+ var self = this;
+ var POLL_INTERVAL = 5000;
+ var TIMEOUT = 3000;
+
+ var dfdPromise = App.ajax.send({
+ name: 'common.get.request.status',
+ sender: this,
+ data: {
+ requestId: requestId,
+ timeout: TIMEOUT
+ }
+ });
+
+ var successCallback = function(data) {
+ if (['PENDING','IN_PROGRESS'].contains(data.Requests.request_status)) {
+ window.setTimeout(function () {
+ self.getRequestStatus(requestId, requestCompletedDfd);
+ }, POLL_INTERVAL);
+ } else if (data.Requests.request_status === 'COMPLETED') {
+ requestCompletedDfd.resolve();
+ } else {
+ requestCompletedDfd.fail();
+ }
+ };
+
+ var errorCallback = function() {
+ window.setTimeout(function () {
+ self.getRequestStatus(requestId, requestCompletedDfd);
+ }, POLL_INTERVAL);
+ };
+
+ dfdPromise.then(successCallback, errorCallback);
+ }
+});
\ No newline at end of file