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

[1/8] ambari git commit: AMBARI-21236. Principal placeholder replacement in kerberos.json does not work with blueprint installs (Attila Magyar via adoroszlai)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-20859 5b9454ef4 -> d7bc588a1


AMBARI-21236. Principal placeholder replacement in kerberos.json does not work with blueprint installs (Attila Magyar via adoroszlai)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 49f6b80051ac3b2cf7e4b18b0b2c454f2f9a6da9
Parents: 192162e
Author: Attila Magyar <am...@hortonworks.com>
Authored: Thu Jun 15 11:35:03 2017 +0200
Committer: Attila Doroszlai <ad...@hortonworks.com>
Committed: Thu Jun 15 11:35:03 2017 +0200

----------------------------------------------------------------------
 .../apache/ambari/server/controller/KerberosHelperImpl.java    | 6 ++----
 .../apache/ambari/server/controller/KerberosHelperTest.java    | 6 +++---
 2 files changed, 5 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/49f6b800/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
index 61674cf..d57fcd2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
@@ -1243,11 +1243,9 @@ public class KerberosHelperImpl implements KerberosHelper {
                                                                   Map<String, String> kerberosDescriptorProperties)
       throws AmbariException
   {
-    Map<String, Map<String, String>> configuration = addAdditionalConfigurations(cluster,
+    return addAdditionalConfigurations(cluster,
       calculateExistingConfigurations(cluster, hostname),
       hostname, kerberosDescriptorProperties);
-    configuration.put("principals", principalNames(cluster, configuration));
-    return configuration;
   }
 
   private Map<String, String> principalNames(Cluster cluster, Map<String, Map<String, String>> configuration) throws AmbariException {
@@ -2543,7 +2541,7 @@ public class KerberosHelperImpl implements KerberosHelper {
         configurations.put("clusterHostInfo", componentHosts);
       }
     }
-
+    configurations.put("principals", principalNames(cluster, configurations));
     return configurations;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/49f6b800/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index 18a6754..4508527 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -2388,7 +2388,7 @@ public class KerberosHelperTest extends EasyMockSupport {
     servicesMap.put("SERVICE2", service2);
 
     Cluster cluster = createMockCluster(clusterName, Arrays.asList(host1, host2, host3), SecurityType.KERBEROS, configKrb5Conf, configKerberosEnv);
-    expect(cluster.getServices()).andReturn(servicesMap).times(2);
+    expect(cluster.getServices()).andReturn(servicesMap).anyTimes();
 
     Map<String, String> kerberosDescriptorProperties = new HashMap<>();
     kerberosDescriptorProperties.put("additional_realms", "");
@@ -2595,7 +2595,7 @@ public class KerberosHelperTest extends EasyMockSupport {
     servicesMap.put("SERVICE1", service1);
 
     Cluster cluster = createMockCluster("c1", Arrays.asList(host1), SecurityType.KERBEROS, configKrb5Conf, configKerberosEnv);
-    expect(cluster.getServices()).andReturn(servicesMap).times(2);
+    expect(cluster.getServices()).andReturn(servicesMap).anyTimes();
 
     Map<String, String> kerberosDescriptorProperties = new HashMap<>();
     kerberosDescriptorProperties.put("additional_realms", "");
@@ -2610,7 +2610,7 @@ public class KerberosHelperTest extends EasyMockSupport {
 
     KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class);
     expect(kerberosDescriptor.getProperties()).andReturn(kerberosDescriptorProperties);
-    expect(kerberosDescriptor.getService("SERVICE1")).andReturn(service1KerberosDescriptor).times(1);
+    expect(kerberosDescriptor.getService("SERVICE1")).andReturn(service1KerberosDescriptor).anyTimes();
 
     setupKerberosDescriptor(kerberosDescriptor);
 


[2/8] ambari git commit: AMBARI-21246. Build creates tarball twice

Posted by rl...@apache.org.
AMBARI-21246. Build creates tarball twice


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: d06fba3506c1e60cbf8a0e737f65c7f842f8402f
Parents: 49f6b80
Author: Attila Doroszlai <ad...@hortonworks.com>
Authored: Wed Jun 14 16:39:10 2017 +0200
Committer: Attila Doroszlai <ad...@hortonworks.com>
Committed: Thu Jun 15 11:53:57 2017 +0200

----------------------------------------------------------------------
 ambari-agent/pom.xml  | 2 +-
 ambari-server/pom.xml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d06fba35/ambari-agent/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-agent/pom.xml b/ambari-agent/pom.xml
index c1cb056..7690fcf 100644
--- a/ambari-agent/pom.xml
+++ b/ambari-agent/pom.xml
@@ -453,7 +453,7 @@
         </configuration>
         <executions>
           <execution>
-            <id>build-tarball</id>
+            <id>make-assembly</id>
             <phase>${assemblyPhase}</phase>
             <goals>
               <goal>single</goal>

http://git-wip-us.apache.org/repos/asf/ambari/blob/d06fba35/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index ac78595..ca3b2da 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -182,7 +182,7 @@
         </configuration>
         <executions>
           <execution>
-            <id>build-tarball</id>
+            <id>make-assembly</id>
             <phase>${assemblyPhase}</phase>
             <goals>
               <goal>single</goal>


[5/8] ambari git commit: AMBARI-21247. Infra Manager: Use custom serializer for execution contexts of job & steps (oleewere)

Posted by rl...@apache.org.
AMBARI-21247. Infra Manager: Use custom serializer for execution contexts of job & steps (oleewere)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: f99e7763ed23dde574ce5f9569e90da293c8f366
Parents: 874b1f8
Author: oleewere <ol...@gmail.com>
Authored: Wed Jun 14 18:06:39 2017 +0200
Committer: oleewere <ol...@gmail.com>
Committed: Thu Jun 15 14:02:22 2017 +0200

----------------------------------------------------------------------
 .../infra/conf/batch/InfraManagerBatchConfig.java    | 11 +++++++++--
 .../ambari/infra/job/dummy/DummyItemWriter.java      | 15 ++++++++++++++-
 .../ambari/infra/job/dummy/DummyJobListener.java     |  7 +++++++
 3 files changed, 30 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f99e7763/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java
index 95f87f5..98a4901 100644
--- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java
+++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/conf/batch/InfraManagerBatchConfig.java
@@ -43,9 +43,10 @@ import org.springframework.batch.core.launch.JobLauncher;
 import org.springframework.batch.core.launch.JobOperator;
 import org.springframework.batch.core.launch.support.SimpleJobLauncher;
 import org.springframework.batch.core.launch.support.SimpleJobOperator;
+import org.springframework.batch.core.repository.ExecutionContextSerializer;
 import org.springframework.batch.core.repository.JobRepository;
-import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer;
 import org.springframework.batch.core.repository.dao.ExecutionContextDao;
+import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
 import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
 import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
 import org.springframework.batch.item.ItemProcessor;
@@ -143,10 +144,16 @@ public class InfraManagerBatchConfig {
   }
 
   @Bean
+  public ExecutionContextSerializer executionContextSerializer() {
+    return new Jackson2ExecutionContextStringSerializer();
+  }
+
+  @Bean
   public JobRepository jobRepository() throws Exception {
     JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
     factory.setDataSource(dataSource());
     factory.setTransactionManager(getTransactionManager());
+    factory.setSerializer(executionContextSerializer());
     factory.afterPropertiesSet();
     return factory.getObject();
   }
@@ -213,7 +220,7 @@ public class InfraManagerBatchConfig {
   @Bean
   public ExecutionContextDao executionContextDao() {
     JdbcExecutionContextDao dao = new JdbcExecutionContextDao();
-    dao.setSerializer(new DefaultExecutionContextSerializer());
+    dao.setSerializer(executionContextSerializer());
     dao.setJdbcTemplate(jdbcTemplate());
     return dao;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f99e7763/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyItemWriter.java
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyItemWriter.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyItemWriter.java
index 9a78706..444f0d1 100644
--- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyItemWriter.java
+++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyItemWriter.java
@@ -20,6 +20,8 @@ package org.apache.ambari.infra.job.dummy;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.batch.core.StepExecution;
+import org.springframework.batch.core.annotation.BeforeStep;
 import org.springframework.batch.item.ItemWriter;
 
 import java.io.File;
@@ -35,6 +37,8 @@ public class DummyItemWriter implements ItemWriter<String> {
 
   private static final Logger LOG = LoggerFactory.getLogger(DummyItemWriter.class);
 
+  private StepExecution stepExecution;
+
   @Override
   public void write(List<? extends String> values) throws Exception {
     LOG.info("DummyItem writer called (values: {})... wait 1 seconds", values.toString());
@@ -43,7 +47,16 @@ public class DummyItemWriter implements ItemWriter<String> {
     Path pathToDirectory = Paths.get(outputDirectoryLocation);
     Path pathToFile = Paths.get(String.format("%s%s%s", outputDirectoryLocation, File.separator, "dummyOutput.txt"));
     Files.createDirectories(pathToDirectory);
-    LOG.info("Write to file: ", pathToFile.getFileName().toAbsolutePath());
+    LOG.info("Write location to step execution context...");
+    stepExecution.getExecutionContext().put("stepOutputLocation", pathToFile.getFileName().toAbsolutePath().toString());
+    LOG.info("Write location to job execution context...");
+    stepExecution.getJobExecution().getExecutionContext().put("jobOutputLocation", pathToFile.getFileName().toAbsolutePath().toString());
+    LOG.info("Write to file: {}", pathToFile.getFileName().toAbsolutePath().toString());
     Files.write(pathToFile, values.toString().getBytes());
   }
+
+  @BeforeStep
+  public void saveStepExecution(StepExecution stepExecution) {
+    this.stepExecution = stepExecution;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f99e7763/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyJobListener.java
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyJobListener.java b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyJobListener.java
index 0bbfb55..99c50e8 100644
--- a/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyJobListener.java
+++ b/ambari-infra/ambari-infra-manager/src/main/java/org/apache/ambari/infra/job/dummy/DummyJobListener.java
@@ -20,6 +20,7 @@ package org.apache.ambari.infra.job.dummy;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.batch.core.ExitStatus;
 import org.springframework.batch.core.JobExecution;
 import org.springframework.batch.core.JobExecutionListener;
 
@@ -35,5 +36,11 @@ public class DummyJobListener implements JobExecutionListener {
   @Override
   public void afterJob(JobExecution jobExecution) {
     LOG.info("Dummy - after job execution");
+    if (jobExecution.getExecutionContext().get("jobOutputLocation") != null) {
+      String jobOutputLocation = (String) jobExecution.getExecutionContext().get("jobOutputLocation");
+      String exitDescription = "file://" + jobOutputLocation;
+      LOG.info("Add exit description '{}'", exitDescription);
+      jobExecution.setExitStatus(new ExitStatus(ExitStatus.COMPLETED.getExitCode(), exitDescription));
+    }
   }
 }


[4/8] ambari git commit: AMBARI-21237. Add validation and recommendation if hive user value is different than hive.(vbrodetskyi)

Posted by rl...@apache.org.
AMBARI-21237. Add validation and recommendation if hive user value is different than hive.(vbrodetskyi)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 874b1f8334ba214b4be1eb4ad7394e5ce6abdd73
Parents: a06b6e1
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Thu Jun 15 14:15:34 2017 +0300
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Thu Jun 15 14:15:34 2017 +0300

----------------------------------------------------------------------
 .../services/YARN/configuration/yarn-site.xml   |  6 ++++
 .../stacks/HDP/2.6/services/stack_advisor.py    | 36 ++++++++++++++++++--
 2 files changed, 40 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/874b1f83/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/configuration/yarn-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/configuration/yarn-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/configuration/yarn-site.xml
index cab0e65..5f8de49 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/configuration/yarn-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/configuration/yarn-site.xml
@@ -109,6 +109,12 @@
   <property>
     <name>yarn.nodemanager.kill-escape.user</name>
     <value>hive</value>
+    <depends-on>
+      <property>
+        <type>hive-env</type>
+        <name>hive_user</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/874b1f83/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
index 488562b..f8bbca5 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/stack_advisor.py
@@ -180,6 +180,26 @@ class HDP26StackAdvisor(HDP25StackAdvisor):
     super(HDP26StackAdvisor, self).recommendYARNConfigurations(configurations, clusterData, services, hosts)
     putYarnSiteProperty = self.putProperty(configurations, "yarn-site", services)
     putYarnEnvProperty = self.putProperty(configurations, "yarn-env", services)
+    servicesList = [service["StackServices"]["service_name"] for service in services["services"]]
+
+    if 'HIVE' in servicesList and "yarn-site" in services["configurations"] and "yarn.nodemanager.kill-escape.user" in \
+                services["configurations"]["yarn-site"]["properties"] and 'hive-env' in services['configurations'] and \
+                'hive_user' in services['configurations']['hive-env']['properties']:
+      hive_user_name = services['configurations']['hive-env']['properties']['hive_user']
+      old_hive_user_name = getOldValue(self, services, "hive-env", "hive_user")
+      yarn_nm_kill_escape_user = services["configurations"]["yarn-site"]["properties"]["yarn.nodemanager.kill-escape.user"]
+      if not hive_user_name in yarn_nm_kill_escape_user:
+        if not yarn_nm_kill_escape_user or yarn_nm_kill_escape_user.strip() == "":
+          yarn_nm_kill_escape_user = hive_user_name
+        else:
+          escape_user_names = yarn_nm_kill_escape_user.split(",")
+          if old_hive_user_name in escape_user_names:
+            escape_user_names.remove(old_hive_user_name)
+          escape_user_names.append(hive_user_name)
+          yarn_nm_kill_escape_user = ",".join(escape_user_names)
+
+        putYarnSiteProperty("yarn.nodemanager.kill-escape.user", yarn_nm_kill_escape_user)
+
 
     if "yarn-site" in services["configurations"] and \
                     "yarn.resourcemanager.scheduler.monitor.enable" in services["configurations"]["yarn-site"]["properties"]:
@@ -391,6 +411,18 @@ class HDP26StackAdvisor(HDP25StackAdvisor):
   def validateYarnSiteConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):
       validationItems = []
       siteProperties = services["configurations"]["yarn-site"]["properties"]
+      servicesList = [service["StackServices"]["service_name"] for service in services["services"]]
+
+      if 'HIVE' in servicesList and "yarn-site" in services["configurations"] and "yarn.nodemanager.kill-escape.user" in \
+          services["configurations"]["yarn-site"]["properties"] and 'hive-env' in services['configurations'] and \
+                  'hive_user' in services['configurations']['hive-env']['properties']:
+        hive_user = services['configurations']['hive-env']['properties']['hive_user']
+        yarn_nm_kill_escape_user = services["configurations"]["yarn-site"]["properties"]["yarn.nodemanager.kill-escape.user"]
+        if not hive_user in yarn_nm_kill_escape_user:
+          validationItems.append(
+            {"config-name": "yarn.nodemanager.kill-escape.user",
+             "item": self.getWarnItem("Value should contain %s" % hive_user)})
+
       if services["configurations"]["yarn-site"]["properties"]["yarn.http.policy"] == 'HTTP_ONLY':
          webapp_address = services["configurations"]["yarn-site"]["properties"]["yarn.timeline-service.webapp.address"]
          propertyValue = "http://"+webapp_address+"/ws/v1/applicationhistory"
@@ -399,9 +431,9 @@ class HDP26StackAdvisor(HDP25StackAdvisor):
          propertyValue = "https://"+webapp_address+"/ws/v1/applicationhistory"
       self.logger.info("validateYarnSiteConfigurations: recommended value for webservice url"+services["configurations"]["yarn-site"]["properties"]["yarn.log.server.web-service.url"])
       if services["configurations"]["yarn-site"]["properties"]["yarn.log.server.web-service.url"] != propertyValue:
-         validationItems = [
+         validationItems.append(
               {"config-name": "yarn.log.server.web-service.url",
-               "item": self.getWarnItem("Value should be %s" % propertyValue)}]
+               "item": self.getWarnItem("Value should be %s" % propertyValue)})
       return self.toConfigurationValidationProblems(validationItems, "yarn-site")
 
   def validateDruidHistoricalConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):


[3/8] ambari git commit: AMBARI-21153.Hdfs directory viewer should be changed from tree view to list view.(Venkata Sairam)

Posted by rl...@apache.org.
AMBARI-21153.Hdfs directory viewer should be changed from tree view to list view.(Venkata Sairam)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: a06b6e1d287ca7ed5e63bf74f2c955aa2ec1dbc9
Parents: d06fba3
Author: Venkata Sairam <ve...@gmail.com>
Authored: Thu Jun 15 16:36:21 2017 +0530
Committer: Venkata Sairam <ve...@gmail.com>
Committed: Thu Jun 15 16:36:34 2017 +0530

----------------------------------------------------------------------
 .../addon/components/directory-viewer.js        | 324 +++++++++++++------
 .../hdfs-directory-viewer/addon/styles/app.css  | 190 +++++++++++
 .../templates/components/directory-viewer.hbs   | 145 +++++++++
 .../addon/utils/viewer-config.js                |   4 +
 .../ui/hdfs-directory-viewer/bower.json         |   1 -
 .../resources/ui/hdfs-directory-viewer/index.js |   3 -
 .../ui/hdfs-directory-viewer/package.json       |   5 +-
 7 files changed, 562 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
index 991d122..2f2b547 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/components/directory-viewer.js
@@ -21,27 +21,81 @@ import layout from '../templates/components/directory-viewer';
 
 export default Ember.Component.extend({
   layout,
+  counter: 0,
   config: Ember.Object.create({}),
   classNames: ['directory-viewer'],
   startPath: '/',
-  treeData: Ember.A(),
+  folderName:'',
+  isDirectory: true,
+  isFile: true,
+  fileBrowserHeight: '850',
+  fileBrowserWidth: '650',
+  maxBreadCrumbsCount: 3,
+  elipsisLength: 8,
+  isFolderCreationSuccess: null,
+  isFolderCreationFailure: null,
+  isFolderCreationprogress:false,
+  // homeDirectory: '/app-logs/cstm-hdfs/logs',
+  fileSystem: Ember.A(),
   currentPath: Ember.computed.oneWay('startPath'),
-  currentQueryParam: Ember.computed('currentPath', function() {
+  currentPathArray: [{'path':'/'}],
+  breadCrumbs: {},
+  isCreateFolder : false,
+  folderAccessError: {},
+  createFolderError: {},
+  filteredFileSytemInfo: Ember.computed('fileSystem', 'isDirectory', 'isFile', function() {
+    return this.get('fileSystem').filter( (record) => {
+      if(record.traverse) {
+         return true;
+      }
+      if(this.get('isDirectory') && this.get('isFile')) {
+         return record.isDirectory || !record.isDirectory;
+      }
+      if(this.get('isDirectory')) {
+         return record.isDirectory;
+      }
+      if(this.get('isFile')) {
+         return !record.isDirectory;
+      }
+      return;
+  });
+  }),
+  currentQueryParam: Ember.computed('currentPath', 'homeDirectory', function() {
+    if(this.get('counter') === 1 && this.get('homeDirectory')){
+      this.set('currentPath', this.get('homeDirectory'));
+    }
     return Ember.$.param({path: this.get('currentPath')});
   }),
-
+  createFolderQueryParam: Ember.computed('currentPath', 'homeDirectory', 'folderName', function() {
+    return {path: this.get('currentPath')+"/"+this.get('folderName')};
+  }),
+  isDataLoading: true,
   startFetch: Ember.on('didInitAttrs', function() {
+    if(this.get('width')) {
+      this.set('fileBrowserWidth', this.get('width'));
+    }
+    if(this.get('height')) {
+      this.set('fileBrowserHeight', this.get('height'));
+    }
     this.fetchData();
   }),
-
-
+  setFileBroswerHeightAndWidth: Ember.on('didInsertElement', function() {
+    Ember.$('.top-header, #file-view-unix').css('width', this.get('fileBrowserWidth'));
+  }),
   fetchData: function() {
+    this.incrementProperty('counter');
+    this.startFileSystemFetchProgress();
+    this.set('folderAccessError', {});
     this.listPath(this.get('currentQueryParam')).then(
       (response) => {
         let list = this.filterDirectoriesIfRequired(response.files);
-        this.modifyTreeViewData(list);
+        this.stopFileSystemFetchProgress();
+        this.modifyFileSystemData(list);
       }, (error) => {
+        this.set('folderAccessError', error.responseJSON);
         this.sendAction('errorAction', error);
+        this.set('errorMsg', 'Error while accessing.Please try again.');
+        this.stopFileSystemFetchProgress();
       }
     );
   },
@@ -57,7 +111,29 @@ export default Ember.Component.extend({
       headers: headers
     });
   },
-
+  createFolder() {
+    let deferred = Ember.RSVP.defer();
+    let config = this.get('config');
+    let listUrl = config.createDirectoryUrl();
+    let headers = config.getHeaders();
+    headers = this.setHeadersForMkdir(headers);
+    Ember.$.ajax(listUrl, {
+      headers: headers,
+      method:'PUT',
+      data:JSON.stringify(this.get('createFolderQueryParam'))
+    }).done(function(data){
+        deferred.resolve(data);
+    }).fail(function(data){
+        deferred.reject(data);
+    });
+    return deferred.promise;
+  },
+  setHeadersForMkdir(headers) {
+    headers['Accept'] = 'application/json';
+    headers.dataType = 'json';
+    headers['Content-Type'] = 'application/json; charset=UTF-8';
+    return headers;
+  },
   filterDirectoriesIfRequired: function(files) {
     let showOnlyDirectories = this.get('config.showOnlyDirectories');
     return files.filter((entry) => {
@@ -65,7 +141,7 @@ export default Ember.Component.extend({
     });
   },
 
-  modifyTreeViewData: function(response) {
+  modifyFileSystemData: function(response) {
     let paths = response.map((entry) => {
       let isDirectory = entry.isDirectory;
       let icon = isDirectory ? this.get('config.folderIcon') : this.get('config.fileIcon');
@@ -74,122 +150,160 @@ export default Ember.Component.extend({
         pathSegment: this.getNameForPath(entry.path),
         isDirectory: isDirectory,
         icon: icon,
-        text: this.getNameForPath(entry.path)
+        permission: entry.permission,
+        text: this.getNameForPath(entry.path),
+        selectedClass: ''
       };
       if(isDirectory) {
         data.nodes = Ember.A();
       }
       return data;
     });
-
-    var currentPath = this.get('currentPath');
-    var newTreeData = Ember.copy(this.get('treeData'), true);
-    if(currentPath === '/') {
-      newTreeData = paths;
-    } else {
-      this.insertPathToTreeData(newTreeData, paths, currentPath.substring(1));
-    }
-
-    this.set('treeData', newTreeData);
-    this.send('refreshTreeView');
+    this.setCurrentPathAsList();
+    paths = this.insertRootAsFirstPath(paths, this.get('currentPath'));
+    this.setBreadCrumbsAndListMenu();
+    this.set('fileSystem', paths);
+    this.set('errorMsg', null);
+    this.stopFileSystemFetchProgress();
   },
-
-  insertPathToTreeData(treeData, paths, pathSegment) {
-    let firstPathSegment;
-    if (pathSegment.indexOf('/') !== -1) {
-      firstPathSegment = pathSegment.substring(0, pathSegment.indexOf('/'));
-    } else {
-      firstPathSegment = pathSegment;
+  insertRootAsFirstPath(paths, currentPath) {
+    if(currentPath !== '/') {
+       paths.unshift({traverse:true, path: this.get('currentPathArray')[this.get('currentPathArray').length-2 >=0 ?this.get('currentPathArray').length-2:this.get('currentPathArray').length-1].path});
     }
-
-    if(treeData.length === 0) {
-      treeData.pushObjects(paths);
+    return paths;
+  },
+  setBreadCrumbsAndListMenu() {
+    let currentPathArray = this.get('currentPathArray');
+    if(currentPathArray.length > this.get('maxBreadCrumbsCount')){
+       this.set("breadCrumbs", {'dropDownMenu': currentPathArray.splice(0, currentPathArray.length - this.get('maxBreadCrumbsCount')), 'breadCrumbsMenu': currentPathArray.splice(0, currentPathArray.length)});
     } else {
-      treeData.forEach((entry) => {
-        entry.state = {};
-        if (entry.pathSegment === firstPathSegment) {
-          entry.state.expanded = true;
-          if(entry.nodes.length === 0) {
-            paths.forEach((pathEntry) => {
-              entry.nodes.push(pathEntry);
-            });
-          } else {
-            this.insertPathToTreeData(entry.nodes, paths, pathSegment.substring(pathSegment.indexOf('/') + 1));
-          }
-        } else {
-          this.collapseAll(entry);
-        }
-      });
+       this.set("breadCrumbs", {'breadCrumbsMenu': currentPathArray});
     }
   },
-
-  collapseAll: function(node) {
-    if (Ember.isNone(node.state)) {
-      node.state = {};
-    }
-    node.state.expanded = false;
-    if(!Ember.isNone(node.nodes)) {
-      node.nodes.forEach((entry) => {
-        this.collapseAll(entry);
-      });
+  shortenName(name) {
+    return name.length > this.get('elipsisLength') ? name.substring(0, this.get('elipsisLength'))+'...':name;
+  },
+  setCurrentPathAsList() {
+    let currentPath = this.get('currentPath'), relPath = "", currentPathArr = currentPath.split('/');
+    if(currentPath === "/") {
+      currentPathArr = [""];
     }
+    this.set('currentPathArray', []);
+    currentPathArr.forEach(function(item, i) {
+        if(i !== 1) {
+         relPath = relPath + "/"+ item;
+        } else if(i === 1){
+         relPath = relPath + currentPathArr[i];
+        }
+        console.log(relPath+" is relPath");
+        if(i === currentPathArr.length-1){
+           if(0 === currentPathArr.length-1) {
+             this.get('currentPathArray').push({'path':relPath, 'fullFileName' : item, 'name':item?this.shortenName(item):'root', isCurrentFolder: true, isRoot:true});
+           } else{
+             this.get('currentPathArray').push({'path':relPath, 'fullFileName' : item, 'name':item?this.shortenName(item):'root', isCurrentFolder: true});
+           }
+        } else if(i === 0){
+           this.get('currentPathArray').push({'path':relPath, 'fullFileName' : item, 'name':item?this.shortenName(item):'root', isRoot:true});
+        } else {
+           this.get('currentPathArray').push({'path':relPath ,'fullFileName' : item,  'name':item?this.shortenName(item):'root'});
+        }
+    }.bind(this));
   },
-
   getNameForPath: function(path) {
     return path.substring(path.lastIndexOf("/") + 1);
   },
-
-  collapseAllExceptPath: function(pathSegment) {
-    let collapseAll = function(nodes, pathSegment) {
-      var firstPathSegment;
-      if (pathSegment.indexOf('/') !== -1) {
-        firstPathSegment = pathSegment.substring(0, pathSegment.indexOf('/'));
-      } else {
-        firstPathSegment = pathSegment;
-      }
-
-      nodes.forEach((entry) => {
-        if (Ember.isNone(entry.state)) {
-          entry.state = {};
-        }
-        if(firstPathSegment !== entry.pathSegment) {
-          entry.state.expanded = false;
-        } else {
-          entry.state.expanded = true;
-          collapseAll(entry.nodes, pathSegment.substring(pathSegment.indexOf('/') + 1));
-        }
-      });
-    };
-    var newTreeData = this.get('treeData');
-    collapseAll(newTreeData, pathSegment);
-    this.set('treeData', newTreeData);
-    this.send('refreshTreeView');
+  stopFolderCreationProgress() {
+    this.set('isFolderCreationprogress', false);
+  },
+  startFolderCreationProgress() {
+    this.set('isFolderCreationprogress', true);
+  },
+  stopFileSystemFetchProgress() {
+    this.set('isDataLoading', false);
+  },
+  startFileSystemFetchProgress() {
+    this.set('isDataLoading', true);
+  },
+  resetFolderCreationMenuValidation() {
+    this.set('isFolderCreationSuccess', false);
+    this.set('isFolderCreationFailure', false);
+  },
+  folderCreationSuccess() {
+    this.set('createFolderError', {});
+    this.set('isFolderCreationSuccess', true);
+    this.set('isFolderCreationFailure', false);
+  },
+  folderCreationFailure() {
+    this.set('isFolderCreationSuccess', false);
+    this.set('isFolderCreationFailure', true);
+  },
+  resetGoToPathMenuValidation() {
+    this.set('isGoToFolderSuccess', false);
+    this.set('isGoToFolderFailure', false);
+  },
+  hideGoToPathMenu() {
+    this.set('isGoToFolder', false);
+  },
+  hideCreateFolderMenu() {
+    this.set('isCreateFolder', false);
   },
-
   actions: {
-    refreshTreeView() {
-      Ember.run.later(() => {
-        this.$().treeview({
-          data: this.get('treeData'),
-          expandIcon: this.get('config.expandIcon'),
-          collapseIcon: this.get('config.collapseIcon'),
-          //emptyIcon: "fa",
-          showBorder: false,
-          onNodeSelected: (event, data) => {
-            this.set('currentPath', data.path);
-            this.sendAction('pathSelectAction', {path: data.path, isDirectory: data.isDirectory});
-          },
-          onNodeExpanded: (event, data) => {
-            this.set('currentPath', data.path);
-            if (!Ember.isNone(data.nodes) && data.nodes.length === 0) {
-              var node = this.$().treeview('getNode', data.nodeId);
-              node.icon = "fa fa-refresh fa-spin";
-              this.fetchData();
-            } else {
-              this.collapseAllExceptPath(data.path.substring(1));
-            }
+    toggleCreateFolderMenu() {
+      if(this.get('isGoToFolder')) {
+        this.hideGoToPathMenu();
+      }
+      this.toggleProperty('isCreateFolder');
+      this.resetFolderCreationMenuValidation();
+    },
+    toggleGoToFolderMenu() {
+      if(this.get('isCreateFolder')) {
+        this.hideCreateFolderMenu();
+      }
+      this.toggleProperty('isGoToFolder');
+      this.resetGoToPathMenuValidation();
+    },
+    createFolder() {
+      if(Ember.isBlank(this.get('currentPath'))) {
+        return true;
+      }
+      this.startFolderCreationProgress();
+      this.set('createFolderError', {});
+      this.createFolder().then(function() {
+         this.send('drillToPath', this.get('currentPath'));
+         this.folderCreationSuccess();
+         this.stopFolderCreationProgress();
+      }.bind(this)).catch(function(e) {
+         this.set('createFolderError', e.responseJSON);
+         this.folderCreationFailure();
+         this.stopFolderCreationProgress();
+         console.error(e);
+      }.bind(this));
+    },
+    goToFolder() {
+      if(Ember.isBlank(this.get('currentPath'))) {
+        return true;
+      }
+      this.send('drillToPath', this.get('currentPath'));
+    },
+    drillToPath(path, fileItem) {
+       if(fileItem) {
+        this.sendAction('pathSelectAction', fileItem);
+       }
+       if(path.indexOf('/') !== 0){
+         this.set('errorMsg', 'Invalid path.');
+         return;
+       }
+       this.set('currentPath', path);
+       this.fetchData();
+    },
+    selectRow(index, fileItem) {
+       this.sendAction('pathSelectAction', fileItem);
+       this.get('fileSystem').forEach(function(item, i) {
+          if(index === i && !item.traverse){
+            Ember.set(item, "selectedClass", "row-selected");
+          } else {
+            Ember.set(item, "selectedClass", "");
           }
-        });
       });
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/styles/app.css
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/styles/app.css b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/styles/app.css
new file mode 100644
index 0000000..828a827
--- /dev/null
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/styles/app.css
@@ -0,0 +1,190 @@
+/**
+ * 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.
+ */
+.directory-viewer{
+  width: 500px;
+}
+.directory-viewer-wrap {
+  width: 600px;
+  height: 500px;
+  border: 1px solid #e2e2e2;
+}
+
+.directory-viewer .container-wrap {
+	position:relative;
+	height:400px;
+}
+.directory-viewer .top-header {
+	position: relative;
+	padding-left: 0px;
+	padding-right: 0px;
+	padding-bottom: 5px;
+	width: 500px;
+	border-bottom:1px solid #e2e2e2;
+}
+.directory-viewer .row-selected {
+	background-color:#c7ddef!important
+}
+.directory-viewer .file-row {
+	padding-top: 10px;
+    padding-bottom: 10px;
+    border-bottom: 1px solid #e2e2e2;
+}
+.directory-viewer .dropdown-menu>li>a {
+    display: block;
+    padding: 3px 20px;
+    clear: both;
+    font-weight: 400;
+    line-height: 1.42857143;
+    color: #337ab7;
+    white-space: nowrap;
+}
+.directory-viewer .file-row:hover {
+    background-color: #f5f5f5;
+}
+.directory-viewer .mod-icon {
+	font-size:1.5em
+}
+.directory-viewer .elipsisClass{
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+    width: 50%;
+}
+.directory-viewer .elipsis-link{
+    overflow: initial;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    white-space: nowrap;
+    width: 50px;
+}
+.directory-viewer .pointer {
+    cursor: pointer;
+}
+.directory-viewer .breadcrumbs-label {
+	display: inline-block;
+	padding: 8px;
+}
+.directory-viewer #file-view-unix {
+	width:500px;
+	position:relative;
+	overflow:auto;
+}
+.directory-viewer .padding-left-10px {
+	padding-left: 10px;
+}
+.directory-viewer .padding-right-10px {
+	padding-right: 10px;
+}
+.directory-viewer .home-icon {
+	top:3px;
+	font-size:1.5em;
+	position:relative;
+}
+.directory-viewer .breadcrumb {
+	background-color:white;
+	margin-bottom:0px;
+	padding: 0px;
+}
+.directory-viewer .container-fluid {
+	position:relative;
+	height:400px;
+}
+.directory-viewer .folder-name {
+	width:100% !important;
+}
+.directory-viewer .add-folder {
+    padding: 10px;
+    height: auto;
+    padding-top:0px;
+    padding-left:10px;
+    padding-bottom:4px;
+    margin-top:3px;
+    left:16px;
+}
+.directory-viewer .go-to-folder {
+    height: auto;
+    padding-right: 0px;
+    padding-left: 10px;
+    padding-bottom: 4px;
+    margin-top:3px;
+    left: 8px;
+}
+.directory-viewer .btn-action {
+	padding: 5px 10px;
+}
+.directory-viewer #folderPath, .directory-viewer #folderName {
+	height: 32px;
+	top: 2px;
+	position: relative;
+}
+.directory-viewer .margin-right-5 {
+	margin-right: 5px !important;
+}
+.directory-viewer a, .directory-viewer .file-system-count  {
+  color: #337ab7;
+}
+.directory-viewer .top-header button.btn{
+  color: #fff !important;
+}
+
+.directory-viewer .form-group{
+  padding-left:0px;
+  width:90%;
+}
+
+.directory-viewer button{
+  position:relative;
+  top:2px;
+  left:5px;
+}
+
+.directory-viewer .file-creation-status {
+  margin-top:10px;
+  margin-bottom:0px;
+}
+
+.directory-viewer .file-creation-success {
+  color:green;
+}
+
+.directory-viewer .file-creation-failure {
+  color:red;
+}
+
+.directory-viewer .inline {
+  display:inline-block;
+}
+
+.directory-viewer .file-viewer-settings {
+  position:relative;
+  top:5px;
+}
+
+.directory-viewer .no-padding {
+  padding:0px;
+}
+
+.directory-viewer .file-system-status {
+  margin-top:10px;
+  padding-left:20px;
+}
+
+.directory-viewer .file-system-count {
+  text-align:center;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
index 75339c5..a4a66ac 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/templates/components/directory-viewer.hbs
@@ -15,4 +15,149 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
+<div class="pull-left col-sm-6 top-header">
+{{#if isGoToFolder}}
+        <div class="container-fluid go-to-folder">
+            <div class="form-inline">
+                <div class="form-group">
+                    {{input class="form-control col-sm-4 folder-name" id="folderPath" placeholder="Enter folder path" name="folderPath" value=currentPath}}
+                </div>
+                <button type="button" class="btn btn-sm btn-default btn-primary btn-action" {{action "goToFolder"}}><i aria-hidden="true" class="fa fa-arrow-circle-right"></i></button>
+                <button type="button" class="btn btn-sm btn-default btn-danger btn-action" {{action "toggleGoToFolderMenu"}}>
+                    <i class="fa fa-times" aria-hidden="true"></i>
+                </button>
+            </div>
+        </div>
+{{else if isCreateFolder}}
+        <div class="container-fluid add-folder">
+            <div class="form-inline">
+                <div class="form-group">
+                    {{input class="form-control col-sm-4 folder-name" id="folderName" placeholder="Enter folder name" name="folderName" value=currentPath}}
+                </div>
+                <button type="button" class="btn btn-sm btn-default btn-primary" {{action "createFolder"}}><i class="fa fa-plus-circle" aria-hidden="true"></i></button>
+                <button type="button" class="btn btn-sm btn-default btn-danger" {{action "toggleCreateFolderMenu"}}><i class="fa fa-times" aria-hidden="true"></i></button>
+                {{#if isFolderCreationSuccess}}
+                    <div class="file-creation-status">
+                        <strong class="file-creation-success">Folder have been created.</strong>
+                    </div>
+                {{/if}}
+                {{#if isFolderCreationFailure}}
+                    <div class="file-creation-status">
+                        <strong class="file-creation-failure">Folder creation failed.</strong>
+                        <div class="file-creation-failure">
+                            {{createFolderError.message}}
+                        </div>
+                    </div>
+                {{/if}}
+                {{#if isFolderCreationprogress}}
+                    <div class="loading-data" class="file-creation-status">
+                        <i class="fa fa-spinner fa-pulse fa-1x fa-fw"></i>Creating the folder...
+                    </div>
+                {{/if}}
+            </div>
+        </div>
 
+{{else}}
+
+    {{#if breadCrumbs.dropDownMenu}}
+        <li class="inline">
+        <div class="dropdown">
+            <a class="dropdown-toggle" d="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
+	        <span class="fa-stack">
+	          <i class="fa fa-folder-o fa-stack-1x mod-icon" aria-hidden="true"></i>
+	          <i class="fa fa-caret-down fa-stack-1x" aria-hidden="true"></i>
+	        </span>
+            </a>
+        <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
+        {{#each breadCrumbs.dropDownMenu as |crumb index|}}
+                <li><a {{action "drillToPath" crumb.path}}> <div title={{crumb.fullFileName}} class="elipsis-link pointer inline">{{crumb.name}}</div></a></li>
+        {{/each}}
+            </ul>
+        </div>
+        </li>&nbsp;/
+    {{/if}}
+    <div class="bs-example breadcrumbs-label">
+        <ul class="breadcrumb">
+            <li>
+                {{#each breadCrumbs.breadCrumbsMenu as |pathItem|}}
+                    {{#if pathItem.isRoot}}
+                        <a {{action "drillToPath" pathItem.path}}><i class="fa fa-folder-o home-icon" aria-hidden="true"></i></a>&nbsp;>
+                    {{else if pathItem.isCurrentFolder}}
+                        <span  title={{pathItem.fullFileName}}>{{pathItem.name}}</span>&nbsp;
+                    {{else}}
+                        <a {{action "drillToPath" pathItem.path}}><div class="pointer inline" title={{pathItem.fullFileName}}>{{pathItem.name}}</div></a>&nbsp;>
+                    {{/if}}
+                {{/each}}
+            </li>
+        </ul>
+    </div>
+
+    <div class="pull-right file-viewer-settings">
+        <li class="breadcrumbs-label no-padding">
+            <div class="dropdown">
+                <a class="dropdown-toggle" d="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
+		  <span class="btn btn-sm btn-default">
+		    <i class="fa fa-cog" aria-hidden="true"></i>
+		    <i class="fa fa-caret-down" aria-hidden="true"></i>
+		  </span>
+                </a>
+                <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
+                    <li><a>{{input type="checkbox" class="margin-right-5" name="dir" checked=isDirectory}}Directories</a></li>
+                    <li><a>{{input type="checkbox" class="margin-right-5" name="file" checked=isFile}}Files</a></li>
+                </ul>
+            </div>
+        </li>
+        <span {{ action "drillToPath" currentPath}} class="btn btn-sm btn-default">
+		    <i class="fa fa-refresh" aria-hidden="true"></i>
+		</span>
+        <button type="button" class="btn btn-sm btn-primary" {{action "toggleCreateFolderMenu"}}>
+            <i class="fa fa-plus-circle" aria-hidden="true"></i>{{!--  New Folder --}}
+        </button>
+        <button type="button" class="btn btn-sm btn-primary" {{action "toggleGoToFolderMenu"}}>
+            <i aria-hidden="true" class="fa fa-arrow-circle-o-right"></i> {{!-- Go To --}}
+        </button>
+    </div>
+{{/if}}
+</div>
+<div id="file-view-unix">
+    {{#if isDataLoading}}
+        <div class="loading-data file-system-status">
+            <i class="fa fa-spinner fa-pulse fa-1x fa-fw"></i>Fetching data...
+        </div>
+    {{else if errorMsg}}
+        <div class="file-system-status">
+            <strong class="file-creation-failure">{{errorMsg}}</strong>
+            <div class="file-creation-failure">
+                {{folderAccessError.message}}
+            </div>
+        </div>
+    {{else}}
+        {{#if filteredFileSytemInfo}}
+            <div class="container-fluid">
+                {{#ember-collection items=filteredFileSytemInfo cell-layout=(fixed-grid-layout fileBrowserWidth 41) as |item index|}}
+                    <div class="row file-row {{item.selectedClass}}" {{action 'selectRow' index item}}>
+                        {{#if item.traverse}}
+                            <div class="col-sm-8">
+                                <a class="padding-left-10px pointer" {{action "drillToPath" item.path item}}>
+                                    <i class="fa fa-reply padding-right-10px" aria-hidden="true"></i>
+                                </a>
+                            </div>
+                        {{else if item.isDirectory }}
+                            <div class="col-sm-6 elipsisClass">
+                                <a title={{item.text}} class="padding-left-10px pointer" {{action "drillToPath" item.path item}}>
+                                <i class="fa fa-folder-o padding-right-10px" aria-hidden="true"></i>{{ item.text }}
+                                </a>
+                            </div>
+                        {{else}}
+                            <div class="col-sm-6 elipsisClass" title={{item.text}}>
+                                <i class="fa fa-file padding-left-10px padding-right-10px" aria-hidden="true"></i>{{ item.text }}
+                            </div>
+                        {{/if}}
+                    </div>
+                {{/ember-collection}}
+            </div>
+        {{else}}
+            No files or folders.
+        {{/if}}
+    {{/if}}
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
index 64773c6..4f3fb5e 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/addon/utils/viewer-config.js
@@ -54,6 +54,10 @@ export default Ember.Object.extend({
    */
   listDirectoryUrl(pathParams) {
     return `/listdir?${pathParams}`;
+  },
+
+  createDirectoryUrl() {
+    return '/mkdir';
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
index f016904..206b8bd 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/bower.json
@@ -10,7 +10,6 @@
     "loader.js": "^3.5.0",
     "qunit": "~1.20.0",
     "bootstrap": "~3.3.6",
-    "bootstrap-treeview": "~1.2.0",
     "font-awesome": "~4.5.0"
   },
   "resolutions": {

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
index dc074d7..762c281 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/index.js
@@ -23,10 +23,7 @@ module.exports = {
   name: 'hdfs-directory-viewer',
   included: function(app) {
     this._super.included(app);
-
     app.import(app.bowerDirectory + '/bootstrap/dist/css/bootstrap.css');
     app.import(app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js');
-    app.import(app.bowerDirectory + '/bootstrap-treeview/src/js/bootstrap-treeview.js');
-    app.import(app.bowerDirectory + '/bootstrap-treeview/dist/bootstrap-treeview.min.css');
   }
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/a06b6e1d/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
index 66a7b20..90e4357 100644
--- a/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
+++ b/contrib/views/commons/src/main/resources/ui/hdfs-directory-viewer/package.json
@@ -36,7 +36,10 @@
     "ember-disable-proxy-controllers": "^1.0.1",
     "ember-export-application-global": "^1.0.4",
     "ember-resolver": "^2.0.3",
-    "ember-try": "~0.0.8"
+    "ember-try": "~0.0.8",
+    "ember-truth-helpers": "1.2.0",
+    "ember-collection": "git://github.com/emberjs/ember-collection.git#4dbe10b7498886e277fc21b28139924f908d1926"
+
   },
   "keywords": [
     "ember-addon"


[6/8] ambari git commit: AMBARI-21258 Install Wizard: JS error when repository uses VDF. (atkach)

Posted by rl...@apache.org.
AMBARI-21258 Install Wizard: JS error when repository uses VDF. (atkach)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 58d77239b70d2295da23d476e5010bb60d4f1c88
Parents: f99e776
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Jun 15 16:00:42 2017 +0300
Committer: Andrii Tkach <at...@apache.org>
Committed: Thu Jun 15 16:00:42 2017 +0300

----------------------------------------------------------------------
 ambari-web/app/controllers/installer.js | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/58d77239/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index db9623a..9d7fcd8 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -618,7 +618,13 @@ App.InstallerController = App.WizardController.extend(App.Persist, {
       var stackInfo = {};
       stackInfo.dfd = dataInfo.dfd;
       stackInfo.response = response;
-      this.getSupportedOSList(data, stackInfo);
+      this.incrementProperty('loadStacksRequestsCounter');
+      this.getSupportedOSListSuccessCallback(data, null, {
+        stackName: data.VersionDefinition.stack_name,
+        stackVersion: data.VersionDefinition.stack_version,
+        versionDefinition: data,
+        stackInfo: stackInfo
+      });
     }
   },
 


[8/8] ambari git commit: Merge branch 'trunk' into branch-feature-AMBARI-20859

Posted by rl...@apache.org.
Merge branch 'trunk' into branch-feature-AMBARI-20859


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: d7bc588a14170ab0f15fd0f414f27a53fb69fc4a
Parents: 5b9454e 70f9bd6
Author: Robert Levas <rl...@hortonworks.com>
Authored: Thu Jun 15 10:20:05 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Thu Jun 15 10:20:05 2017 -0400

----------------------------------------------------------------------
 ambari-agent/pom.xml                            |   2 +-
 .../conf/batch/InfraManagerBatchConfig.java     |  11 +-
 .../ambari/infra/job/dummy/DummyItemWriter.java |  15 +-
 .../infra/job/dummy/DummyJobListener.java       |   7 +
 ambari-server/pom.xml                           |   2 +-
 .../server/controller/KerberosHelperImpl.java   |   6 +-
 .../services/YARN/configuration/yarn-site.xml   |   6 +
 .../stacks/HDP/2.6/services/stack_advisor.py    |  36 ++-
 .../server/controller/KerberosHelperTest.java   |   6 +-
 ambari-web/app/controllers/installer.js         |   8 +-
 ambari-web/app/controllers/main/host/details.js |  83 ++++-
 .../test/controllers/main/host/details_test.js  |  64 +++-
 .../addon/components/directory-viewer.js        | 324 +++++++++++++------
 .../hdfs-directory-viewer/addon/styles/app.css  | 190 +++++++++++
 .../templates/components/directory-viewer.hbs   | 145 +++++++++
 .../addon/utils/viewer-config.js                |   4 +
 .../ui/hdfs-directory-viewer/bower.json         |   1 -
 .../resources/ui/hdfs-directory-viewer/index.js |   3 -
 .../ui/hdfs-directory-viewer/package.json       |   5 +-
 19 files changed, 774 insertions(+), 144 deletions(-)
----------------------------------------------------------------------



[7/8] ambari git commit: AMBARI-20569. Configure KMS/Zookeeper settings automatically when multiple KMS are involved (alexantonenko)

Posted by rl...@apache.org.
AMBARI-20569. Configure KMS/Zookeeper settings automatically when multiple KMS are involved (alexantonenko)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 70f9bd6201ba2c3f406d414d52e40c6534abe870
Parents: 58d7723
Author: Alex Antonenko <hi...@gmail.com>
Authored: Thu Jun 15 13:32:07 2017 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Thu Jun 15 16:30:07 2017 +0300

----------------------------------------------------------------------
 ambari-web/app/controllers/main/host/details.js | 83 +++++++++++++++++---
 .../test/controllers/main/host/details_test.js  | 64 ++++++++++++---
 2 files changed, 128 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/70f9bd62/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index def75d6..6f34dfe 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -1407,7 +1407,10 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
       name: 'admin.get.all_configurations',
       sender: this,
       data: {
-        urlParams: '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')|(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')|(type=kms-env&tag=' + data.Clusters.desired_configs['kms-env'].tag + ')'
+        urlParams: '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')|' +
+        '(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')|' +
+        '(type=kms-env&tag=' + data.Clusters.desired_configs['kms-env'].tag + ')|' +
+        '(type=kms-site&tag=' + data.Clusters.desired_configs['kms-site'].tag + ')'
       },
       success: params.callback
     });
@@ -1420,7 +1423,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
    * @method onLoadRangerConfigs
    */
   onLoadRangerConfigs: function (data) {
-    var properties = [
+    var hdfsProperties = [
         {
           type: 'core-site',
           name: 'hadoop.security.key.provider.path'
@@ -1430,12 +1433,47 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
           name: 'dfs.encryption.key.provider.uri'
         }
       ],
+      kmsSiteProperties = [
+        {
+          name: 'hadoop.kms.cache.enable',
+          notHaValue: 'true',
+          haValue: 'false'
+        },
+        {
+          name: 'hadoop.kms.cache.timeout.ms',
+          notHaValue: '600000',
+          haValue: '0'
+        },
+        {
+          name: 'hadoop.kms.current.key.cache.timeout.ms',
+          notHaValue: '30000',
+          haValue: '0'
+        },
+        {
+          name: 'hadoop.kms.authentication.signer.secret.provider',
+          notHaValue: 'random',
+          haValue: 'zookeeper'
+        },
+        {
+          name: 'hadoop.kms.authentication.signer.secret.provider.zookeeper.auth.type',
+          notHaValue: 'kerberos',
+          haValue: 'none'
+        },
+        {
+          name: 'hadoop.kms.authentication.signer.secret.provider.zookeeper.connection.string',
+          notHaValue: '#HOSTNAME#:#PORT#,...',
+          haValue: this.getZookeeperConnectionString()
+        }
+      ],
       hostToInstall = this.get('rangerKMSServerHost'),
-      rkmsHosts = this.getRangerKMSServerHosts().join(';'),
+      rkmsHosts = this.getRangerKMSServerHosts(),
+      rkmsHostsStr = rkmsHosts.join(';'),
+      isHA = rkmsHosts.length > 1,
       rkmsPort = data.items.findProperty('type', 'kms-env').properties['kms_port'],
-      newValue = 'kms://http@' + rkmsHosts + ':' + rkmsPort + '/kms',
+      newValue = 'kms://http@' + rkmsHostsStr + ':' + rkmsPort + '/kms',
       coreSiteConfigs = data.items.findProperty('type', 'core-site'),
       hdfsSiteConfigs = data.items.findProperty('type', 'hdfs-site'),
+      kmsSiteConfigs = data.items.findProperty('type', 'kms-site'),
       groups = [
         {
           properties: {
@@ -1446,19 +1484,27 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
             'core-site': coreSiteConfigs.properties_attributes,
             'hdfs-site': hdfsSiteConfigs.properties_attributes
           }
+        },
+        {
+          properties: {
+            'kms-site': kmsSiteConfigs.properties
+          },
+          properties_attributes: {
+            'kms-site': kmsSiteConfigs.properties_attributes
+          }
         }
       ],
       propertiesToChange = this.get('allPropertiesToChange');
 
     this.saveLoadedConfigs(data);
 
-    properties.forEach(function (property) {
+    hdfsProperties.forEach(function (property) {
       var typeConfigs = data.items.findProperty('type', property.type).properties,
         currentValue = typeConfigs[property.name],
         pattern = new RegExp('^kms:\\/\\/http@(.+):' + rkmsPort + '\\/kms$'),
         patternMatch = currentValue && currentValue.match(pattern),
         currentHostsList = patternMatch && patternMatch[1].split(';').sort().join(';');
-      if (currentHostsList !== rkmsHosts) {
+      if (currentHostsList !== rkmsHostsStr) {
         typeConfigs[property.name] = newValue;
         if (this.get('isReconfigureRequired')) {
           var service = App.config.get('serviceByConfigTypeMap')[property.type];
@@ -1473,6 +1519,22 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
         }
       }
     }, this);
+
+    kmsSiteProperties.forEach(function (property) {
+      var currentValue = kmsSiteConfigs.properties[property.name];
+      var newValue = isHA ? property.haValue : property.notHaValue;
+      kmsSiteConfigs.properties[property.name] = newValue;
+
+      propertiesToChange.pushObject({
+        propertyFileName: 'kms-site',
+        propertyName: property.name,
+        serviceDisplayName: App.Service.find().findProperty('serviceName', 'RANGER_KMS').get('displayName'),
+        initialValue: currentValue,
+        recommendedValue: newValue,
+        saveRecommended: true
+      });
+    });
+
     if (this.get('isReconfigureRequired')) {
       this.setConfigsChanges(groups);
     } else {
@@ -1492,17 +1554,20 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
 
     if (!!rangerKMSServerHost) {
       rkmsHosts.push(rangerKMSServerHost);
-      this.set('rangerKMSServerHost', '');
     }
 
     if (this.get('fromDeleteHost') || this.get('deleteRangerKMSServer')) {
-      this.set('deleteRangerKMSServer', false);
-      this.set('fromDeleteHost', false);
       return rkmsHosts.without(this.get('content.hostName'));
     }
     return rkmsHosts.sort();
   },
 
+  getZookeeperConnectionString: function () {
+    return this.getRangerKMSServerHosts().map(function (host) {
+      return host + ':2181';
+    }).join(',');
+  },
+
   /**
    * Delete Storm Nimbus is performed
    * @type {bool}

http://git-wip-us.apache.org/repos/asf/ambari/blob/70f9bd62/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index c7e1808..34794f7 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -690,6 +690,9 @@ describe('App.MainHostDetailsController', function () {
           },
           'core-site': {
             tag: 'tag'
+          },
+          'kms-site': {
+            tag: 'tag'
           }
         }
       }}, null, {});
@@ -697,7 +700,7 @@ describe('App.MainHostDetailsController', function () {
       expect(args[0]).exists;
       expect(args[0].sender).to.be.eql(controller);
       expect(args[0].data).to.be.eql({
-        urlParams: '(type=core-site&tag=tag)|(type=hdfs-site&tag=tag)|(type=kms-env&tag=tag)'
+        urlParams: '(type=core-site&tag=tag)|(type=hdfs-site&tag=tag)|(type=kms-env&tag=tag)|(type=kms-site&tag=tag)'
       });
     });
   });
@@ -720,15 +723,6 @@ describe('App.MainHostDetailsController', function () {
     it('hosts list is valid', function() {
       expect(this.hosts).to.eql(['host2']);
     });
-    it('rangerKMSServerHost is empty', function () {
-      expect(controller.get('rangerKMSServerHost')).to.be.empty;
-    });
-    it('deleteRangerKMSServer is false', function () {
-      expect(controller.get('deleteRangerKMSServer')).to.be.false;
-    });
-    it('fromDeleteHost is false', function () {
-      expect(controller.get('fromDeleteHost')).to.be.false;
-    });
   });
 
   describe("#getStormNimbusHosts()", function() {
@@ -3257,6 +3251,21 @@ describe('App.MainHostDetailsController', function () {
               'core-site': undefined,
               'hdfs-site': undefined
             }
+          },
+          {
+            properties: {
+              'kms-site': {
+                'hadoop.kms.cache.enable': 'true',
+                'hadoop.kms.cache.timeout.ms': '600000',
+                'hadoop.kms.current.key.cache.timeout.ms': '30000',
+                'hadoop.kms.authentication.signer.secret.provider': 'random',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.auth.type': 'kerberos',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.connection.string': '#HOSTNAME#:#PORT#,...'
+              }
+            },
+            properties_attributes: {
+              'kms-site': undefined
+            }
           }
         ]
       },
@@ -3275,6 +3284,21 @@ describe('App.MainHostDetailsController', function () {
               'core-site': undefined,
               'hdfs-site': undefined
             }
+          },
+          {
+            properties: {
+              'kms-site': {
+                'hadoop.kms.cache.enable': 'false',
+                'hadoop.kms.cache.timeout.ms': '0',
+                'hadoop.kms.current.key.cache.timeout.ms': '0',
+                'hadoop.kms.authentication.signer.secret.provider': 'zookeeper',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.auth.type': 'none',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.connection.string': 'host1:2181,host2:2181'
+              }
+            },
+            properties_attributes: {
+              'kms-site': undefined
+            }
           }
         ]
       }
@@ -3282,11 +3306,20 @@ describe('App.MainHostDetailsController', function () {
 
     beforeEach(function () {
       sinon.spy(controller, 'saveConfigsBatch');
+      sinon.stub(App.Service, 'find', function () {
+        return [
+          Em.Object.create({
+            displayName: 'service',
+            serviceName: 'RANGER_KMS'
+          })
+        ];
+      });
       sinon.stub(controller, 'saveLoadedConfigs', Em.K);
     });
 
     afterEach(function () {
       controller.saveConfigsBatch.restore();
+      App.Service.find.restore();
       controller.saveLoadedConfigs.restore();
     });
 
@@ -3310,6 +3343,17 @@ describe('App.MainHostDetailsController', function () {
               properties: {
                 'dfs.encryption.key.provider.uri': 'kms://http@host2:port/kms'
               }
+            },
+            {
+              type: 'kms-site',
+              properties: {
+                'hadoop.kms.cache.enable': 'true',
+                'hadoop.kms.cache.timeout.ms': '600000',
+                'hadoop.kms.current.key.cache.timeout.ms': '30000',
+                'hadoop.kms.authentication.signer.secret.provider': 'random',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.auth.type': 'kerberos',
+                'hadoop.kms.authentication.signer.secret.provider.zookeeper.connection.string': '#HOSTNAME#:#PORT#,...'
+              }
             }
           ]
         };