You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/11/13 16:57:18 UTC

[01/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC integration (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-21674 c839dbfe4 -> ff8f686f8


http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
index 7bf26c5..e6f0868 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
@@ -18,15 +18,13 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
-import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.easymock.EasyMock.expectLastCall;
 
 import java.io.File;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -45,7 +43,7 @@ import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.stack.OsFamily;
-import org.easymock.EasyMock;
+import org.easymock.EasyMockSupport;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -53,11 +51,10 @@ import org.junit.Test;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.google.inject.Provider;
 
 import junit.framework.Assert;
 
-public class KerberosServerActionTest {
+public class KerberosServerActionTest extends EasyMockSupport {
 
   Map<String, String> commandParams = new HashMap<>();
   File temporaryDirectory;
@@ -66,49 +63,53 @@ public class KerberosServerActionTest {
 
   @Before
   public void setUp() throws Exception {
-    final Cluster cluster = mock(Cluster.class);
+    Cluster cluster = createMock(Cluster.class);
 
-    final Clusters clusters = mock(Clusters.class);
-    when(clusters.getCluster(anyString())).thenReturn(cluster);
+    Clusters clusters = createMock(Clusters.class);
+    expect(clusters.getCluster(anyString())).andReturn(cluster).anyTimes();
 
-    final ExecutionCommand mockExecutionCommand = mock(ExecutionCommand.class);
-    final HostRoleCommand mockHostRoleCommand = mock(HostRoleCommand.class);
+    ExecutionCommand mockExecutionCommand = createMock(ExecutionCommand.class);
+    HostRoleCommand mockHostRoleCommand = createMock(HostRoleCommand.class);
+
+    action = new KerberosServerAction() {
+
+      @Override
+      protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
+                                              KerberosOperationHandler operationHandler,
+                                              Map<String, String> kerberosConfiguration,
+                                              Map<String, Object> requestSharedDataContext)
+          throws AmbariException {
+        Assert.assertNotNull(requestSharedDataContext);
+
+        if (requestSharedDataContext.get("FAIL") != null) {
+          return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
+        } else {
+          requestSharedDataContext.put(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL), evaluatedPrincipal);
+          return null;
+        }
+      }
+
+      @Override
+      public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+          throws AmbariException, InterruptedException {
+        return processIdentities(requestSharedDataContext);
+      }
+    };
+    action.setExecutionCommand(mockExecutionCommand);
+    action.setHostRoleCommand(mockHostRoleCommand);
 
     injector = Guice.createInjector(new AbstractModule() {
 
       @Override
       protected void configure() {
-        bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
-        Provider<EntityManager> entityManagerProvider =  createNiceMock(Provider.class);
-        bind(EntityManager.class).toProvider(entityManagerProvider);
-        bind(KerberosServerAction.class).toInstance(new KerberosServerAction() {
-
-          @Override
-          protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
-                                                  KerberosOperationHandler operationHandler,
-                                                  Map<String, String> kerberosConfiguration,
-                                                  Map<String, Object> requestSharedDataContext)
-              throws AmbariException {
-            Assert.assertNotNull(requestSharedDataContext);
-
-            if (requestSharedDataContext.get("FAIL") != null) {
-              return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
-            } else {
-              requestSharedDataContext.put(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL), evaluatedPrincipal);
-              return null;
-            }
-          }
-
-          @Override
-          public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
-              throws AmbariException, InterruptedException {
-            return processIdentities(requestSharedDataContext);
-          }
-        });
+        bind(KerberosHelper.class).toInstance(createMock(KerberosHelper.class));
+        bind(KerberosServerAction.class).toInstance(action);
+        bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
 
         bind(Clusters.class).toInstance(clusters);
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
         bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
+        bind(KerberosOperationHandlerFactory.class).toInstance(createMock(KerberosOperationHandlerFactory.class));
       }
     });
 
@@ -133,13 +134,17 @@ public class KerberosServerActionTest {
     commandParams.put(KerberosServerAction.DEFAULT_REALM, "REALM.COM");
     commandParams.put(KerberosServerAction.KDC_TYPE, KDCType.MIT_KDC.toString());
 
-    when(mockExecutionCommand.getCommandParams()).thenReturn(commandParams);
-    when(mockExecutionCommand.getClusterName()).thenReturn("c1");
-
-    action = injector.getInstance(KerberosServerAction.class);
-
-    action.setExecutionCommand(mockExecutionCommand);
-    action.setHostRoleCommand(mockHostRoleCommand);
+    expect(mockExecutionCommand.getCommandParams()).andReturn(commandParams).anyTimes();
+    expect(mockExecutionCommand.getClusterName()).andReturn("c1").anyTimes();
+    expect(mockExecutionCommand.getConfigurations()).andReturn(Collections.emptyMap()).anyTimes();
+    expect(mockExecutionCommand.getRoleCommand()).andReturn(null).anyTimes();
+    expect(mockExecutionCommand.getConfigurationTags()).andReturn(null).anyTimes();
+    expect(mockExecutionCommand.getRole()).andReturn(null).anyTimes();
+    expect(mockExecutionCommand.getServiceName()).andReturn(null).anyTimes();
+    expect(mockExecutionCommand.getTaskId()).andReturn(1L).anyTimes();
+
+    expect(mockHostRoleCommand.getRequestId()).andReturn(1L).anyTimes();
+    expect(mockHostRoleCommand.getStageId()).andReturn(1L).anyTimes();
   }
 
   @After
@@ -189,17 +194,28 @@ public class KerberosServerActionTest {
 
   @Test
   public void testGetDataDirectoryPath() throws Exception {
+    replayAll();
     Assert.assertEquals(temporaryDirectory.getAbsolutePath(), action.getDataDirectoryPath());
+    verifyAll();
   }
 
   @Test
   public void testProcessIdentitiesSuccess() throws Exception {
     KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
-    expect(kerberosHelper.getKDCAdministratorCredentials(EasyMock.anyObject(String.class)))
+    expect(kerberosHelper.getKDCAdministratorCredentials(anyObject(String.class)))
         .andReturn(new PrincipalKeyCredential("principal", "password"))
         .anyTimes();
 
-    replay(kerberosHelper);
+    KerberosOperationHandler kerberosOperationHandler = createMock(KerberosOperationHandler.class);
+    kerberosOperationHandler.open(anyObject(PrincipalKeyCredential.class), anyString(), anyObject(Map.class));
+    expectLastCall().atLeastOnce();
+    kerberosOperationHandler.close();
+    expectLastCall().atLeastOnce();
+
+    KerberosOperationHandlerFactory factory = injector.getInstance(KerberosOperationHandlerFactory.class);
+    expect(factory.getKerberosOperationHandler(KDCType.MIT_KDC)).andReturn(kerberosOperationHandler).once();
+
+    replayAll();
 
     ConcurrentMap<String, Object> sharedMap = new ConcurrentHashMap<>();
     CommandReport report = action.processIdentities(sharedMap);
@@ -210,17 +226,26 @@ public class KerberosServerActionTest {
       Assert.assertEquals(entry.getValue(), entry.getKey());
     }
 
-    verify(kerberosHelper);
+    verifyAll();
   }
 
   @Test
   public void testProcessIdentitiesFail() throws Exception {
     KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
-    expect(kerberosHelper.getKDCAdministratorCredentials(EasyMock.anyObject(String.class)))
+    expect(kerberosHelper.getKDCAdministratorCredentials(anyObject(String.class)))
         .andReturn(new PrincipalKeyCredential("principal", "password"))
         .anyTimes();
 
-    replay(kerberosHelper);
+    KerberosOperationHandler kerberosOperationHandler = createMock(KerberosOperationHandler.class);
+    kerberosOperationHandler.open(anyObject(PrincipalKeyCredential.class), anyString(), anyObject(Map.class));
+    expectLastCall().atLeastOnce();
+    kerberosOperationHandler.close();
+    expectLastCall().atLeastOnce();
+
+    KerberosOperationHandlerFactory factory = injector.getInstance(KerberosOperationHandlerFactory.class);
+    expect(factory.getKerberosOperationHandler(KDCType.MIT_KDC)).andReturn(kerberosOperationHandler).once();
+
+    replayAll();
 
     ConcurrentMap<String, Object> sharedMap = new ConcurrentHashMap<>();
     sharedMap.put("FAIL", "true");
@@ -229,6 +254,6 @@ public class KerberosServerActionTest {
     Assert.assertNotNull(report);
     Assert.assertEquals(HostRoleStatus.FAILED.toString(), report.getStatus());
 
-    verify(kerberosHelper);
+    verifyAll();
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index 04d03be..848d479 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -19,12 +19,9 @@
 package org.apache.ambari.server.serveraction.kerberos;
 
 import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.newCapture;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
 
 import java.lang.reflect.Method;
 import java.util.HashMap;
@@ -36,11 +33,8 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.stack.OsFamily;
 import org.apache.ambari.server.utils.ShellCommandUtil;
 import org.easymock.Capture;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.easymock.IMockBuilder;
+import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.inject.AbstractModule;
@@ -49,15 +43,7 @@ import com.google.inject.Injector;
 
 import junit.framework.Assert;
 
-public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
-
-  private static final String DEFAULT_ADMIN_PRINCIPAL = "admin/admin";
-  private static final String DEFAULT_ADMIN_PASSWORD = "hadoop";
-  private static final String DEFAULT_REALM = "EXAMPLE.COM";
-
-  private static Injector injector;
-
-  private static Method methodExecuteCommand;
+public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
 
   private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
     {
@@ -69,105 +55,75 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
     }
   };
 
+  private static Method methodIsOpen;
+
+  private static Method methodPrincipalExists;
+
+  private static Method methodInvokeKAdmin;
+
+  private Injector injector;
+
   @BeforeClass
-  public static void beforeClass() throws Exception {
+  public static void beforeClassMITKerberosOperationHandlerTestC() throws Exception {
+    methodIsOpen = KerberosOperationHandler.class.getDeclaredMethod("isOpen");
+    methodPrincipalExists = MITKerberosOperationHandler.class.getDeclaredMethod("principalExists", String.class, boolean.class);
+    methodInvokeKAdmin = MITKerberosOperationHandler.class.getDeclaredMethod("invokeKAdmin", String.class);
+  }
+
+  @Before
+  public void beforeMITKerberosOperationHandlerTest() throws Exception {
     injector = Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
-        Configuration configuration = EasyMock.createNiceMock(Configuration.class);
+        Configuration configuration = createNiceMock(Configuration.class);
         expect(configuration.getServerOsFamily()).andReturn("redhat6").anyTimes();
         expect(configuration.getKerberosOperationRetryTimeout()).andReturn(1).anyTimes();
-        replay(configuration);
 
-        bind(Clusters.class).toInstance(EasyMock.createNiceMock(Clusters.class));
+        bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
         bind(Configuration.class).toInstance(configuration);
-        bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
       }
     });
-
-    methodExecuteCommand = KerberosOperationHandler.class.getDeclaredMethod(
-        "executeCommand",
-        String[].class,
-        Map.class,
-        ShellCommandUtil.InteractiveHandler.class);
   }
 
+
   @Test
-  public void testSetPrincipalPasswordExceptions() throws Exception {
-    MITKerberosOperationHandler handler = injector.getInstance(MITKerberosOperationHandler.class);
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+  public void testSetPrincipalPassword() throws Exception {
+    MITKerberosOperationHandler handler = createMockedHandler(methodIsOpen, methodPrincipalExists);
 
-    try {
-      handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null);
-      Assert.fail("KerberosOperationException not thrown for null password");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    expect(handler.isOpen()).andReturn(true).atLeastOnce();
+    expect(handler.principalExists(DEFAULT_ADMIN_PRINCIPAL, false)).andReturn(true).atLeastOnce();
+    expect(handler.principalExists(null, false)).andReturn(false).atLeastOnce();
+    expect(handler.principalExists("", false)).andReturn(false).atLeastOnce();
 
-    try {
-      handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "");
-      Assert.fail("KerberosOperationException not thrown for empty password");
-      handler.createPrincipal("", "1234", false);
-      Assert.fail("AmbariException not thrown for empty principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    replayAll();
+
+    Integer expected = 0;
+
+    // setPrincipalPassword should always return 0
+    Assert.assertEquals(expected, handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null, false));
+    Assert.assertEquals(expected, handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "", false));
 
     try {
-      handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD);
-      Assert.fail("KerberosOperationException not thrown for null principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
+      handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD, false);
+      Assert.fail("Expected KerberosPrincipalDoesNotExistException");
+    } catch (KerberosPrincipalDoesNotExistException e) {
+      // Expected...
     }
 
     try {
-      handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD);
-      Assert.fail("KerberosOperationException not thrown for empty principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
+      handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD, false);
+      Assert.fail("Expected KerberosPrincipalDoesNotExistException");
+    } catch (KerberosPrincipalDoesNotExistException e) {
+      // Expected...
     }
-  }
-
-  @Test(expected = KerberosPrincipalDoesNotExistException.class)
-  public void testSetPrincipalPasswordPrincipalDoesNotExist() throws Exception {
 
-    MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
-        .addMockedMethod(methodExecuteCommand)
-        .createNiceMock();
-    injector.injectMembers(handler);
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(0).anyTimes();
-            expect(result.isSuccessful()).andReturn(true).anyTimes();
-            expect(result.getStderr())
-                .andReturn("change_password: Principal does not exist while changing password for \"nonexistant@EXAMPLE.COM\".")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.setPrincipalPassword("nonexistant@EXAMPLE.COM", "password");
-    handler.close();
+    verifyAll();
   }
 
   @Test
   public void testCreateServicePrincipal_AdditionalAttributes() throws Exception {
-    Method invokeKAdmin = MITKerberosOperationHandler.class.getDeclaredMethod("invokeKAdmin", String.class, String.class);
-
     Capture<? extends String> query = newCapture();
-    Capture<? extends String> password = newCapture();
 
     ShellCommandUtil.Result result1 = createNiceMock(ShellCommandUtil.Result.class);
     expect(result1.getStderr()).andReturn("").anyTimes();
@@ -177,72 +133,40 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
     expect(result2.getStderr()).andReturn("").anyTimes();
     expect(result2.getStdout()).andReturn("Key: vno 1").anyTimes();
 
-    MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
-        .addMockedMethod(invokeKAdmin)
-        .createStrictMock();
+    ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+    expect(kinitResult.isSuccessful()).andReturn(true);
 
-    expect(handler.invokeKAdmin(capture(query), anyString())).andReturn(result1).once();
-    expect(handler.invokeKAdmin("get_principal " + DEFAULT_ADMIN_PRINCIPAL, null)).andReturn(result2).once();
+    MITKerberosOperationHandler handler = createMockedHandler(methodInvokeKAdmin, methodExecuteCommand);
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kinitResult)
+        .once();
+    expect(handler.invokeKAdmin(capture(query))).andReturn(result1).once();
 
-    replay(handler, result1, result2);
+    replayAll();
 
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+    handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
     handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD, false);
+    handler.close();
 
-    verify(handler, result1, result2);
+    verifyAll();
 
     Assert.assertTrue(query.getValue().contains(" " + KERBEROS_ENV_MAP.get(MITKerberosOperationHandler.KERBEROS_ENV_KDC_CREATE_ATTRIBUTES) + " "));
   }
 
-  @Test(expected = KerberosPrincipalAlreadyExistsException.class)
-  public void testCreatePrincipalPrincipalAlreadyNotExists() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(0).anyTimes();
-            expect(result.isSuccessful()).andReturn(true).anyTimes();
-            expect(result.getStderr())
-                .andReturn("add_principal: Principal or policy already exists while creating \"existing@EXAMPLE.COM\".")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.createPrincipal("existing@EXAMPLE.COM", "password", false);
-    handler.close();
-  }
 
   @Test
-  public void testCreateServicePrincipal_Exceptions() throws Exception {
-    MITKerberosOperationHandler handler = new MITKerberosOperationHandler();
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+  public void testCreateServicePrincipalExceptions() throws Exception {
+    ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+    expect(kinitResult.isSuccessful()).andReturn(true);
 
-    try {
-      handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, null, false);
-      Assert.fail("KerberosOperationException not thrown for null password");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kinitResult)
+        .once();
 
-    try {
-      handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, "", false);
-      Assert.fail("KerberosOperationException not thrown for empty password");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    replayAll();
+
+    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
 
     try {
       handler.createPrincipal(null, DEFAULT_ADMIN_PASSWORD, false);
@@ -257,339 +181,156 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
     } catch (Throwable t) {
       Assert.assertEquals(KerberosOperationException.class, t.getClass());
     }
-  }
 
-  @Test(expected = KerberosAdminAuthenticationException.class)
-  public void testTestAdministratorCredentialsIncorrectAdminPassword() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Incorrect password while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
-  }
-
-  @Test(expected = KerberosAdminAuthenticationException.class)
-  public void testTestAdministratorCredentialsIncorrectAdminPrincipal() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Client not found in Kerberos database while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
-  }
-
-  @Test(expected = KerberosRealmException.class)
-  public void testTestAdministratorCredentialsInvalidRealm() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Missing parameters in krb5.conf required for kadmin client while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
-  }
-
-  @Test(expected = KerberosRealmException.class)
-  public void testTestAdministratorCredentialsInvalidRealm2() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Cannot find KDC for requested realm while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
+    verifyAll();
   }
 
   @Test(expected = KerberosKDCConnectionException.class)
-  public void testTestAdministratorCredentialsKDCConnectionException() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Cannot contact any KDC for requested realm while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
+  public void testKDCConnectionException() throws Exception {
+    ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+    expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+    ShellCommandUtil.Result kadminResult = createMock(ShellCommandUtil.Result.class);
+    expect(kadminResult.getExitCode()).andReturn(1).anyTimes();
+    expect(kadminResult.isSuccessful()).andReturn(false).anyTimes();
+    expect(kadminResult.getStderr())
+        .andReturn("kadmin: Cannot contact any KDC for requested realm while initializing kadmin interface")
+        .anyTimes();
+    expect(kadminResult.getStdout())
+        .andReturn("Authenticating as principal admin/admin with password.")
+        .anyTimes();
+
+    MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kinitResult)
+        .once();
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kadminResult)
+        .once();
 
     replayAll();
 
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+    handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
     handler.testAdministratorCredentials();
     handler.close();
+
+    verifyAll();
   }
 
   @Test(expected = KerberosKDCConnectionException.class)
   public void testTestAdministratorCredentialsKDCConnectionException2() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(1).anyTimes();
-            expect(result.isSuccessful()).andReturn(false).anyTimes();
-            expect(result.getStderr())
-                .andReturn("kadmin: Cannot resolve network address for admin server in requested realm while initializing kadmin interface")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
+    ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+    expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+    ShellCommandUtil.Result kadminResult = createMock(ShellCommandUtil.Result.class);
+    expect(kadminResult.getExitCode()).andReturn(1).anyTimes();
+    expect(kadminResult.isSuccessful()).andReturn(false).anyTimes();
+    expect(kadminResult.getStderr())
+        .andReturn("kadmin: Cannot resolve network address for admin server in requested realm while initializing kadmin interface")
+        .anyTimes();
+    expect(kadminResult.getStdout())
+        .andReturn("Authenticating as principal admin/admin with password.")
+        .anyTimes();
+
+    MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kinitResult)
+        .once();
+    expect(handler.executeCommand(anyObject(String[].class), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(kadminResult)
+        .once();
 
     replayAll();
 
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+    handler.open(getAdminCredentials(), DEFAULT_REALM, KERBEROS_ENV_MAP);
     handler.testAdministratorCredentials();
     handler.close();
-  }
-
-  @Test
-  public void testTestAdministratorCredentialsNotFound() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(0).anyTimes();
-            expect(result.isSuccessful()).andReturn(true).anyTimes();
-            expect(result.getStderr())
-                .andReturn("get_principal: Principal does not exist while retrieving \"admin/admi@EXAMPLE.COM\".")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
 
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    Assert.assertFalse(handler.testAdministratorCredentials());
-    handler.close();
+    verifyAll();
   }
 
-  @Test
-  public void testTestAdministratorCredentialsSuccess() throws Exception {
-    MITKerberosOperationHandler handler = createMock();
-
-    expect(handler.executeCommand(anyObject(String[].class), EasyMock.anyObject(), anyObject(MITKerberosOperationHandler.InteractivePasswordHandler.class)))
-        .andAnswer(new IAnswer<ShellCommandUtil.Result>() {
-          @Override
-          public ShellCommandUtil.Result answer() throws Throwable {
-            ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
-
-            expect(result.getExitCode()).andReturn(0).anyTimes();
-            expect(result.isSuccessful()).andReturn(true).anyTimes();
-            expect(result.getStderr())
-                .andReturn("")
-                .anyTimes();
-            expect(result.getStdout())
-                .andReturn("Authenticating as principal admin/admin with password.\n" +
-                    "Principal: admin/admin@EXAMPLE.COM\n" +
-                    "Expiration date: [never]\n" +
-                    "Last password change: Thu Jan 08 13:09:52 UTC 2015\n" +
-                    "Password expiration date: [none]\n" +
-                    "Maximum ticket life: 1 day 00:00:00\n" +
-                    "Maximum renewable life: 0 days 00:00:00\n" +
-                    "Last modified: Thu Jan 08 13:09:52 UTC 2015 (root/admin@EXAMPLE.COM)\n" +
-                    "Last successful authentication: [never]\n" +
-                    "Last failed authentication: [never]\n" +
-                    "Failed password attempts: 0\n" +
-                    "Number of keys: 6\n" +
-                    "Key: vno 1, aes256-cts-hmac-sha1-96, no salt\n" +
-                    "Key: vno 1, aes128-cts-hmac-sha1-96, no salt\n" +
-                    "Key: vno 1, des3-cbc-sha1, no salt\n" +
-                    "Key: vno 1, arcfour-hmac, no salt\n" +
-                    "Key: vno 1, des-hmac-sha1, no salt\n" +
-                    "Key: vno 1, des-cbc-md5, no salt\n" +
-                    "MKey: vno 1\n" +
-                    "Attributes:\n" +
-                    "Policy: [none]")
-                .anyTimes();
-
-            replay(result);
-            return result;
-          }
-        });
-
-    replayAll();
-
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
+  @Override
+  protected MITKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+    MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)
+        .addMockedMethods(mockedMethods)
+        .createMock();
+    injector.injectMembers(handler);
+    return handler;
   }
 
-  @Test
-  @Ignore
-  public void testTestAdministratorCredentialsLive() throws KerberosOperationException {
-    MITKerberosOperationHandler handler = new MITKerberosOperationHandler();
-    String principal = System.getProperty("principal");
-    String password = System.getProperty("password");
-    String realm = System.getProperty("realm");
-
-    if (principal == null) {
-      principal = DEFAULT_ADMIN_PRINCIPAL;
-    }
-
-    if (password == null) {
-      password = DEFAULT_ADMIN_PASSWORD;
-    }
-
-    if (realm == null) {
-      realm = DEFAULT_REALM;
-    }
-
-    PrincipalKeyCredential credentials = new PrincipalKeyCredential(principal, password);
-
-    handler.open(credentials, realm, KERBEROS_ENV_MAP);
-    handler.testAdministratorCredentials();
-    handler.close();
+  @Override
+  protected Map<String, String> getKerberosEnv() {
+    return KERBEROS_ENV_MAP;
   }
 
-  @Test
-  public void testInteractivePasswordHandler() {
-    MITKerberosOperationHandler.InteractivePasswordHandler handler = new MITKerberosOperationHandler.InteractivePasswordHandler("admin_password", "user_password");
-
-    handler.start();
-    Assert.assertEquals("admin_password", handler.getResponse("password"));
-    Assert.assertFalse(handler.done());
-    Assert.assertEquals("user_password", handler.getResponse("password"));
-    Assert.assertFalse(handler.done());
-    Assert.assertEquals("user_password", handler.getResponse("password"));
-    Assert.assertTrue(handler.done());
-
-    // Test restarting
-    handler.start();
-    Assert.assertEquals("admin_password", handler.getResponse("password"));
-    Assert.assertFalse(handler.done());
-    Assert.assertEquals("user_password", handler.getResponse("password"));
-    Assert.assertFalse(handler.done());
-    Assert.assertEquals("user_password", handler.getResponse("password"));
-    Assert.assertTrue(handler.done());
+  @Override
+  protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(0).anyTimes();
+    expect(result.isSuccessful()).andReturn(true).anyTimes();
+    expect(result.getStderr())
+        .andReturn(String.format("add_principal: Principal or policy already exists while creating \"%s@EXAMPLE.COM\".", (service) ? "service/host" : "user"))
+        .anyTimes();
+    expect(result.getStdout())
+        .andReturn("Authenticating as principal admin/admin with password.")
+        .anyTimes();
+
+    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
   }
 
-  private MITKerberosOperationHandler createMock(){
-    return createMock(false);
+  @Override
+  protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(0).anyTimes();
+    expect(result.isSuccessful()).andReturn(true).anyTimes();
+    expect(result.getStderr())
+        .andReturn(String.format("get_principal: Principal does not exist while retrieving \"%s@EXAMPLE.COM\".", (service) ? "service/host" : "user"))
+        .anyTimes();
+    expect(result.getStdout())
+        .andReturn("Authenticating as principal admin/admin with password.")
+        .anyTimes();
+
+    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
   }
 
-  private MITKerberosOperationHandler createMock(boolean strict) {
-    IMockBuilder<MITKerberosOperationHandler> mockBuilder = createMockBuilder(MITKerberosOperationHandler.class)
-        .addMockedMethod(methodExecuteCommand);
-    MITKerberosOperationHandler result;
-    if(strict){
-      result = mockBuilder.createStrictMock();
-    } else {
-      result = mockBuilder.createNiceMock();
-    }
-    injector.injectMembers(result);
-    return result;
+  @Override
+  protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(0).anyTimes();
+    expect(result.isSuccessful()).andReturn(true).anyTimes();
+    expect(result.getStderr())
+        .andReturn("")
+        .anyTimes();
+    expect(result.getStdout())
+        .andReturn(String.format("Authenticating as principal admin/admin with password.\n" +
+            "Principal: %s@EXAMPLE.COM\n" +
+            "Expiration date: [never]\n" +
+            "Last password change: Thu Jan 08 13:09:52 UTC 2015\n" +
+            "Password expiration date: [none]\n" +
+            "Maximum ticket life: 1 day 00:00:00\n" +
+            "Maximum renewable life: 0 days 00:00:00\n" +
+            "Last modified: Thu Jan 08 13:09:52 UTC 2015 (root/admin@EXAMPLE.COM)\n" +
+            "Last successful authentication: [never]\n" +
+            "Last failed authentication: [never]\n" +
+            "Failed password attempts: 0\n" +
+            "Number of keys: 6\n" +
+            "Key: vno 1, aes256-cts-hmac-sha1-96, no salt\n" +
+            "Key: vno 1, aes128-cts-hmac-sha1-96, no salt\n" +
+            "Key: vno 1, des3-cbc-sha1, no salt\n" +
+            "Key: vno 1, arcfour-hmac, no salt\n" +
+            "Key: vno 1, des-hmac-sha1, no salt\n" +
+            "Key: vno 1, des-cbc-md5, no salt\n" +
+            "MKey: vno 1\n" +
+            "Attributes:\n" +
+            "Policy: [none]", (service) ? "service/host" : "user"))
+        .anyTimes();
+
+    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
index 25e9dbf..bd8f5cb 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
@@ -24,7 +24,9 @@ import static org.apache.ambari.server.upgrade.UpgradeCatalog300.SERVICE_DESIRED
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.expectLastCall;
@@ -34,19 +36,23 @@ import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertTrue;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.persistence.EntityManager;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
 import org.apache.ambari.server.orm.DBAccessor;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -130,13 +136,15 @@ public class UpgradeCatalog300Test {
     Method showHcatDeletedUserMessage = UpgradeCatalog300.class.getDeclaredMethod("showHcatDeletedUserMessage");
     Method setStatusOfStagesAndRequests = UpgradeCatalog300.class.getDeclaredMethod("setStatusOfStagesAndRequests");
     Method updateLogSearchConfigs = UpgradeCatalog300.class.getDeclaredMethod("updateLogSearchConfigs");
-
-   UpgradeCatalog300 upgradeCatalog300 = createMockBuilder(UpgradeCatalog300.class)
-            .addMockedMethod(showHcatDeletedUserMessage)
-            .addMockedMethod(addNewConfigurationsFromXml)
-            .addMockedMethod(setStatusOfStagesAndRequests)
-            .addMockedMethod(updateLogSearchConfigs)
-            .createMock();
+    Method updateKerberosConfigurations = UpgradeCatalog300.class.getDeclaredMethod("updateKerberosConfigurations");
+
+    UpgradeCatalog300 upgradeCatalog300 = createMockBuilder(UpgradeCatalog300.class)
+        .addMockedMethod(showHcatDeletedUserMessage)
+        .addMockedMethod(addNewConfigurationsFromXml)
+        .addMockedMethod(setStatusOfStagesAndRequests)
+        .addMockedMethod(updateLogSearchConfigs)
+        .addMockedMethod(updateKerberosConfigurations)
+        .createMock();
 
 
     upgradeCatalog300.addNewConfigurationsFromXml();
@@ -146,6 +154,9 @@ public class UpgradeCatalog300Test {
     upgradeCatalog300.updateLogSearchConfigs();
     expectLastCall().once();
 
+    upgradeCatalog300.updateKerberosConfigurations();
+    expectLastCall().once();
+
     replay(upgradeCatalog300);
 
     upgradeCatalog300.executeDMLUpdates();
@@ -168,9 +179,12 @@ public class UpgradeCatalog300Test {
     Capture<DBAccessor.DBColumnInfo> hrcOpsDisplayNameColumn = newCapture();
     dbAccessor.addColumn(eq(UpgradeCatalog300.HOST_ROLE_COMMAND_TABLE), capture(hrcOpsDisplayNameColumn));
 
-    dbAccessor.dropColumn(COMPONENT_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
-    dbAccessor.dropColumn(COMPONENT_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
-    dbAccessor.dropColumn(SERVICE_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN); expectLastCall().once();
+    dbAccessor.dropColumn(COMPONENT_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN);
+    expectLastCall().once();
+    dbAccessor.dropColumn(COMPONENT_STATE_TABLE, SECURITY_STATE_COLUMN);
+    expectLastCall().once();
+    dbAccessor.dropColumn(SERVICE_DESIRED_STATE_TABLE, SECURITY_STATE_COLUMN);
+    expectLastCall().once();
 
     replay(dbAccessor, configuration);
 
@@ -221,9 +235,9 @@ public class UpgradeCatalog300Test {
     Collection<Config> configs = Arrays.asList(confSomethingElse1, confLogSearchConf1, confSomethingElse2, confLogSearchConf2);
 
     expect(cluster.getAllConfigs()).andReturn(configs).atLeastOnce();
-    configHelper.removeConfigsByType(cluster,"service-1-logsearch-conf");
+    configHelper.removeConfigsByType(cluster, "service-1-logsearch-conf");
     expectLastCall().once();
-    configHelper.removeConfigsByType(cluster,"service-2-logsearch-conf");
+    configHelper.removeConfigsByType(cluster, "service-2-logsearch-conf");
     expectLastCall().once();
     configHelper.createConfigType(anyObject(Cluster.class), anyObject(StackId.class), eq(controller),
         eq("logsearch-common-properties"), eq(Collections.emptyMap()), eq("ambari-upgrade"),
@@ -307,23 +321,23 @@ public class UpgradeCatalog300Test {
     Map<String, String> oldLogFeederOutputConf = ImmutableMap.of(
         "content",
         "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
-        "      \"collection\":\"{{logsearch_solr_collection_service_logs}}\",\n" +
-        "      \"number_of_shards\": \"{{logsearch_collection_service_logs_numshards}}\",\n" +
-        "      \"splits_interval_mins\": \"{{logsearch_service_logs_split_interval_mins}}\",\n" +
-        "\n" +
-        "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
-        "      \"collection\":\"{{logsearch_solr_collection_audit_logs}}\",\n" +
-        "      \"number_of_shards\": \"{{logsearch_collection_audit_logs_numshards}}\",\n" +
-        "      \"splits_interval_mins\": \"{{logsearch_audit_logs_split_interval_mins}}\",\n"
+            "      \"collection\":\"{{logsearch_solr_collection_service_logs}}\",\n" +
+            "      \"number_of_shards\": \"{{logsearch_collection_service_logs_numshards}}\",\n" +
+            "      \"splits_interval_mins\": \"{{logsearch_service_logs_split_interval_mins}}\",\n" +
+            "\n" +
+            "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
+            "      \"collection\":\"{{logsearch_solr_collection_audit_logs}}\",\n" +
+            "      \"number_of_shards\": \"{{logsearch_collection_audit_logs_numshards}}\",\n" +
+            "      \"splits_interval_mins\": \"{{logsearch_audit_logs_split_interval_mins}}\",\n"
     );
 
     Map<String, String> expectedLogFeederOutputConf = ImmutableMap.of(
         "content",
         "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
-        "      \"type\": \"service\",\n" +
-        "\n" +
-        "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
-        "      \"type\": \"audit\",\n"
+            "      \"type\": \"service\",\n" +
+            "\n" +
+            "      \"zk_connect_string\":\"{{logsearch_solr_zk_quorum}}{{logsearch_solr_zk_znode}}\",\n" +
+            "      \"type\": \"audit\",\n"
     );
 
     Config logFeederOutputConf = easyMockSupport.createNiceMock(Config.class);
@@ -343,10 +357,10 @@ public class UpgradeCatalog300Test {
     new UpgradeCatalog300(injector2).updateLogSearchConfigs();
     easyMockSupport.verifyAll();
 
-    Map<String,String> newLogFeederProperties = logFeederPropertiesCapture.getValue();
+    Map<String, String> newLogFeederProperties = logFeederPropertiesCapture.getValue();
     assertTrue(Maps.difference(expectedLogFeederProperties, newLogFeederProperties).areEqual());
 
-    Map<String,String> newLogSearchProperties = logSearchPropertiesCapture.getValue();
+    Map<String, String> newLogSearchProperties = logSearchPropertiesCapture.getValue();
     assertTrue(Maps.difference(Collections.emptyMap(), newLogSearchProperties).areEqual());
 
     Map<String, String> updatedLogFeederLog4j = logFeederLog4jCapture.getValue();
@@ -364,4 +378,90 @@ public class UpgradeCatalog300Test {
     Map<String, String> updatedLogFeederOutputConf = logFeederOutputConfCapture.getValue();
     assertTrue(Maps.difference(expectedLogFeederOutputConf, updatedLogFeederOutputConf).areEqual());
   }
+
+  @Test
+  public void testUpdateKerberosConfigurations() throws AmbariException, NoSuchFieldException, IllegalAccessException {
+    StackId stackId = new StackId("HDP", "2.6.0.0");
+
+    Map<String, Cluster> clusterMap = new HashMap<>();
+
+    Map<String, String> propertiesWithGroup = new HashMap<>();
+    propertiesWithGroup.put("group", "ambari_managed_identities");
+    propertiesWithGroup.put("kdc_host", "host1.example.com");
+
+    Config newConfig = createMock(Config.class);
+    expect(newConfig.getTag()).andReturn("version2").atLeastOnce();
+    expect(newConfig.getType()).andReturn("kerberos-env").atLeastOnce();
+
+    ServiceConfigVersionResponse response = createMock(ServiceConfigVersionResponse.class);
+
+    Config configWithGroup = createMock(Config.class);
+    expect(configWithGroup.getProperties()).andReturn(propertiesWithGroup).atLeastOnce();
+    expect(configWithGroup.getPropertiesAttributes()).andReturn(Collections.emptyMap()).atLeastOnce();
+    expect(configWithGroup.getTag()).andReturn("version1").atLeastOnce();
+
+    Cluster cluster1 = createMock(Cluster.class);
+    expect(cluster1.getDesiredConfigByType("kerberos-env")).andReturn(configWithGroup).atLeastOnce();
+    expect(cluster1.getConfigsByType("kerberos-env")).andReturn(Collections.singletonMap("v1", configWithGroup)).atLeastOnce();
+    expect(cluster1.getServiceByConfigType("kerberos-env")).andReturn("KERBEROS").atLeastOnce();
+    expect(cluster1.getClusterName()).andReturn("c1").atLeastOnce();
+    expect(cluster1.getDesiredStackVersion()).andReturn(stackId).atLeastOnce();
+    expect(cluster1.getConfig(eq("kerberos-env"), anyString())).andReturn(newConfig).atLeastOnce();
+    expect(cluster1.addDesiredConfig("ambari-upgrade", Collections.singleton(newConfig), "Updated kerberos-env during Ambari Upgrade from 2.6.0 to 3.0.0.")).andReturn(response).once();
+
+    Map<String, String> propertiesWithoutGroup = new HashMap<>();
+    propertiesWithoutGroup.put("kdc_host", "host2.example.com");
+
+    Config configWithoutGroup = createMock(Config.class);
+    expect(configWithoutGroup.getProperties()).andReturn(propertiesWithoutGroup).atLeastOnce();
+
+    Cluster cluster2 = createMock(Cluster.class);
+    expect(cluster2.getDesiredConfigByType("kerberos-env")).andReturn(configWithoutGroup).atLeastOnce();
+
+    Cluster cluster3 = createMock(Cluster.class);
+    expect(cluster3.getDesiredConfigByType("kerberos-env")).andReturn(null).atLeastOnce();
+
+    clusterMap.put("c1", cluster1);
+    clusterMap.put("c2", cluster2);
+    clusterMap.put("c3", cluster3);
+
+    Clusters clusters = createMock(Clusters.class);
+    expect(clusters.getClusters()).andReturn(clusterMap).anyTimes();
+
+    Capture<Map<String, String>> capturedProperties = newCapture();
+
+    AmbariManagementControllerImpl controller = createMockBuilder(AmbariManagementControllerImpl.class)
+        .addMockedMethod("createConfiguration")
+        .addMockedMethod("getClusters", new Class[]{})
+        .addMockedMethod("createConfig")
+        .createMock();
+    expect(controller.getClusters()).andReturn(clusters).anyTimes();
+    expect(controller.createConfig(eq(cluster1), eq(stackId), eq("kerberos-env"), capture(capturedProperties), anyString(), anyObject(Map.class))).andReturn(newConfig).once();
+
+
+    Injector injector = createNiceMock(Injector.class);
+    expect(injector.getInstance(AmbariManagementController.class)).andReturn(controller).anyTimes();
+
+    replay(controller, clusters, cluster1, cluster2, configWithGroup, configWithoutGroup, newConfig, response, injector);
+
+    Field field = AbstractUpgradeCatalog.class.getDeclaredField("configuration");
+
+    UpgradeCatalog300 upgradeCatalog300 = new UpgradeCatalog300(injector);
+    field.set(upgradeCatalog300, configuration);
+    upgradeCatalog300.updateKerberosConfigurations();
+
+    verify(controller, clusters, cluster1, cluster2, configWithGroup, configWithoutGroup, newConfig, response, injector);
+
+
+    Assert.assertEquals(1, capturedProperties.getValues().size());
+
+    Map<String, String> properties = capturedProperties.getValue();
+    Assert.assertEquals(2, properties.size());
+    Assert.assertEquals("ambari_managed_identities", properties.get("ipa_user_group"));
+    Assert.assertEquals("host1.example.com", properties.get("kdc_host"));
+
+    Assert.assertEquals(2, propertiesWithGroup.size());
+    Assert.assertEquals("ambari_managed_identities", propertiesWithGroup.get("group"));
+    Assert.assertEquals("host1.example.com", propertiesWithGroup.get("kdc_host"));
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json b/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
index 288d155..69000df 100644
--- a/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
+++ b/ambari-server/src/test/python/stacks/2.5/configs/ranger-admin-secured.json
@@ -432,9 +432,7 @@
             "create_ambari_principal": "true",
             "service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
             "executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
-            "password_chat_timeout": "5",
             "kdc_type": "mit-kdc",
-            "set_password_expiry": "false",
             "password_min_punctuation": "1",
             "container_dn": "",
             "case_insensitive_username_rules": "false",

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json b/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
index f7f054a..daef35d 100644
--- a/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
+++ b/ambari-server/src/test/python/stacks/2.5/configs/ranger-kms-secured.json
@@ -529,9 +529,7 @@
             "create_ambari_principal": "true",
             "service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
             "executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
-            "password_chat_timeout": "5",
             "kdc_type": "mit-kdc",
-            "set_password_expiry": "false",
             "password_min_punctuation": "1",
             "container_dn": "",
             "case_insensitive_username_rules": "false",

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json b/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
index 38b5906..06b247a 100644
--- a/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
+++ b/ambari-server/src/test/python/stacks/2.6/configs/ranger-admin-secured.json
@@ -456,9 +456,7 @@
             "create_ambari_principal": "true",
             "service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
             "executable_search_paths": "/usr/bin, /usr/kerberos/bin, /usr/sbin, /usr/lib/mit/bin, /usr/lib/mit/sbin",
-            "password_chat_timeout": "5",
             "kdc_type": "mit-kdc",
-            "set_password_expiry": "false",
             "password_min_punctuation": "1",
             "container_dn": "",
             "case_insensitive_username_rules": "false",

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json b/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
index 2a744c7..0b357e9 100644
--- a/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
+++ b/ambari-server/src/test/resources/PreconfigureActionTest_cluster_config.json
@@ -95,7 +95,6 @@
     "manage_auth_to_local": "true",
     "manage_identities": "true",
     "master_kdc": "",
-    "password_chat_timeout": "5",
     "password_length": "20",
     "password_min_digits": "1",
     "password_min_lowercase_letters": "1",
@@ -104,7 +103,6 @@
     "password_min_whitespace": "0",
     "preconfigure_services": "DEFAULT",
     "realm": "EXAMPLE.COM",
-    "service_check_principal_name": "${cluster_name|toLower()}-${short_date}",
-    "set_password_expiry": "false"
+    "service_check_principal_name": "${cluster_name|toLower()}-${short_date}"
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 05b0b31..a97e04e 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -46,7 +46,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
       type: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc')
     },
     'ipa': {
-      configNames: ['group', 'set_password_expiry', 'password_chat_timeout'],
+      configNames: ['ipa_user_group'],
       type: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa')
     }
   },


[44/51] [abbrv] ambari git commit: AMBARI-22415. Blueprint deploys failing with missing smoke user keytab file (echekanskiy)

Posted by nc...@apache.org.
AMBARI-22415. Blueprint deploys failing with missing smoke user keytab file (echekanskiy)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ec02a14c02529ec7fec647e6fed7c8c401f10e6d
Parents: 22b2d55
Author: Eugene Chekanskiy <ec...@gmail.com>
Authored: Fri Nov 10 17:17:34 2017 +0200
Committer: Eugene Chekanskiy <ec...@gmail.com>
Committed: Fri Nov 10 18:29:43 2017 +0200

----------------------------------------------------------------------
 .../kerberos/CreateKeytabFilesServerAction.java             | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ec02a14c/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
index aa65e61..5ec4c10 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
@@ -218,17 +218,18 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
                 }
 
                 boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
+
+                KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
+                String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
+
                 if (password == null) {
                   if (!regenerateKeytabs && (hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME) || kerberosPrincipalHostDAO
-                      .exists(evaluatedPrincipal, hostEntity.getHostId(), keytabFilePath))) {
+                      .exists(evaluatedPrincipal, hostEntity.getHostId(), keytabFilePath)) && cachedKeytabPath == null) {
                     // There is nothing to do for this since it must already exist and we don't want to
                     // regenerate the keytab
                     message = String.format("Skipping keytab file for %s, missing password indicates nothing to do", evaluatedPrincipal);
                     LOG.debug(message);
                   } else {
-                    KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
-                    String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
-
                     if (cachedKeytabPath == null) {
                       message = String.format("Failed to create keytab for %s, missing cached file", evaluatedPrincipal);
                       actionLog.writeStdErr(message);


[21/51] [abbrv] ambari git commit: AMBARI-22376 Log Search UI: add navigation to first and last page. (Istvan Tobias via ababiichuk)

Posted by nc...@apache.org.
AMBARI-22376 Log Search UI: add navigation to first and last page. (Istvan Tobias via ababiichuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 38f6740cdacc0c18e87f1b5b979e1ddb9519dcd8
Parents: cbce5e8
Author: Istvan Tobias <to...@gmail.com>
Authored: Tue Nov 7 17:00:58 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Nov 7 17:33:35 2017 +0200

----------------------------------------------------------------------
 .../pagination-controls.component.html          |  15 ++-
 .../pagination-controls.component.spec.ts       | 101 +++++++++++++++++++
 .../pagination-controls.component.ts            |  71 ++++++++++++-
 3 files changed, 177 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
index c227a2b..370d1c7 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.html
@@ -14,10 +14,15 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 -->
-
-<button class="btn btn-link" [disabled]="currentPage === 0" (click)="updateValue(true)">
-  <span class="pagination-control fa fa-chevron-left"></span>
+<button class="btn btn-link" [disabled]="!hasPreviousPage()" (click)="setFirstPage()">
+  <span class="pagination-control fa fa-angle-double-left"></span>
+</button>
+<button class="btn btn-link" [disabled]="!hasPreviousPage()" (click)="setPreviousPage()">
+  <span class="pagination-control fa fa-angle-left"></span>
+</button>
+<button class="btn btn-link" [disabled]="!hasNextPage()" (click)="setNextPage()">
+  <span class="pagination-control fa fa-angle-right"></span>
 </button>
-<button class="btn btn-link" [disabled]="currentPage === pagesCount - 1" (click)="updateValue()">
-  <span class="pagination-control fa fa-chevron-right"></span>
+<button class="btn btn-link" [disabled]="!hasNextPage()" (click)="setLastPage()">
+  <span class="pagination-control fa fa-angle-double-right"></span>
 </button>

http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
index 489f79c..999609c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.spec.ts
@@ -34,10 +34,111 @@ describe('PaginationControlsComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(PaginationControlsComponent);
     component = fixture.componentInstance;
+    component.registerOnChange(() => {});
+    component.pagesCount = 3;
+    component.totalCount = 30;
     fixture.detectChanges();
   });
 
   it('should create component', () => {
     expect(component).toBeTruthy();
   });
+
+  it('should the hasNextPage function return true when the currentPage is less than the pagesCount', () => {
+    component.pagesCount = 3;
+    component.totalCount = 30;
+    fixture.detectChanges();
+    expect(component.hasNextPage()).toBe(true);
+  });
+  it('should the hasNextPage function return false when the currentPage is equal than the pagesCount', () => {
+    component.currentPage = 3;
+    fixture.detectChanges();
+    expect(component.hasNextPage()).toBe(false);
+  });
+  it('should the hasNextPage function return false when the pagesCount is 0', () => {
+    component.pagesCount = 0;
+    component.totalCount = 0;
+    component.currentPage = 0;
+    fixture.detectChanges();
+    expect(component.hasNextPage()).toBe(false);
+  });
+
+  it('should the hasPreviousPage function return true when the currentPage is greater than 0 and the pagesCount is greater than 0', () => {
+    component.currentPage = 1;
+    fixture.detectChanges();
+    expect(component.hasPreviousPage()).toBe(true);
+  });
+  it('should the hasPreviousPage function return false when the currentPage is equal to 0', () => {
+    component.currentPage = 0;
+    fixture.detectChanges();
+    expect(component.hasPreviousPage()).toBe(false);
+  });
+  it('should the hasPreviousPage function return false when the pagesCount is 0', () => {
+    component.pagesCount = 0;
+    component.totalCount = 0;
+    fixture.detectChanges();
+    expect(component.hasPreviousPage()).toBe(false);
+  });
+
+  it('should the setNextPage function increment the value/currentPage when it is less then the pagesCount', () => {
+    let initialPage = 0;
+    let pagesCount = 3;
+    component.pagesCount = pagesCount;
+    component.totalCount = 30;
+    component.currentPage = initialPage;
+    fixture.detectChanges();
+    component.setNextPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(initialPage + 1);
+  });
+
+  it('should not the setNextPage function increment the value/currentPage when it is on the last page', () => {
+    let pagesCount = 3;
+    component.pagesCount = pagesCount;
+    component.totalCount = 30;
+    component.currentPage = pagesCount - 1;
+    fixture.detectChanges();
+    component.setNextPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(pagesCount - 1);
+  });
+
+  it('should the setPreviousPage function decrement the value/currentPage', () => {
+    let initialPage = 1;
+    component.pagesCount = 3;
+    component.totalCount = 30;
+    component.currentPage = initialPage;
+    fixture.detectChanges();
+    component.setPreviousPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(initialPage - 1);
+  });
+
+  it('should not the setPreviousPage function decrement the value/currentPage when it is equal to 0', () => {
+    component.pagesCount = 3;
+    component.totalCount = 30;
+    component.currentPage = 0;
+    fixture.detectChanges();
+    component.setPreviousPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(0);
+  });
+
+  it('should the setFirstPage set the value/currentPage to 0', () => {
+    component.pagesCount = 3;
+    component.totalCount = 30;
+    component.currentPage = 1;
+    fixture.detectChanges();
+    component.setFirstPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(0);
+  });
+
+
+  it('should the setLastPage set the value/currentPage to the value of pagesCount', () => {
+    component.setLastPage();
+    fixture.detectChanges();
+    expect(component.currentPage).toEqual(component.pagesCount - 1);
+  });
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/38f6740c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
index c71844c..81676a9 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
@@ -51,13 +51,74 @@ export class PaginationControlsComponent implements ControlValueAccessor {
   }
 
   set value(newValue: number) {
-    this.currentPage = newValue;
-    this.currentPageChange.emit(newValue);
-    this.onChange(newValue);
+    if (this.isValidValue(newValue)) { // this is the last validation check
+      this.currentPage = newValue;
+      this.currentPageChange.emit(newValue);
+      this.onChange(newValue);
+    } else {
+      throw new Error(`Invalid value ${newValue}. The currentPage should be between 0 and ${this.pagesCount}.`);
+    }
+  }
+
+  /**
+   * A simple check if the given value is valid for the current pagination instance
+   * @param {number} value The new value to test
+   * @returns {boolean}
+   */
+  private isValidValue(value: number): boolean {
+    return value <= this.pagesCount || value >= 0;
+  }
+
+  /**
+   * The goal is to set the value to the first page... obviously to zero. It is just to have a centralized api for that.
+   */
+  setFirstPage(): void {
+    this.value = 0;
+  }
+
+  /**
+   * The goal is to set the value to the last page which is the pagesCount property anyway.
+   */
+  setLastPage(): void {
+    this.value = this.pagesCount - 1;
+  }
+
+  /**
+   * The goal is to decrease the value (currentPage) property if it is possible (checking with 'hasPreviousPage').
+   * @returns {number} The new value of the currentPage
+   */
+  setPreviousPage(): number {
+    if (this.hasPreviousPage()) {
+      this.value -= 1;
+    }
+    return this.value;
+  }
+
+  /**
+   * The goal is to increase the value (currentPage) property if it is possible (checking with 'hasNextPage').
+   * @returns {number} The new value of the currentPage
+   */
+  setNextPage(): number {
+    if (this.hasNextPage()){
+      this.value += 1;
+    }
+    return this.value;
+  }
+
+  /**
+   * The goal is to have a single source of true to check if we can set a next page or not.
+   * @returns {boolean}
+   */
+  hasNextPage(): boolean {
+    return this.pagesCount > 0 && this.value < this.pagesCount - 1;
   }
 
-  updateValue(isDecrement?: boolean) {
-    isDecrement? this.value-- : this.value++;
+  /**
+   * The goal is to have a single source of true to check if we can set a previous page or not.
+   * @returns {boolean}
+   */
+  hasPreviousPage(): boolean {
+    return this.pagesCount > 0 && this.value > 0;
   }
 
   writeValue() {


[06/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
new file mode 100644
index 0000000..7d1ad61
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/theme/bootstrap-ambari.css
@@ -0,0 +1,1518 @@
+/**
+ * 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.
+ */
+@font-face {
+  font-family: 'Roboto';
+  font-weight: normal;
+  font-style: normal;
+  src: url('fonts/Roboto-Regular-webfont.eot');
+  src: url('fonts/Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'), url('fonts/Roboto-Regular-webfont.woff') format('woff'), url('fonts/Roboto-Regular-webfont.ttf') format('truetype'), url('fonts/Roboto-Regular-webfont.svg#robotoregular') format('svg');
+}
+.font-mixin {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+}
+.btn,
+.btn:focus {
+  outline: none;
+  font-family: 'Roboto', sans-serif;
+  text-transform: uppercase;
+  height: 34px;
+  font-size: 14px;
+  padding: 10px 20px;
+  line-height: 14px;
+}
+.btn .glyphicon,
+.btn:focus .glyphicon {
+  top: -1px;
+  float: left;
+}
+.box-shadow {
+  box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-disabled {
+  opacity: 0.6;
+  box-shadow: none;
+}
+.btn-default-disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #FFF;
+  background-color: #808793;
+  border: none;
+}
+.btn-default,
+.btn-default:focus {
+  color: #666;
+  background-color: #FFF;
+  border: 1px solid #CFD3D7;
+}
+.btn-default:hover,
+.btn-default:focus:hover {
+  color: #FFF;
+  background-color: #808793;
+}
+.btn-default:active,
+.btn-default:focus:active {
+  color: #666;
+  background-color: #FFF;
+  border: 1px solid #CFD3D7;
+  box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-default[disabled],
+.btn-default:focus[disabled],
+.btn-default.disabled,
+.btn-default:focus.disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #FFF;
+  background-color: #808793;
+  border: none;
+}
+.btn-default[disabled]:active,
+.btn-default:focus[disabled]:active,
+.btn-default.disabled:active,
+.btn-default:focus.disabled:active,
+.btn-default[disabled].active,
+.btn-default:focus[disabled].active,
+.btn-default.disabled.active,
+.btn-default:focus.disabled.active,
+.btn-default[disabled]:hover,
+.btn-default:focus[disabled]:hover,
+.btn-default.disabled:hover,
+.btn-default:focus.disabled:hover {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #FFF;
+  background-color: #808793;
+  border: none;
+}
+.btn-primary-disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+}
+.btn-primary,
+.btn-primary:focus {
+  color: #FFF;
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+}
+.btn-primary:hover,
+.btn-primary:focus:hover {
+  color: #FFF;
+  background-color: #429929;
+  border: 1px solid #429929;
+}
+.btn-primary:active,
+.btn-primary:focus:active,
+.btn-primary.active,
+.btn-primary:focus.active {
+  color: #FFF;
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+  box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-primary[disabled],
+.btn-primary:focus[disabled],
+.btn-primary.disabled,
+.btn-primary:focus.disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+}
+.btn-primary[disabled]:active,
+.btn-primary:focus[disabled]:active,
+.btn-primary.disabled:active,
+.btn-primary:focus.disabled:active,
+.btn-primary[disabled].active,
+.btn-primary:focus[disabled].active,
+.btn-primary.disabled.active,
+.btn-primary:focus.disabled.active,
+.btn-primary[disabled]:hover,
+.btn-primary:focus[disabled]:hover,
+.btn-primary.disabled:hover,
+.btn-primary:focus.disabled:hover {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+}
+.btn-secondary-disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #429929;
+  border: 1px solid #3FAE2A;
+}
+.btn-secondary,
+.btn-secondary:focus {
+  color: #429929;
+  background-color: #FFF;
+  border: 1px solid #3FAE2A;
+}
+.btn-secondary:hover,
+.btn-secondary:focus:hover {
+  color: #FFF;
+  background-color: #429929;
+}
+.btn-secondary:active,
+.btn-secondary:focus:active {
+  color: #429929;
+  background-color: #FFF;
+  box-shadow: 0 0 2px 0 #1391c1;
+}
+.btn-secondary[disabled],
+.btn-secondary:focus[disabled],
+.btn-secondary.disabled,
+.btn-secondary:focus.disabled {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #429929;
+  border: 1px solid #3FAE2A;
+}
+.btn-secondary[disabled]:active,
+.btn-secondary:focus[disabled]:active,
+.btn-secondary.disabled:active,
+.btn-secondary:focus.disabled:active,
+.btn-secondary[disabled].active,
+.btn-secondary:focus[disabled].active,
+.btn-secondary.disabled.active,
+.btn-secondary:focus.disabled.active,
+.btn-secondary[disabled]:hover,
+.btn-secondary:focus[disabled]:hover,
+.btn-secondary.disabled:hover,
+.btn-secondary:focus.disabled:hover {
+  opacity: 0.6;
+  box-shadow: none;
+  color: #D1E8D1;
+  background-color: #429929;
+  border: 1px solid #3FAE2A;
+}
+.btn-success {
+  border: none;
+}
+.btn-regular-default-state {
+  background-color: #FFF;
+  color: #666;
+  border: 1px solid #cfd3d7;
+}
+.btn-primary-default-state {
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+  color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle,
+.dropdown.open .btn.dropdown-toggle {
+  box-shadow: inset 0px 0px 3px 0px #1391c1;
+}
+.btn-group.open .btn.dropdown-toggle,
+.dropdown.open .btn.dropdown-toggle,
+.btn-group.open .btn.dropdown-toggle.btn-default,
+.dropdown.open .btn.dropdown-toggle.btn-default {
+  background-color: #FFF;
+  color: #666;
+  border: 1px solid #cfd3d7;
+}
+.btn-group.open .btn.dropdown-toggle:hover,
+.dropdown.open .btn.dropdown-toggle:hover,
+.btn-group.open .btn.dropdown-toggle.btn-default:hover,
+.dropdown.open .btn.dropdown-toggle.btn-default:hover {
+  background-color: #FFF;
+  color: #666;
+  border: 1px solid #cfd3d7;
+}
+.btn-group.open .btn.dropdown-toggle + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle + .dropdown-menu > li > a:hover,
+.btn-group.open .btn.dropdown-toggle.btn-default + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle.btn-default + .dropdown-menu > li > a:hover {
+  background-color: #808793;
+  color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary,
+.dropdown.open .btn.dropdown-toggle.btn-primary {
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+  color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary:hover,
+.dropdown.open .btn.dropdown-toggle.btn-primary:hover {
+  background-color: #3FAE2A;
+  border: 1px solid #3FAE2A;
+  color: #FFF;
+}
+.btn-group.open .btn.dropdown-toggle.btn-primary + .dropdown-menu > li > a:hover,
+.dropdown.open .btn.dropdown-toggle.btn-primary + .dropdown-menu > li > a:hover {
+  background-color: #429929;
+  color: #FFF;
+}
+.btn-group.open .dropdown-menu,
+.dropdown.open .dropdown-menu {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  border-radius: 2px;
+  font-size: 14px;
+  min-width: 200px;
+  background: #FFF;
+  color: #666;
+  border: 1px solid #cfd3d7;
+}
+.btn-group.open .dropdown-menu > li,
+.dropdown.open .dropdown-menu > li {
+  margin-bottom: 1px;
+}
+.btn-group.open .dropdown-menu > li > a,
+.dropdown.open .dropdown-menu > li > a {
+  height: 24px;
+}
+.btn-group .btn.dropdown-toggle:first-child,
+.dropdown .btn.dropdown-toggle:first-child {
+  min-width: 80px;
+}
+.btn-group .btn.dropdown-toggle.disabled,
+.dropdown .btn.dropdown-toggle.disabled,
+.btn-group .btn.dropdown-toggle[disabled],
+.dropdown .btn.dropdown-toggle[disabled] {
+  opacity: 0.6;
+}
+input.form-control {
+  font-size: 14px;
+  border-radius: 2px;
+  color: #666;
+  border: 1px solid #CFD3D7;
+  height: 34px;
+  padding: 10px;
+}
+input.form-control:focus {
+  border-color: #1291c1;
+  box-shadow: none;
+}
+.help-block {
+  color: #999999;
+  font-size: 14px;
+}
+.help-block.validation-block {
+  color: #999999;
+  margin-top: 10px;
+}
+.help-block.validation-block::before {
+  position: relative;
+  top: 2px;
+  margin-right: 5px;
+  font-family: 'Glyphicons Halflings';
+}
+.has-success input.form-control {
+  color: #666;
+  border: 1px solid #1EB475;
+}
+.has-success input.form-control:focus {
+  border-color: #1EB475;
+  box-shadow: none;
+}
+.has-success .help-block.validation-block::before {
+  content: '\e084';
+  color: #1EB475;
+}
+.has-error input.form-control {
+  color: #666;
+  border: 1px solid #EF6162;
+}
+.has-error input.form-control:focus {
+  border-color: #EF6162;
+  box-shadow: none;
+}
+.has-error .help-block.validation-block::before {
+  content: '\e083';
+  color: #EF6162;
+}
+.has-warning input.form-control {
+  color: #666;
+  border: 1px solid #E98A40;
+}
+.has-warning input.form-control:focus {
+  border-color: #E98A40;
+  box-shadow: none;
+}
+.has-warning .help-block.validation-block::before {
+  content: '\e101';
+  color: #E98A40;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+  color: #999999;
+  border-color: #cccccc;
+  background-color: #dddddd;
+}
+h2.table-title {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  margin-top: 10px;
+  font-size: 20px;
+}
+.table {
+  color: #666;
+  font-size: 13px;
+}
+.table thead,
+.table tfoot {
+  color: #999;
+}
+.table input[type="checkbox"] + label {
+  position: relative;
+  line-height: 1.3em;
+  font-size: initial;
+  top: 4px;
+  margin-bottom: 0;
+}
+.table thead > tr > th {
+  border-bottom-color: #EEE;
+}
+.table tfoot > tr:first-of-type > td {
+  border-top-width: 2px;
+  border-top-color: #EEE;
+}
+.table > tbody > tr > td {
+  border-top-color: #EEE;
+}
+.table > tbody > tr.active {
+  background-color: #EEE;
+}
+.table > tbody > tr.active > td {
+  background-color: #EEE;
+}
+.table.table-hover .action {
+  visibility: hidden;
+  padding: 0;
+  line-height: 1;
+}
+.table.table-hover .action:hover {
+  text-decoration: none;
+}
+.table.table-hover > tbody > tr {
+  border-width: 0 1px 1px;
+  border-style: solid;
+  border-color: #EEE transparent;
+}
+.table.table-hover > tbody > tr > td {
+  border-width: 0;
+}
+.table.table-hover > tbody > tr:hover {
+  border-color: #A7DFF2;
+  background-color: #E7F6FC;
+}
+.table.table-hover > tbody > tr:hover > td {
+  border-top: 1px solid #A7DFF2;
+  background-color: #E7F6FC;
+}
+.table.table-hover > tbody > tr:hover > td .action {
+  visibility: visible;
+}
+.table.table-hover > tbody > tr:first-of-type > td {
+  border-top: 1px solid transparent;
+}
+.table.table-hover > tbody > tr:first-of-type:hover > td {
+  border-color: #A7DFF2;
+}
+.pagination-block .pagination-block-item {
+  float: left;
+  padding: 0 5px;
+}
+.pagination-block .pagination-block-item a,
+.pagination-block .pagination-block-item a:visited,
+.pagination-block .pagination-block-item a:focus {
+  text-decoration: none;
+}
+.pagination-block .pagination-block-item select {
+  border: none;
+  background-color: transparent;
+  color: #1491C1;
+}
+.nav.nav-tabs {
+  border: none;
+  margin-bottom: 20px;
+}
+.nav.nav-tabs li a {
+  border-width: 0;
+  border-radius: 0;
+  border-bottom: 3px solid transparent;
+  color: #6B6C6C;
+  text-transform: uppercase;
+}
+.nav.nav-tabs li a:hover,
+.nav.nav-tabs li a:active,
+.nav.nav-tabs li a:focus {
+  color: #333;
+  border-top-width: 0;
+  border-left-width: 0;
+  border-right-width: 0;
+  background: none;
+}
+.nav.nav-tabs li a .badge.badge-important {
+  display: inline;
+  vertical-align: baseline;
+}
+.nav.nav-tabs li.active a {
+  color: #333;
+  border-bottom: 3px solid #3FAE2A;
+  padding-bottom: 2px;
+}
+.nav-tabs-left li,
+.nav-tabs-right li {
+  float: none;
+  margin-bottom: 3px;
+}
+.nav-tabs-left li a,
+.nav-tabs-right li a {
+  margin-right: 0;
+}
+.nav-tabs-left li {
+  margin-right: -1px;
+}
+.nav-tabs-left li a {
+  border: 3px solid transparent !important;
+}
+.nav-tabs-left li.active a,
+.nav-tabs-left li.active a:hover,
+.nav-tabs-left li.active a:active,
+.nav-tabs-left li.active a:focus {
+  border-right: 3px solid #3FAE2A !important;
+}
+.nav-tabs-right li {
+  margin-left: -1px;
+}
+.nav-tabs-right li a {
+  border: 3px solid transparent !important;
+}
+.nav-tabs-right li.active a,
+.nav-tabs-right li.active a:hover,
+.nav-tabs-right li.active a:active,
+.nav-tabs-right li.active a:focus {
+  border-left: 3px solid #3FAE2A !important;
+}
+.wizard {
+  border: 2px solid #ebecf1;
+}
+.wizard .wizard-header h3 {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  font-size: 20px;
+  color: #333;
+  margin: 15px 20px;
+}
+.wizard .wizard-body {
+  overflow: hidden;
+  margin: 0;
+}
+.wizard .wizard-body .wizard-content {
+  background: #ebecf1;
+  padding-top: 25px;
+  float: left;
+  margin-bottom: -99999px;
+  padding-bottom: 99999px;
+}
+.wizard .wizard-body .wizard-content .step-title {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-weight: bold;
+  font-size: 18px;
+  color: #666;
+}
+.wizard .wizard-body .wizard-content .step-description {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+  line-height: 1.4;
+  color: #999;
+}
+.wizard .wizard-body .wizard-content .panel.panel-default {
+  border: none;
+  box-shadow: none;
+  margin-top: 20px;
+}
+.wizard .wizard-body .wizard-content .panel.panel-default .panel-body {
+  padding: 30px 20px;
+}
+.wizard .wizard-body .wizard-nav {
+  min-height: 550px;
+  padding-top: 25px;
+  background-color: #323544;
+  float: left;
+  margin-bottom: -99999px;
+  padding-bottom: 99999px;
+}
+.wizard .wizard-body .wizard-nav .nav li {
+  padding: 0px 15px;
+}
+.wizard .wizard-body .wizard-nav .nav li a {
+  height: 48px;
+  padding: 0px 5px;
+  display: table-cell;
+  vertical-align: middle;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-marker {
+  position: absolute;
+  top: 9px;
+  line-height: 16px;
+  text-align: center;
+  width: 20px;
+  height: 20px;
+  border: 2px solid #1EB475;
+  border-radius: 50%;
+  font-size: 12px;
+  font-style: inherit;
+  color: #1EB475;
+  background-color: #323544;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-name {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+  color: #999;
+  margin-left: 30px;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-index {
+  line-height: 18px;
+}
+.wizard .wizard-body .wizard-nav .nav li .step-description {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 12px;
+  color: #999;
+  margin-left: 30px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker {
+  background-color: #1EB475;
+  color: white;
+  font-size: 10px;
+  padding-left: 2px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker .step-index {
+  display: none;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed .step-marker:after {
+  font-family: "Glyphicons Halflings";
+  content: "\e013";
+  position: relative;
+  top: 1px;
+  left: -1px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed:after {
+  width: 2px;
+  height: 100%;
+  position: absolute;
+  background-color: #1EB475;
+  content: "";
+  top: 25px;
+  left: 29px;
+}
+.wizard .wizard-body .wizard-nav .nav li.completed:last-child:after {
+  content: none;
+}
+.wizard .wizard-body .wizard-nav .nav li.active .step-name {
+  font-weight: bold;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-marker {
+  color: #666;
+  border-color: #666;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-name,
+.wizard .wizard-body .wizard-nav .nav li.disabled .step-description {
+  color: #666;
+}
+.wizard .wizard-body .wizard-nav .nav li.disabled.completed .step-marker {
+  background-color: #1EB475;
+  border: 2px solid #1EB475;
+  color: white;
+}
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a,
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a:focus,
+.wizard .wizard-body .wizard-nav .nav-pills > li.active > a:hover,
+.wizard .wizard-body .wizard-nav .nav > li > a:focus,
+.wizard .wizard-body .wizard-nav .nav > li > a:hover {
+  background-color: inherit;
+}
+.wizard .wizard-body .wizard-footer {
+  background: white;
+  padding: 15px 20px;
+}
+.wizard .wizard-body .wizard-footer button {
+  margin: 0 10px;
+}
+.checkbox-disabled-style {
+  background-color: #b2b8c1;
+  border-color: #b2b8c1;
+}
+input[type="checkbox"]:not(:checked),
+input[type="radio"]:not(:checked),
+input[type="checkbox"]:checked,
+input[type="radio"]:checked {
+  display: none;
+}
+input[type="checkbox"]:not(:checked) + label,
+input[type="radio"]:not(:checked) + label,
+input[type="checkbox"]:checked + label,
+input[type="radio"]:checked + label {
+  position: relative;
+  padding-left: 20px;
+}
+input[type="checkbox"]:not(:checked) + label:hover:before,
+input[type="radio"]:not(:checked) + label:hover:before,
+input[type="checkbox"]:checked + label:hover:before,
+input[type="radio"]:checked + label:hover:before {
+  border-color: #1491C1;
+  background-color: #1491C1;
+}
+input[type="checkbox"]:checked + label:before,
+input[type="radio"]:checked + label:before {
+  background-color: #1491C1;
+  border-color: #1491C1;
+}
+input[type="checkbox"][disabled] + label:before,
+input[type="radio"][disabled] + label:before,
+input[type="checkbox"].disabled + label:before,
+input[type="radio"].disabled + label:before,
+input[type="checkbox"][disabled] + label:hover:before,
+input[type="radio"][disabled] + label:hover:before,
+input[type="checkbox"].disabled + label:hover:before,
+input[type="radio"].disabled + label:hover:before {
+  background-color: #b2b8c1;
+  border-color: #b2b8c1;
+}
+input[type="checkbox"] + label:before {
+  content: '';
+  position: absolute;
+  left: 0;
+  top: 4px;
+  width: 10px;
+  height: 10px;
+  box-sizing: border-box;
+  border-radius: 2px;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #ddd;
+}
+input[type="checkbox"]:checked + label:after {
+  content: '\2714';
+  color: #FFF;
+  position: absolute;
+  top: 0;
+  left: 2px;
+  font-size: 9px;
+}
+input[type="radio"] + label:before,
+input.radio + label:before {
+  content: '';
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 12px;
+  height: 12px;
+  box-sizing: border-box;
+  border-radius: 12px;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #ddd;
+}
+input[type="radio"]:checked + label:after,
+input.radio:checked + label:after {
+  content: '';
+  background-color: #FFF;
+  position: absolute;
+  top: 3px;
+  left: 3px;
+  width: 6px;
+  height: 6px;
+  border-radius: 6px;
+}
+.navigation-bar-container {
+  height: auto;
+  width: 230px;
+  background-color: #323544;
+  padding: 0;
+  -ms-overflow-style: none;
+  transition: width 0.5s ease-out;
+  -webkit-font-smoothing: antialiased;
+}
+.navigation-bar-container ul.nav.side-nav-header {
+  width: 230px;
+  transition: width 0.5s ease-out;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header {
+  background: #313d54;
+  padding: 15px 5px 15px 25px;
+  height: 55px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo {
+  padding: 0;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo > img {
+  height: 25px;
+  float: left;
+  margin-left: -3px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group {
+  cursor: pointer;
+  margin-top: 3px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group:hover span.ambari-header {
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group span.ambari-header {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 20px;
+  width: 55px;
+  display: inline;
+  color: #b8bec4;
+  padding: 0 8px 0 10px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group span.toggle-icon {
+  margin-bottom: 5px;
+  font-size: 13px;
+  display: inline-block;
+  vertical-align: middle;
+  color: #43AD49;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group.open .dropdown-toggle {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu {
+  top: 30px;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu li > a {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+  color: #666;
+  line-height: 1.42;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.navigation-bar-container ul.nav.side-nav-header li.navigation-header ul.dropdown-menu li > a:hover {
+  background: #f5f5f5;
+}
+.navigation-bar-container ul.nav.side-nav-menu,
+.navigation-bar-container ul.nav.side-nav-footer {
+  background-color: #323544;
+  width: 230px;
+  transition: width 0.5s ease-out;
+}
+.navigation-bar-container ul.nav.side-nav-menu li,
+.navigation-bar-container ul.nav.side-nav-footer li {
+  padding: 0;
+  margin: 0;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a {
+  display: table-cell;
+  vertical-align: middle;
+  width: 230px;
+  border-radius: 0;
+  -moz-border-radius: 0;
+  -webkit-border-radius: 0;
+  white-space: nowrap;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .navigation-menu-item {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+  color: #b8bec4;
+  padding-left: 8px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .navigation-icon {
+  line-height: 18px;
+  font-size: 16px;
+  color: #b8bec4;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a .toggle-icon {
+  line-height: 14px;
+  font-size: 14px;
+  color: #b8bec4;
+  padding: 3px 5px 3px 10px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.mainmenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.mainmenu-li > a {
+  padding: 10px 5px 10px 20px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer > a,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer > a {
+  padding: 14px 5px 14px 20px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container ul.nav.side-nav-footer li.submenu-li > a {
+  padding: 10px 5px 10px 25px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer {
+  background: #313d54;
+  height: 48px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer a .navigation-icon {
+  color: #3fae2a;
+  font-size: 19px;
+  position: relative;
+  padding: 0 15px;
+  left: calc(30%);
+}
+.navigation-bar-container ul.nav.side-nav-menu li.navigation-footer a .navigation-icon:hover,
+.navigation-bar-container ul.nav.side-nav-footer li.navigation-footer a .navigation-icon:hover {
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li {
+  background-color: #323544;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li a,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li a {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+  color: #999;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li a .submenu-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li a .submenu-icon {
+  line-height: 14px;
+  font-size: 14px;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover {
+  background: #404351;
+  cursor: pointer;
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li > ul > li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > ul > li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li > a:hover .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li > a:hover .submenu-item {
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu),
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu),
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed {
+  background: #404351;
+  cursor: pointer;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a {
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .navigation-menu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .submenu-item,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .navigation-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a .toggle-icon,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a .toggle-icon {
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu li.active:not(.has-sub-menu) > a:after,
+.navigation-bar-container ul.nav.side-nav-footer li.active:not(.has-sub-menu) > a:after,
+.navigation-bar-container ul.nav.side-nav-menu li.active.collapsed > a:after,
+.navigation-bar-container ul.nav.side-nav-footer li.active.collapsed > a:after {
+  left: 0;
+  top: 50%;
+  border: solid transparent;
+  border-width: 10px 7px;
+  content: " ";
+  height: 0;
+  width: 0;
+  position: absolute;
+  pointer-events: none;
+  border-color: transparent;
+  border-left-color: #3fae2a;
+  margin-top: -12px;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions {
+  display: block;
+  position: absolute;
+  top: 14px;
+  right: 33px;
+  line-height: 25px;
+  width: 20px;
+  text-align: center;
+  font-size: 14px;
+  cursor: pointer;
+  vertical-align: middle;
+  color: #fff;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a {
+  color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a i,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a i {
+  color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a:hover,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a:hover {
+  background: #f5f5f5;
+}
+.navigation-bar-container ul.nav.side-nav-menu .menu-item-name,
+.navigation-bar-container ul.nav.side-nav-footer .menu-item-name {
+  display: inline-block;
+  vertical-align: bottom;
+  max-width: 100px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  -ms-text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.navigation-bar-container .nav-pills > li.active > a,
+.navigation-bar-container .nav-pills > li.active > a:focus,
+.navigation-bar-container .nav-pills > li.active > a:hover,
+.navigation-bar-container .nav > li > a:focus,
+.navigation-bar-container .nav > li > a:hover {
+  background-color: inherit;
+}
+.navigation-bar-container.collapsed {
+  width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header {
+  width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header {
+  padding: 15px 0 15px 15px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.ambari-header,
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header .dropdown-menu {
+  display: none;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer {
+  width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a {
+  padding: 15px 0 15px 15px;
+  width: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .toggle-icon {
+  display: none;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li a .navigation-icon {
+  font-size: 19px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.navigation-footer a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.navigation-footer a .navigation-icon {
+  padding: 0 5px;
+  left: 0;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li ul.sub-menu,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li ul.sub-menu {
+  display: none;
+  width: 230px;
+  position: absolute;
+  z-index: 100;
+  top: 0;
+  left: 50px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.submenu-li > a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.submenu-li > a {
+  padding: 10px 5px 10px 25px;
+  width: 230px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active {
+  background: #404351;
+  cursor: pointer;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a {
+  color: #fff;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .navigation-menu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .submenu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .submenu-item,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .navigation-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a .toggle-icon,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a .toggle-icon {
+  color: #fff;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu li.active > a:after,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer li.active > a:after {
+  left: 0;
+  top: 50%;
+  border: solid transparent;
+  border-width: 12px 6px;
+  content: " ";
+  height: 0;
+  width: 0;
+  position: absolute;
+  pointer-events: none;
+  border-color: transparent;
+  border-left-color: #3fae2a;
+  margin-top: -12px;
+}
+.navigation-bar-container.collapsed ul.nav.side-nav-menu .more-actions,
+.navigation-bar-container.collapsed ul.nav.side-nav-footer .more-actions {
+  display: none;
+}
+.navigation-bar-fit-height {
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 2079;
+}
+.navigation-bar-fit-height .side-nav-header {
+  position: absolute;
+  top: 0;
+}
+.navigation-bar-fit-height .side-nav-menu {
+  position: absolute;
+  top: 55px;
+  bottom: 50px;
+}
+.navigation-bar-fit-height .side-nav-footer {
+  position: absolute;
+  bottom: 0;
+}
+.navigation-bar-fit-height .more-actions .dropdown-menu {
+  position: fixed;
+  top: auto;
+  left: auto;
+}
+.navigation-bar-fit-height .navigation-bar-container {
+  height: 100%;
+}
+.navigation-bar-fit-height .navigation-bar-container .side-nav-menu {
+  overflow-y: auto;
+}
+.notifications-group {
+  position: relative;
+  top: 1px;
+}
+.notifications-dropdown,
+#notifications-dropdown.dropdown-menu {
+  min-width: 400px;
+  max-width: 400px;
+  min-height: 150px;
+  padding: 0px;
+  z-index: 1000;
+  right: -50px;
+  left: auto;
+  top: 260%;
+  border: none;
+  -webkit-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+  -moz-box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+  box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.29);
+}
+.notifications-dropdown .popup-arrow-up,
+#notifications-dropdown.dropdown-menu .popup-arrow-up {
+  position: absolute;
+  right: 37px;
+  top: -40px;
+  width: 40px;
+  height: 40px;
+  overflow: hidden;
+}
+.notifications-dropdown .popup-arrow-up:after,
+#notifications-dropdown.dropdown-menu .popup-arrow-up:after {
+  content: "";
+  position: absolute;
+  width: 20px;
+  height: 20px;
+  background: #fff;
+  transform: rotate(45deg);
+  top: 30px;
+  left: 10px;
+  box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
+}
+.notifications-dropdown .notifications-header,
+#notifications-dropdown.dropdown-menu .notifications-header {
+  border-bottom: 1px solid #eee;
+  padding: 15px 20px;
+}
+.notifications-dropdown .notifications-header .notifications-title,
+#notifications-dropdown.dropdown-menu .notifications-header .notifications-title {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 16px;
+}
+.notifications-dropdown .notifications-body,
+#notifications-dropdown.dropdown-menu .notifications-body {
+  padding: 0px 15px;
+  overflow: auto;
+  max-height: 500px;
+}
+.notifications-dropdown .notifications-body .no-alert-text,
+#notifications-dropdown.dropdown-menu .notifications-body .no-alert-text {
+  padding: 15px 5px;
+}
+.notifications-dropdown .notifications-body .table-controls,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls {
+  padding: 10px 0px;
+  margin: 0px;
+  border-bottom: 1px solid #eee;
+}
+.notifications-dropdown .notifications-body .table-controls .state-filter,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter {
+  padding: 0px;
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 12px;
+  color: #666;
+  position: relative;
+}
+.notifications-dropdown .notifications-body .table-controls .state-filter .form-control.filter-select,
+#notifications-dropdown.dropdown-menu .notifications-body .table-controls .state-filter .form-control.filter-select {
+  font-size: 12px;
+  color: #666;
+  height: 25px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table {
+  margin-top: 0px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr {
+  cursor: pointer;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover {
+  cursor: default;
+  border-color: transparent;
+  border-bottom-color: #eee;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover > td,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody tr.no-alert-tr:hover > td {
+  border-color: transparent;
+  background-color: white;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status {
+  width: 9%;
+  padding: 15px 3px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status .alert-state-CRITICAL,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-CRITICAL {
+  color: #EF6162;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.status .alert-state-WARNING,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.status .alert-state-WARNING {
+  color: #E98A40;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content {
+  width: 90%;
+  padding: 15px 3px 10px 3px;
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  line-height: 1.3;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .name,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .name {
+  font-weight: bold;
+  font-size: 14px;
+  color: #333;
+  margin-bottom: 5px;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .description,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .description {
+  font-size: 12px;
+  color: #666;
+  margin-bottom: 4px;
+  display: block;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  max-height: 47px;
+  /* For firefox */
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  /* Break long urls*/
+  overflow-wrap: break-word;
+  word-wrap: break-word;
+  -ms-word-break: break-all;
+  word-break: break-all;
+  word-break: break-word;
+  /* Adds a hyphen where the word breaks*/
+  -ms-hyphens: auto;
+  -moz-hyphens: auto;
+  -webkit-hyphens: auto;
+  hyphens: auto;
+}
+.notifications-dropdown .notifications-body .table.alerts-table tbody td.content .timestamp,
+#notifications-dropdown.dropdown-menu .notifications-body .table.alerts-table tbody td.content .timestamp {
+  text-align: right;
+  font-size: 11px;
+  color: #999;
+}
+.notifications-dropdown .notifications-footer,
+#notifications-dropdown.dropdown-menu .notifications-footer {
+  border-top: 1px solid #eee;
+  padding: 15px;
+}
+.modal-backdrop {
+  background-color: #808080;
+}
+.modal .modal-content {
+  border-radius: 2px;
+}
+.modal .modal-content .modal-header,
+.modal .modal-content .modal-body,
+.modal .modal-content .modal-footer {
+  padding-left: 20px;
+  padding-right: 20px;
+}
+.modal .modal-content .modal-header {
+  border-bottom: none;
+  padding-top: 20px;
+  color: #666;
+  font-size: 20px;
+}
+.modal .modal-content .modal-header h4 {
+  margin: 0;
+  color: inherit;
+  font-size: inherit;
+}
+.modal .modal-content .modal-body {
+  color: #666;
+  font-size: 12px;
+}
+.modal .modal-content .modal-footer {
+  border-top: none;
+  padding-bottom: 20px;
+}
+.modal .modal-content .modal-footer .btn ~ .btn {
+  margin-left: 10px;
+}
+.accordion .panel-group,
+.wizard .wizard-body .wizard-content .accordion .panel-group {
+  margin-bottom: 0;
+}
+.accordion .panel-group .panel,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel {
+  border-radius: 0;
+  border: none;
+  margin-top: 0;
+  padding: 0 10px;
+}
+.accordion .panel-group .panel .panel-heading,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading {
+  height: 50px;
+  padding: 15px 10px;
+  border: 1px solid;
+  border-color: #ddd transparent;
+  border-top: none;
+  background: #fff;
+}
+.accordion .panel-group .panel .panel-heading .panel-title,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+}
+.accordion .panel-group .panel .panel-heading .panel-title > a,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title > a {
+  font-size: 18px;
+  color: #333;
+}
+.accordion .panel-group .panel .panel-heading .panel-title > i,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading .panel-title > i {
+  font-size: 20px;
+  color: #1491c1;
+}
+.accordion .panel-group .panel .panel-heading:hover,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-heading:hover {
+  background: #f3faff;
+  cursor: pointer;
+}
+.accordion .panel-group .panel .panel-body,
+.wizard .wizard-body .wizard-content .accordion .panel-group .panel .panel-body {
+  padding: 15px 10px 20px 20px;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+  font-family: 'Roboto', sans-serif;
+}
+h1,
+.h1 {
+  font-size: 24px;
+}
+h2,
+.h2 {
+  font-size: 18px;
+}
+body,
+.body {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  font-style: normal;
+  line-height: 1;
+  color: #333;
+  font-size: 14px;
+}
+.description {
+  font-family: 'Roboto', sans-serif;
+  font-size: 12px;
+  color: #000;
+}
+a,
+a:visited,
+a:focus {
+  color: #1491C1;
+  text-decoration: none;
+}
+a:hover,
+a:visited:hover,
+a:focus:hover {
+  text-decoration: underline;
+}
+a:active,
+a:visited:active,
+a:focus:active {
+  text-decoration: none;
+}
+a[disabled],
+a:visited[disabled],
+a:focus[disabled],
+a.disabled,
+a:visited.disabled,
+a:focus.disabled {
+  cursor: not-allowed;
+  color: #666;
+  text-decoration: none;
+}
+a[disabled]:hover,
+a:visited[disabled]:hover,
+a:focus[disabled]:hover,
+a.disabled:hover,
+a:visited.disabled:hover,
+a:focus.disabled:hover {
+  text-decoration: none;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
new file mode 100644
index 0000000..f93b2e6
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/top-nav.css
@@ -0,0 +1,197 @@
+/**
+ * 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.
+ */
+
+
+#top-nav .navbar.navbar-static-top {
+  background: #fff;
+  border-top: 1px solid #e3e3e3;
+  border-bottom: 1px solid #e3e3e3;
+  margin-bottom: 10px;
+  min-height: 55px;
+}
+
+#top-nav .breadcrumb li {
+  padding: 15px 0;
+}
+
+#top-nav .navbar-text {
+  padding: 2px 0;
+}
+
+#top-nav .navbar-right {
+  font-size: 16px;
+}
+
+
+/** Override bootstrap styles **/
+@media (min-width: 0) {
+  .navbar-nav {
+    float: left;
+    margin: 0;
+  }
+  .navbar-nav > li {
+    float: left;
+  }
+  .navbar-nav > li > a {
+    padding-top: 15px;
+    padding-bottom: 15px;
+  }
+  .navbar-left {
+    float: left !important;
+  }
+  .navbar-right {
+    float: right !important;
+    margin-right: -15px;
+  }
+  .navbar-right ~ .navbar-right {
+    margin-right: 0;
+  }
+  .navbar-right .dropdown-menu {
+    right: 0;
+    left: auto;
+  }
+  .navbar-right .dropdown-menu-left {
+    right: auto;
+    left: 0;
+  }
+  .navbar {
+    border-radius: 4px;
+  }
+  .navbar-header {
+    float: left;
+  }
+  .container > .navbar-header,
+  .container-fluid > .navbar-header,
+  .container > .navbar-collapse,
+  .container-fluid > .navbar-collapse {
+    margin-right: 0;
+    margin-left: 0;
+  }
+  .navbar-static-top {
+    border-radius: 0;
+  }
+  .navbar-fixed-top,
+  .navbar-fixed-bottom {
+    border-radius: 0;
+  }
+  .navbar > .container .navbar-brand,
+  .navbar > .container-fluid .navbar-brand {
+    margin-left: -15px;
+  }
+  .navbar-toggle {
+    display: none;
+  }
+  .navbar-text {
+    float: left;
+    margin-right: 15px;
+    margin-left: 15px;
+  }
+  .navbar-header {
+    float: left;
+  }
+  .navbar-collapse {
+    width: auto;
+    border-top: 0;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+  .navbar-collapse.collapse {
+    display: block !important;
+    height: auto !important;
+    padding-bottom: 0;
+    overflow: visible !important;
+  }
+  .navbar-collapse.in {
+    overflow-y: visible;
+  }
+  .navbar-fixed-top .navbar-collapse,
+  .navbar-static-top .navbar-collapse,
+  .navbar-fixed-bottom .navbar-collapse {
+    padding-right: 0;
+    padding-left: 0;
+  }
+  .navbar {
+    border-radius: 4px;
+  }
+  .navbar-form .form-group {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .navbar-form .form-control-static {
+    display: inline-block;
+  }
+  .navbar-form .input-group {
+    display: inline-table;
+    vertical-align: middle;
+  }
+  .navbar-form .input-group .input-group-addon,
+  .navbar-form .input-group .input-group-btn,
+  .navbar-form .input-group .form-control {
+    width: auto;
+  }
+  .navbar-form .input-group > .form-control {
+    width: 100%;
+  }
+  .navbar-form .control-label {
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio,
+  .navbar-form .checkbox {
+    display: inline-block;
+    margin-top: 0;
+    margin-bottom: 0;
+    vertical-align: middle;
+  }
+  .navbar-form .radio label,
+  .navbar-form .checkbox label {
+    padding-left: 0;
+  }
+  .navbar-form .radio input[type="radio"],
+  .navbar-form .checkbox input[type="checkbox"] {
+    position: relative;
+    margin-left: 0;
+  }
+  .navbar-form .has-feedback .form-control-feedback {
+    top: 0;
+  }
+  .navbar-form {
+    width: auto;
+    padding-top: 0;
+    padding-bottom: 0;
+    margin-right: 0;
+    margin-left: 0;
+    border: 0;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+  }
+}
+
+@media (max-width: 767px) {
+  .navbar-nav .open .dropdown-menu {
+    position: absolute;
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
index 8457065..5271ceb 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
@@ -21,7 +21,9 @@
       <li class="active">{{'common.groups' | translate}}</li>
     </ol>
     <div class="pull-right top-margin-4">
-      <link-to route="groups.create" class="btn btn-primary creategroup-btn"><span class="glyphicon glyphicon-plus"></span> {{'groups.createLocal' | translate}}</link-to>
+      <link-to route="groups.create" class="btn btn-default creategroup-btn">
+        {{'groups.createLocal' | translate}}
+      </link-to>
     </div>
   </div>
   <hr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
deleted file mode 100644
index a7fc18a..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<div class="left-navbar" xmlns="http://www.w3.org/1999/html">
-  <div class="panel panel-default">
-    <div class="panel-heading"><span class="glyphicon glyphicon-cloud"></span> {{'common.clusters' | translate}}</div>
-    <div class="panel-body">
-      <div class="cluster-section" ng-show="cluster">
-        <div id="cluster-name"  ng-switch on="editCluster.editingName">
-          <h5 ng-switch-when="false"><div title={{cluster.Clusters.cluster_name}} class="clusterDisplayName">{{clusterDisplayName()}}</div>
-            <i ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
-               ng-click="toggleEditName()"
-               class="glyphicon glyphicon-edit pull-right edit-cluster-name renameCluster" tooltip="{{'common.renameCluster' | translate}}">
-            </i>
-          </h5>
-
-          <form ng-keyup="toggleEditName($event)"
-                tabindex="1"
-                name="editClusterNameForm"
-                class="editClusterNameForm"
-                ng-switch-when="true"
-                ng-submit="editCluster.name !== cluster.Clusters.cluster_name && editClusterNameForm.newClusterName.$valid && confirmClusterNameChange()">
-            <div class="form-group"
-                 ng-class="{'has-error': editClusterNameForm.newClusterName.$invalid && !editClusterNameForm.newClusterName.$pristine }">
-              <input
-                  autofocus
-                  type="text"
-                  name="newClusterName"
-                  ng-required="true"
-                  ng-pattern="/^\w*$/"
-                  ng-trim="false"
-                  ng-model="editCluster.name"
-                  class="form-control input-sm"
-                  ng-maxlength="80"
-                  tooltip="{{'common.renameClusterTip' | translate}}"
-                  tooltip-trigger="focus">
-              <button ng-click="toggleEditName()"
-                      class="btn btn-xs">
-                <i class="glyphicon glyphicon-remove"></i>
-              </button>
-              <button
-                  type="submit"
-                  class="btn btn-primary btn-xs"
-                  ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}">
-                <i class="glyphicon glyphicon-ok"></i>
-              </button>
-            </div>
-          </form>
-
-        </div>
-
-        <ul class="nav nav-pills nav-stacked" ng-show="cluster.Clusters.provisioning_state == 'INSTALLED' ">
-          <li ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
-            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="permissions">{{'common.roles' | translate}}</a>
-          </li>
-          <li><a href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">{{'common.goToDashboard' | translate}}</a></li>
-          <li ng-class="{active: isActive('clusters.exportBlueprint')}">
-            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/exportBlueprint" class="exportblueprint">{{'common.exportBlueprint' | translate}}</a>
-          </li>
-        </ul>
-        <span class="cluster-installation-progress-label" ng-show="cluster.Clusters.provisioning_state == 'INIT'"><a href="{{fromSiteRoot('/#/')}}">{{'common.clusterCreationInProgress' | translate}}</a></span>
-      </div>
-
-
-      <div ng-hide="cluster">
-        <ul class="nav nav-pills nav-stacked">
-          <li><p class="noclusters">{{'common.noClusters' | translate}}</p></li>
-        </ul>
-      </div>
-      <ul class="nav nav-pills nav-stacked" >
-        <li ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
-          <a href="#/stackVersions">{{'common.versions' | translate}}</a>
-        </li>
-        <li ng-class="{active: isActive('remoteClusters.list')}">
-          <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
-        </li>
-      </ul>
-    </div>
-  </div>
-
-  <div class="panel panel-default">
-    <div class="panel-heading"><span class="glyphicon glyphicon-th"></span> {{'common.views' | translate}}</div>
-    <div class="panel-body">
-      <ul class="nav nav-pills nav-stacked">
-        <li ng-class="{active: isActive('views.list')}"><link-to route="views.list" class="viewslist-link">{{'common.views' | translate}}</link-to></li>
-        <li ng-class="{active: isActive('views.listViewUrls') || isActive('views.createViewUrl') || isActive('views.editViewUrl') }"><link-to route="views.listViewUrls" class="viewslistviewurls-link">{{'common.viewUrls' | translate}}</link-to></li>
-      </ul>
-    </div>
-  </div>
-
-
-  <div class="panel panel-default">
-    <div class="panel-heading"><span class="glyphicon glyphicon-user"></span> {{'common.userGroupManagement' | translate}}</div>
-    <div class="panel-body">
-      <ul class="nav nav-pills nav-stacked">
-        <li ng-class="{active: isActive('users.list')}"><link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to></li>
-        <li ng-class="{active: isActive('groups.list')}"><link-to route="groups.list" class="groupslist-link">{{'common.groups' | translate}}</link-to></li>
-      </ul>
-    </div>
-  </div>
-
-  <div class="panel panel-default" ng-show="settings.isLoginActivitiesSupported || settings.isLDAPConfigurationSupported">
-    <div class="panel-heading"><span class="glyphicon glyphicon-cog"></span> {{'common.settings' | translate}}</div>
-    <div class="panel-body">
-      <ul class="nav nav-pills nav-stacked">
-        <li ng-class="{active: isActive('authentication.main')}" ng-show="settings.isLDAPConfigurationSupported"><link-to route="authentication.main">{{'common.authentication' | translate}}</link-to></li>
-        <li ng-class="{active: isActive('loginActivities.loginMessage')}" ng-show="settings.isLoginActivitiesSupported"><link-to route="loginActivities.loginMessage">{{'common.loginActivities.loginActivities' | translate}}</link-to></li>
-      </ul>
-    </div>
-  </div>
-</div>
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
index 3bdb80e..3c382af 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
@@ -19,7 +19,7 @@
   <div class="panel-body">
     <h1>{{'main.title' | translate}}</h1>
 
-    <div ng-if="isLoaded" id="main-operations-boxes" class="row thumbnails">
+    <div id="main-operations-boxes" class="row thumbnails">
       <p ng-hide="cluster">{{'main.noClusterDescription' | translate}}</p>
 
       <p ng-show="cluster">{{'main.hasClusterDescription' | translate}}</p>
@@ -32,24 +32,29 @@
         <div class="glyphicon glyphicon-cloud"></div>
         <div class="buttons">
         <span ng-class="{active: isActive('clusters.manageAccess')}">
-          <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href class="btn btn-primary permission-button"
-             ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'main.operateCluster.manageRoles' |
-            translate}}</a>
+          <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
+                  class="btn btn-primary permission-button"
+                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+            {{'main.operateCluster.manageRoles' | translate}}
+          </a>
           <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
-             href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
-             class="btn btn-primary permission-button"
-             ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'main.operateCluster.manageRoles' |
-            translate}}</a>
+                  href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
+                  class="btn btn-primary permission-button"
+                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+            {{'main.operateCluster.manageRoles' | translate}}
+          </a>
         </span>
         <span>
           <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
-             class="btn btn-primary go-dashboard-button"
-             ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'common.goToDashboard' |
-            translate}}</a>
+                  class="btn btn-primary go-dashboard-button"
+                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+            {{'common.goToDashboard' | translate}}
+          </a>
           <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
-             href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
-             ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">{{'common.goToDashboard' |
-            translate}}</a>
+                  href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
+                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
+            {{'common.goToDashboard' | translate}}
+          </a>
         </span>
         </div>
       </div>
@@ -58,9 +63,11 @@
 
         <div class="description">{{'main.createCluster.description' | translate}}</div>
         <div class="glyphicon glyphicon-cloud"></div>
-        <div class="buttons"><a href="{{fromSiteRoot('/#/installer/step0')}}"
-                                class="btn btn-primary create-cluster-button">{{'main.createCluster.launchInstallWizard'
-          | translate}}</a></div>
+        <div class="buttons">
+          <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary create-cluster-button">
+            {{'main.createCluster.launchInstallWizard' | translate}}
+          </a>
+        </div>
       </div>
 
       <!--Manage Users and groups-->
@@ -70,14 +77,16 @@
         <div class="description">{{'main.manageUsersAndGroups.description' | translate}}</div>
         <div class="glyphicon glyphicon-user"></div>
         <div class="buttons">
-          <span ng-class="{active: isActive('users.list')}"><link-to route="users.list"
-                                                                     class="btn btn-primary userslist-button">
+          <span ng-class="{active: isActive('users.list')}">
+            <link-to route="users.list" class="btn btn-primary userslist-button">
             {{'common.users' | translate}}
-          </link-to></span>
-          <span ng-class="{active: isActive('groups.list')}"><link-to route="groups.list"
-                                                                      class="btn btn-primary groupslist-button">
+            </link-to>
+          </span>
+          <span ng-class="{active: isActive('groups.list')}">
+            <link-to route="groups.list" class="btn btn-primary groupslist-button">
             {{'common.groups' | translate}}
-          </link-to></span>
+            </link-to>
+          </span>
         </div>
       </div>
 
@@ -88,7 +97,9 @@
         <div class="description">{{'main.deployViews.description' | translate}}</div>
         <div class="glyphicon glyphicon-th"></div>
         <div ng-class="{active: isActive('views.list')}" class="buttons">
-          <link-to route="views.list" class="btn btn-primary viewslist-button">{{'common.views' | translate}}</link-to>
+          <link-to route="views.list" class="btn btn-primary viewslist-button">
+            {{'common.views' | translate}}
+          </link-to>
         </div>
       </div>
     </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index 3bbf09d..e3e11d5 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -22,8 +22,7 @@
       <li class="active">{{'common.remoteClusters' | translate}}</li>
     </ol>
     <div class="pull-right top-margin-4">
-      <a href="#/remoteClusters/create" class="btn btn-primary">
-        <span class="glyphicon glyphicon-plus"></span>
+      <a href="#/remoteClusters/create" class="btn btn-default">
         {{'views.registerRemoteCluster' | translate}}
       </a>
     </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
new file mode 100644
index 0000000..09b4cd9
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
@@ -0,0 +1,106 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div id="side-nav" class="navigation-bar navigation-bar-fit-height">
+  <div class="navigation-bar-container">
+    <ul class="side-nav-header nav nav-pills nav-stacked">
+      <li class="navigation-header active">
+        <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="ambari-logo">
+          <img src="/img/ambari-logo.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-logo">
+        </a>
+        <div class="btn-group">
+          <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="ambari-header-link" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-title">
+            <span class="ambari-header">
+              {{'common.ambari' | translate}}
+            </span>
+          </a>
+        </div>
+      </li>
+    </ul>
+    <ul class="nav side-nav-menu nav-pills nav-stacked">
+      <li class="mainmenu-li active">
+        <a title="{{'common.dashboard' | translate}}" rel="tooltip" data-placement="right" href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">
+          <i class="navigation-icon fa fa-tachometer" aria-hidden="true"></i>
+          <span class="navigation-menu-item">{{'common.dashboard' | translate}}</span>
+        </a>
+      </li>
+      <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+        <a title="{{'common.clusterManagement' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
+          <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+          <i class="navigation-icon fa fa-cloud" aria-hidden="true"></i>
+          <span class="navigation-menu-item">{{'common.clusterManagement' | translate}}</span>
+        </a>
+        <ul class="sub-menu nav nav-pills nav-stacked">
+          <li class="submenu-li"  ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
+            <a href="#/stackVersions">{{'common.clusterInformation' | translate}}</a>
+          </li>
+          <li class="submenu-li" ng-class="{active: isActive('remoteClusters.list')}">
+            <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
+          </li>
+        </ul>
+      </li>
+      <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+        <a title="{{'common.userManagement' | translate}}" rel="tooltip" data-placement="right" data-toggle="collapse-sub-menu">
+          <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+          <i class="navigation-icon fa fa-users" aria-hidden="true"></i>
+          <span class="navigation-menu-item">{{'common.userManagement' | translate}}</span>
+        </a>
+        <ul class="sub-menu nav nav-pills nav-stacked">
+          <li class="submenu-li" ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
+            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">Roles</a>
+          </li>
+          <li class="submenu-li" ng-class="{active: isActive('users.list')}">
+            <link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to>
+          </li>
+          <li class="submenu-li" ng-class="{active: isActive('groups.list')}">
+            <link-to route="groups.list" class="groupslist-link">{{'common.groups' | translate}}</link-to>
+          </li>
+        </ul>
+      </li>
+      <li class="mainmenu-li" ng-class="{active: isActive('views.list')}">
+        <link-to route="views.list" class="viewslist-link" title="{{'common.views' | translate}}" rel="tooltip" data-placement="right">
+          <i class="navigation-icon fa fa-th" aria-hidden="true"></i>
+          <span class="navigation-menu-item">{{'common.views' | translate}}</span>
+        </link-to>
+      </li>
+      <li class="mainmenu-li dropdown has-sub-menu" ng-show="settings.isLoginActivitiesSupported || settings.isLDAPConfigurationSupported">
+        <a title="{{'common.settings' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
+          <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
+          <i class="navigation-icon glyphicon glyphicon-cog" aria-hidden="true"></i>
+          <span class="navigation-menu-item">{{'common.settings' | translate}}</span>
+        </a>
+        <ul class="sub-menu nav nav-pills nav-stacked">
+          <li class="submenu-li"  ng-class="{active: isActive('authentication.main')}" ng-show="settings.isLDAPConfigurationSupported">
+            <link-to route="authentication.main">{{'common.authentication' | translate}}</link-to>
+          </li>
+          <li class="submenu-li" ng-class="{active: isActive('loginActivities.loginMessage')}" ng-show="settings.isLoginActivitiesSupported">
+            <link-to route="loginActivities.loginMessage">{{'common.loginActivities.loginActivities' | translate}}</link-to>
+          </li>
+        </ul>
+      </li>
+    </ul>
+    <ul class="side-nav-footer nav nav-pills nav-stacked">
+      <li class="navigation-footer">
+        <a href="#" data-toggle="collapse-side-nav">
+          <span class="navigation-icon fa fa-angle-double-left" aria-hidden="true"></span>
+        </a>
+      </li>
+    </ul>
+  </div>
+</div>
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index 3e788f8..f6b6ee9 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -22,9 +22,8 @@
       <li class="active">{{'common.versions' | translate}}</li>
     </ol>
     <div class="pull-right top-margin-4">
-      <a href="#/stackVersions/create" class="btn btn-primary">
-        <span class="glyphicon glyphicon-plus"></span>
-        {{'versions.register.title' | translate}}
+      <a href="#/stackVersions/create" class="btn btn-default">
+        {{'versions.add.title' | translate}}
       </a>
     </div>
   </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
index 09024a5..7b8e12a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
@@ -22,7 +22,9 @@
       <li class="active">{{'common.users' | translate}}</li>
     </ol>
     <div class="pull-right top-margin-4">
-      <link-to route="users.create" class="btn btn-primary createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'users.create' | translate}}</link-to>
+      <link-to route="users.create" class="btn btn-default createuser-btn">
+        </span> {{'users.create' | translate}}
+      </link-to>
     </div>
   </div>
   <hr>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/bower.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/bower.json b/ambari-admin/src/main/resources/ui/admin-web/bower.json
index dbdf005..c38f464 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/bower.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/bower.json
@@ -2,7 +2,7 @@
   "name": "adminconsole",
   "private": true,
   "dependencies": {
-    "bootstrap": "3.1.1",
+    "bootstrap": "3.3.7",
     "angular": "1.2.26",
     "angular-route": "1.2.26",
     "angular-bootstrap": "0.11.0",

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
index 2f47b85..9b377d1 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js
@@ -24,10 +24,10 @@ var gulp = require('gulp');
 var $ = require('gulp-load-plugins')();
 
 gulp.task('styles', function () {
-  return gulp.src('app/styles/*.css')
+  return gulp.src('app/styles/**/*.css')
     .pipe($.order([
-      'app/styles/main.css',
-      'app/styles/custom-admin-ui.css'   // This should always be the last stylesheet. So it can be dropped and be effective on build time
+      'app/styles/theme/bootstrap-ambari.css',
+      'app/styles/main.css'
     ], { base: './' }))
     .pipe($.concat('main.css'))
     .pipe($.autoprefixer('last 1 version'))
@@ -64,8 +64,8 @@ gulp.task('images', function () {
 });
 
 gulp.task('fonts', function () {
-  return $.bowerFiles()
-    .pipe($.filter('**/*.{eot,svg,ttf,woff}'))
+  return gulp.src('app/bower_components/**/fonts/*.{eot,svg,ttf,woff}')
+    .pipe($.addSrc('app/assets/fonts/*'))
     .pipe($.flatten())
     .pipe(gulp.dest('dist/fonts'))
     .pipe($.size());

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/package.json
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/package.json b/ambari-admin/src/main/resources/ui/admin-web/package.json
index efcd9d4..b7c514c 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/package.json
+++ b/ambari-admin/src/main/resources/ui/admin-web/package.json
@@ -5,19 +5,19 @@
   "devDependencies": {
     "bower": "1.3.8",
     "gulp": "^3.8.8",
+    "gulp-add-src": "^0.2.0",
     "gulp-autoprefixer": "0.0.7",
-    "gulp-bower-files": "0.2.1",
     "gulp-cache": "0.1.1",
     "gulp-clean": "0.2.4",
+    "gulp-concat": "2.6.0",
     "gulp-filter": "0.4.1",
     "gulp-flatten": "0.0.2",
     "gulp-load-plugins": "0.5.0",
+    "gulp-order": "1.1.1",
     "gulp-plumber": "0.6.6",
     "gulp-size": "0.3.0",
     "gulp-uglify": "0.2.1",
     "gulp-useref": "0.4.2",
-    "gulp-concat": "2.6.0",
-    "gulp-order": "1.1.1",
     "http-server": "0.6.1",
     "karma": "0.12.16",
     "karma-chrome-launcher": "0.1.4",

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
new file mode 100644
index 0000000..1bbe47a
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js
@@ -0,0 +1,211 @@
+/**
+ * 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.
+ */
+
+describe('#AppCtrl', function () {
+
+  var scope, ctrl, $httpBackend, $window, clusterService, deferred;
+
+  beforeEach(function () {
+    module('ambariAdminConsole', function ($provide) {
+      $provide.value('$route', {
+        current: null
+      });
+      $provide.value('$window', {
+        location: {
+          pathname: 'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
+        },
+        localStorage: {
+          getItem: function () {
+            return null;
+          },
+          setItem: angular.noop
+        }
+      });
+      localStorage.ambari = JSON.stringify({
+        app: {
+          authenticated: true,
+          loginName: 'admin',
+          user: 'user'
+        }
+      });
+    });
+    inject(function (_$httpBackend_, $rootScope, $controller, _$window_, _Cluster_, _$q_) {
+      clusterService = _Cluster_;
+      deferred = _$q_.defer();
+      spyOn(clusterService, 'getStatus').andReturn(deferred.promise);
+      deferred.resolve({
+        Clusters: {
+          provisioning_state: 'INIT'
+        }
+      });
+      $window = _$window_;
+      $httpBackend = _$httpBackend_;
+      $httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200, {
+        RootServiceComponents: {
+          component_version: 2.2,
+          properties: {
+            'user.inactivity.timeout.default': 20
+          }
+        }
+      });
+      $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
+          "href": "http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true",
+          "items": [
+            {
+              "ViewInfo": {
+                "view_name": "SLIDER"
+              },
+              "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER",
+              "versions": [
+                {
+                  "ViewVersionInfo": {
+                    "system": false,
+                    "version": "1.0.0",
+                    "view_name": "SLIDER"
+                  },
+                  "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0",
+                  "instances": [
+                    {
+                      "ViewInstanceInfo": {
+                        "context_path": "/views/SLIDER/1.0.0/VisibleInstance",
+                        "description": "VisibleInstance",
+                        "icon64_path": null,
+                        "icon_path": null,
+                        "instance_data": {},
+                        "instance_name": "VisibleInstance",
+                        "label": "VisibleInstance",
+                        "properties": {
+                          "ambari.server.password": "123",
+                          "ambari.server.url": "123",
+                          "ambari.server.username": "123",
+                          "slider.user": null,
+                          "view.kerberos.principal": null,
+                          "view.kerberos.principal.keytab": null
+                        },
+                        "static": false,
+                        "version": "1.0.0",
+                        "view_name": "SLIDER",
+                        "visible": true
+                      },
+                      "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        });
+      $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {
+        data: {
+          data: {
+            addingNewRepository: true
+          }
+        }
+      });
+      scope = $rootScope.$new();
+      scope.$apply();
+      ctrl = $controller('AppCtrl', {
+        $scope: scope
+      });
+    });
+  });
+
+  afterEach(function() {
+    $httpBackend.verifyNoOutstandingExpectation();
+    $httpBackend.verifyNoOutstandingRequest();
+  });
+
+  describe('signout', function () {
+
+    beforeEach(function () {
+      $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{
+        message: "successfully logged out"
+      });
+      $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+        items: [
+          {
+            AuthorizationInfo: {
+              authorization_id: "AMBARI.RENAME_CLUSTER"
+            }
+          }
+        ]
+      });
+    });
+
+    it('should reset window.location and ambari localstorage', function () {
+      scope.signOut();
+
+      runs(function() {
+        chai.expect($window.location.pathname).to.equal('/');
+      });
+
+      var data = JSON.parse(localStorage.ambari);
+      chai.expect(data.app.authenticated).to.equal(undefined);
+      chai.expect(data.app.loginName).to.equal(undefined);
+      chai.expect(data.app.user).to.equal(undefined);
+      $httpBackend.flush();
+    });
+  });
+
+  describe('roles loading', function () {
+
+    var mock = {
+        callback: angular.noop
+      },
+      cases = [
+        {
+          canPersistData: true,
+          items: [
+            {
+              AuthorizationInfo: {
+                authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA'
+              }
+            }
+          ],
+          title: 'user can persist data'
+        },
+        {
+          canPersistData: false,
+          items: [],
+          title: 'user can\'t persist data'
+        }
+      ];
+
+    angular.forEach(cases, function (item) {
+
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
+            items: item.items
+          });
+          spyOn(mock, 'callback');
+          scope.authDataLoad.promise.then(mock.callback);
+          $httpBackend.flush();
+        });
+
+        it('authDataLoad should be resolved with the correct argument', function () {
+          expect(mock.callback).toHaveBeenCalledWith(item.canPersistData);
+        });
+
+      });
+
+    });
+
+  });
+});


[16/51] [abbrv] ambari git commit: AMBARI-22360. Send ClusterVersionSummary to install_packages and conf-select exclusion (ncole)

Posted by nc...@apache.org.
AMBARI-22360. Send ClusterVersionSummary to install_packages and conf-select exclusion (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1afee6096639b26ed74178bcdd2b6984fda42b32
Parents: 1fefbba
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Nov 6 10:11:21 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Nov 6 12:16:26 2017 -0500

----------------------------------------------------------------------
 .../libraries/functions/conf_select.py          |  58 +++++
 .../ambari/server/agent/ExecutionCommand.java   |  34 ++-
 .../ClusterStackVersionResourceProvider.java    |   3 +-
 .../HostStackVersionResourceProvider.java       |   2 +-
 .../state/repository/ClusterVersionSummary.java |   3 +
 .../state/repository/ServiceVersionSummary.java |  11 +-
 .../state/repository/VersionDefinitionXml.java  |   2 +-
 .../stack/upgrade/RepositoryVersionHelper.java  |  28 ++-
 .../custom_actions/scripts/install_packages.py  |  12 +-
 .../HDP/2.0.6/properties/stack_packages.json    | 101 ++++++++
 .../HDP/3.0/properties/stack_packages.json      | 108 ++++++++-
 ...ClusterStackVersionResourceProviderTest.java | 239 +++++++++++++++++++
 .../stacks/2.2/common/test_conf_select.py       |  14 +-
 13 files changed, 600 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
index c89e767..d38e273 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/conf_select.py
@@ -294,6 +294,64 @@ def convert_conf_directories_to_symlinks(package, version, dirs):
       Logger.warning("Could not change symlink for package {0} to point to current directory. Error: {1}".format(package, e))
 
 
+def get_restricted_packages():
+  """
+  Gets the list of conf-select 'package' names that need to be invoked on the command.
+  When the server passes down the list of packages to install, check the service names
+  and use the information in stack_packages json to determine the list of packages that should
+  be executed.  That is valid only for PATCH or MAINT upgrades.  STANDARD upgrades should be
+  conf-select'ing everything it can find.
+  """
+  package_names = []
+
+  # shortcut the common case if we are not patching
+  cluster_version_summary = default("/roleParameters/cluster_version_summary/services", None)
+
+  if cluster_version_summary is None:
+    Logger.info("Cluster Summary is not available, there are no restrictions for conf-select")
+    return package_names
+
+  service_names = []
+
+  # pick out the services that are targeted
+  for servicename, servicedetail in cluster_version_summary.iteritems():
+    if servicedetail['upgrade']:
+      service_names.append(servicename)
+
+  if 0 == len(service_names):
+    Logger.info("No services found, there are no restrictions for conf-select")
+    return package_names
+
+  stack_name = default("/hostLevelParams/stack_name", None)
+  if stack_name is None:
+    Logger.info("The stack name is not present in the command. Restricted names skipped.")
+    return package_names
+
+  stack_packages_config = default("/configurations/cluster-env/stack_packages", None)
+  if stack_packages_config is None:
+    Logger.info("The stack packages are not defined on the command. Restricted names skipped.")
+    return package_names
+
+  data = json.loads(stack_packages_config)
+
+  if stack_name not in data:
+    Logger.info("Cannot find conf-select packages for the {0} stack".format(stack_name))
+    return package_names
+
+  conf_select_key = "conf-select-patching"
+  if conf_select_key not in data[stack_name]:
+    Logger.info("There are no conf-select-patching elements defined for this command for the {0} stack".format(stack_name))
+    return package_names
+
+  service_dict = data[stack_name][conf_select_key]
+
+  for servicename in service_names:
+    if servicename in service_dict and 'packages' in service_dict[servicename]:
+      package_names.extend(service_dict[servicename]['packages'])
+
+  return package_names
+
+
 def _seed_new_configuration_directories(package, created_directories):
   """
   Copies any files from the "current" configuration directory to the directories which were

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 9198164..e475c05 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -160,6 +160,9 @@ public class ExecutionCommand extends AgentCommand {
   @SerializedName("upgradeSummary")
   private UpgradeSummary upgradeSummary;
 
+  @SerializedName("roleParameters")
+  private Map<String, Object> roleParameters;
+
   public void setConfigurationCredentials(Map<String, Map<String, String>> configurationCredentials) {
     this.configurationCredentials = configurationCredentials;
   }
@@ -235,6 +238,10 @@ public class ExecutionCommand extends AgentCommand {
     return roleParams;
   }
 
+  /**
+   * Sets the roleParams for the command.  Consider instead using {@link #setRoleParameters}
+   * @param roleParams
+   */
   public void setRoleParams(Map<String, String> roleParams) {
     this.roleParams = roleParams;
   }
@@ -332,11 +339,11 @@ public class ExecutionCommand extends AgentCommand {
   }
 
   public String getServiceType() {
-	return serviceType;
+    return serviceType;
   }
 
   public void setServiceType(String serviceType) {
-	this.serviceType = serviceType;
+    this.serviceType = serviceType;
   }
 
   /**
@@ -413,6 +420,23 @@ public class ExecutionCommand extends AgentCommand {
   }
 
   /**
+   * Gets the object-based role parameters for the command.
+   */
+  public Map<String, Object> getRoleParameters() {
+    return roleParameters;
+  }
+
+  /**
+   * Sets the role parameters for the command.  This is preferred over {@link #setRoleParams(Map)},
+   * as this form will pass values as structured data, as opposed to unstructured, escaped json.
+   *
+   * @param params
+   */
+  public void setRoleParameters(Map<String, Object> params) {
+    roleParameters = params;
+  }
+
+  /**
    * Contains key name strings. These strings are used inside maps
    * incapsulated inside command.
    */
@@ -512,6 +536,12 @@ public class ExecutionCommand extends AgentCommand {
         feature = ExperimentalFeature.PATCH_UPGRADES,
         comment = "Change this to reflect the component version")
     String VERSION = "version";
+
+
+    /**
+     * When installing packages, includes what services will be included in the upgrade
+     */
+    String CLUSTER_VERSION_SUMMARY = "cluster_version_summary";
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 969fca1..98adcd1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -730,7 +730,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       return null;
     }
 
-
     Map<String, String> roleParams = repoVersionHelper.buildRoleParams(managementController, repoVersion,
         osFamily, servicesOnHost);
 
@@ -744,7 +743,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
     actionContext.setRepositoryVersion(repoVersion);
     actionContext.setTimeout(Short.valueOf(configuration.getDefaultAgentTaskTimeout(true)));
 
-    repoVersionHelper.addCommandRepository(actionContext, repoVersion, osEntity);
+    repoVersionHelper.addCommandRepository(actionContext, cluster, repoVersion, osEntity);
 
     return actionContext;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
index ba5fccc..b106209 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostStackVersionResourceProvider.java
@@ -443,7 +443,7 @@ public class HostStackVersionResourceProvider extends AbstractControllerResource
             roleParams);
     actionContext.setTimeout(Short.valueOf(configuration.getDefaultAgentTaskTimeout(true)));
 
-    repoVersionHelper.addCommandRepository(actionContext, repoVersionEnt, osEntity);
+    repoVersionHelper.addCommandRepository(actionContext, cluster, repoVersionEnt, osEntity);
 
     String caption = String.format(INSTALL_PACKAGES_FULL_NAME + " on host %s", hostName);
     RequestStageContainer req = createRequest(caption);

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
index e9d9920..5486ecd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ClusterVersionSummary.java
@@ -24,11 +24,14 @@ import java.util.Set;
 import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
 
+import com.google.gson.annotations.SerializedName;
+
 /**
  * For a version, collects summary information for a cluster.
  */
 public class ClusterVersionSummary {
 
+  @SerializedName("services")
   @JsonProperty("services")
   private Map<String, ServiceVersionSummary> m_services;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
index 29505c8..d87caef 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/ServiceVersionSummary.java
@@ -20,25 +20,26 @@ package org.apache.ambari.server.state.repository;
 import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
 
+import com.google.gson.annotations.SerializedName;
+
 /**
  * Used to hold information about Service's ability to upgrade for a repository version.
  */
 public class ServiceVersionSummary {
 
-  @JsonProperty("display_name")
-  private String m_displayName;
-
+  @SerializedName("version")
   @JsonProperty("version")
   private String m_version;
 
+  @SerializedName("release_version")
   @JsonProperty("release_version")
   private String m_releaseVersion;
 
+  @SerializedName("upgrade")
   @JsonProperty("upgrade")
   private boolean m_upgrade = false;
 
-  ServiceVersionSummary(String displayName) {
-    m_displayName = displayName;
+  ServiceVersionSummary() {
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 62f78de..a519d00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -300,7 +300,7 @@ public class VersionDefinitionXml {
         continue;
       }
 
-      ServiceVersionSummary summary = new ServiceVersionSummary(service.getDisplayName());
+      ServiceVersionSummary summary = new ServiceVersionSummary();
       summaries.put(service.getName(), summary);
 
       String serviceVersion = service.getDesiredRepositoryVersion().getVersion();

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
index 8f34613..87943d1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/RepositoryVersionHelper.java
@@ -41,10 +41,14 @@ import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.orm.entities.OperatingSystemEntity;
 import org.apache.ambari.server.orm.entities.RepositoryEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.repository.ClusterVersionSummary;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.UpgradePack;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -312,7 +316,7 @@ public class RepositoryVersionHelper {
    * @param osEntity      the OS family
    * @param repoVersion   the repository version entity
    */
-  public void addCommandRepository(ActionExecutionContext context,
+  public void addCommandRepository(ActionExecutionContext context, Cluster cluster,
       RepositoryVersionEntity repoVersion, OperatingSystemEntity osEntity) {
 
     final CommandRepository commandRepo = new CommandRepository();
@@ -344,12 +348,34 @@ public class RepositoryVersionHelper {
       commandRepo.getFeature().setIsScoped(false);
     }
 
+    ClusterVersionSummary summary = null;
+    if (RepositoryType.STANDARD != repoVersion.getType()) {
+      try {
+        VersionDefinitionXml xml = repoVersion.getRepositoryXml();
+        summary = xml.getClusterSummary(cluster);
+      } catch (Exception e) {
+        LOG.warn("Could not determine repository from %s/%s.  Will not pass cluster version.");
+      }
+    }
+
+    final ClusterVersionSummary clusterSummary = summary;
+
     context.addVisitor(new ExecutionCommandVisitor() {
       @Override
       public void visit(ExecutionCommand command) {
         if (null == command.getRepositoryFile()) {
           command.setRepositoryFile(commandRepo);
         }
+
+        if (null != clusterSummary) {
+          Map<String, Object> params = command.getRoleParameters();
+          if (null == params) {
+            params = new HashMap<>();
+            command.setRoleParameters(params);
+          }
+          params.put(KeyNames.CLUSTER_VERSION_SUMMARY, clusterSummary);
+        }
+
       }
     });
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
index 47f9a74..fff18bb 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/install_packages.py
@@ -179,8 +179,18 @@ class InstallPackages(Script):
             and not sudo.path_exists("/usr/bin/conf-select") and sudo.path_exists("/usr/bin/hdfconf-select"):
       Link("/usr/bin/conf-select", to="/usr/bin/hdfconf-select")
 
+
+    restricted_packages = conf_select.get_restricted_packages()
+
+    if 0 == len(restricted_packages):
+      Logger.info("There are no restricted conf-select packages for this installation")
+    else:
+      Logger.info("Restricting conf-select packages to {0}".format(restricted_packages))
+
     for package_name, directories in conf_select.get_package_dirs().iteritems():
-      conf_select.convert_conf_directories_to_symlinks(package_name, stack_version, directories)
+      if 0 == len(restricted_packages) or package_name in restricted_packages:
+        conf_select.convert_conf_directories_to_symlinks(package_name, stack_version, directories)
+
 
   def compute_actual_version(self):
     """

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 20b12a9..23c6d32 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -994,6 +994,12 @@
           "current_dir": "{0}/current/atlas-client/conf"
         }
       ],
+      "beacon": [
+        {
+          "conf_dir": "/etc/beacon/conf",
+          "current_dir": "{0}/current/beacon-client/conf"
+        }
+      ],
       "druid": [
         {
           "conf_dir": "/etc/druid/conf",
@@ -1060,6 +1066,12 @@
           "current_dir": "{0}/current/knox-server/conf"
         }
       ],
+      "livy": [
+        {
+          "conf_dir": "/etc/livy/conf",
+          "current_dir": "{0}/current/livy"
+        }
+      ],
       "mahout": [
         {
           "conf_dir": "/etc/mahout/conf",
@@ -1175,6 +1187,95 @@
         }
       ]
     },
+    "conf-select-patching": {
+      "ACCUMULO": {
+        "packages": ["accumulo"]
+      },
+      "ATLAS": {
+        "packages": ["atlas"]
+      },
+      "BEACON": {
+        "packages": ["beacon"]
+      },
+      "DRUID": {
+        "packages": ["druid", "superset"]
+      },
+      "FALCON": {
+        "packages": ["falcon"]
+      },
+      "FLUME": {
+        "packages": ["flume"]
+      },
+      "HBASE": {
+        "packages": ["hbase"]
+      },
+      "HDFS": {
+        "packages": []
+      },
+      "HIVE": {
+        "packages": ["hive", "hive-hcatalog", "hive2", "tez_hive2"]
+      },
+      "KAFKA": {
+        "packages": ["kafka"]
+      },
+      "KNOX": {
+        "packages": ["knox"]
+      },
+      "MAHOUT": {
+        "packages": ["mahout"]
+      },
+      "MAPREDUCE2": {
+        "packages": []
+      },
+      "OOZIE": {
+        "packages": ["oozie"]
+      },
+      "PIG": {
+        "packages": ["pig"]
+      },
+      "R4ML": {
+        "packages": []
+      },
+      "RANGER": {
+        "packages": ["ranger-admin", "ranger-usersync", "ranger-tagsync"]
+      },
+      "RANGER_KMS": {
+        "packages": ["ranger-kms"]
+      },
+      "SLIDER": {
+        "packages": ["slider"]
+      },
+      "SPARK": {
+        "packages": ["spark", "livy"]
+      },
+      "SPARK2": {
+        "packages": ["spark2", "livy"]
+      },
+      "SQOOP": {
+        "packages": ["sqoop"]
+      },
+      "STORM": {
+        "packages": ["storm", "storm-slider-client"]
+      },
+      "SYSTEMML": {
+        "packages": []
+      },
+      "TEZ": {
+        "packages": ["tez"]
+      },
+      "TITAN": {
+        "packages": []
+      },
+      "YARN": {
+        "packages": []
+      },
+      "ZEPPELIN": {
+        "packages": ["zeppelin"]
+      },
+      "ZOOKEEPER": {
+        "packages": ["zookeeper"]
+      }
+    },
     "upgrade-dependencies" : {
       "YARN": ["TEZ"],
       "TEZ": ["YARN"],

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
index be4c718..d8cd015 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
@@ -871,6 +871,12 @@
           "current_dir": "{0}/current/atlas-client/conf"
         }
       ],
+      "beacon": [
+        {
+          "conf_dir": "/etc/beacon/conf",
+          "current_dir": "{0}/current/beacon-client/conf"
+        }
+      ],
       "druid": [
         {
           "conf_dir": "/etc/druid/conf",
@@ -937,6 +943,12 @@
           "current_dir": "{0}/current/knox-server/conf"
         }
       ],
+      "livy": [
+        {
+          "conf_dir": "/etc/livy/conf",
+          "current_dir": "{0}/current/livy"
+        }
+      ],
       "mahout": [
         {
           "conf_dir": "/etc/mahout/conf",
@@ -1051,6 +1063,100 @@
           "current_dir": "{0}/current/zookeeper-client/conf"
         }
       ]
-    }
+    },
+    "conf-select-patching": {
+      "ACCUMULO": {
+        "packages": ["accumulo"]
+      },
+      "ATLAS": {
+        "packages": ["atlas"]
+      },
+      "BEACON": {
+        "packages": ["beacon"]
+      },
+      "DRUID": {
+        "packages": ["druid", "superset"]
+      },
+      "FALCON": {
+        "packages": ["falcon"]
+      },
+      "FLUME": {
+        "packages": ["flume"]
+      },
+      "HBASE": {
+        "packages": ["hbase"]
+      },
+      "HDFS": {
+        "packages": []
+      },
+      "HIVE": {
+        "packages": ["hive", "hive-hcatalog", "hive2", "tez_hive2"]
+      },
+      "KAFKA": {
+        "packages": ["kafka"]
+      },
+      "KNOX": {
+        "packages": ["knox"]
+      },
+      "MAHOUT": {
+        "packages": ["mahout"]
+      },
+      "MAPREDUCE2": {
+        "packages": []
+      },
+      "OOZIE": {
+        "packages": ["oozie"]
+      },
+      "PIG": {
+        "packages": ["pig"]
+      },
+      "R4ML": {
+        "packages": []
+      },
+      "RANGER": {
+        "packages": ["ranger-admin", "ranger-usersync", "ranger-tagsync"]
+      },
+      "RANGER_KMS": {
+        "packages": ["ranger-kms"]
+      },
+      "SLIDER": {
+        "packages": ["slider"]
+      },
+      "SPARK": {
+        "packages": ["spark", "livy"]
+      },
+      "SPARK2": {
+        "packages": ["spark2", "livy"]
+      },
+      "SQOOP": {
+        "packages": ["sqoop"]
+      },
+      "STORM": {
+        "packages": ["storm", "storm-slider-client"]
+      },
+      "SYSTEMML": {
+        "packages": []
+      },
+      "TEZ": {
+        "packages": ["tez"]
+      },
+      "TITAN": {
+        "packages": []
+      },
+      "YARN": {
+        "packages": []
+      },
+      "ZEPPELIN": {
+        "packages": ["zeppelin"]
+      },
+      "ZOOKEEPER": {
+        "packages": ["zookeeper"]
+      }
+    },
+    "upgrade-dependencies" : {
+      "YARN": ["TEZ"],
+      "TEZ": ["YARN"],
+      "MAHOUT": ["MAPREDUCE2"]
+    }    
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
index 9840106..f45ff75 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProviderTest.java
@@ -99,6 +99,7 @@ import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.cluster.ClusterImpl;
 import org.apache.ambari.server.state.repository.AvailableService;
+import org.apache.ambari.server.state.repository.ClusterVersionSummary;
 import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
@@ -1883,6 +1884,244 @@ public class ClusterStackVersionResourceProviderTest {
 
   }
 
+   @Test
+   public void testCreateResourcesPatch() throws Exception {
+     JsonArray json = new JsonParser().parse(OS_JSON).getAsJsonArray();
+
+     JsonObject jsonObj = json.get(0).getAsJsonObject();
+     jsonObj.addProperty(OperatingSystemResourceProvider.OPERATING_SYSTEM_AMBARI_MANAGED_REPOS, false);
+
+     String os_json = json.toString();
+
+     Cluster cluster = createNiceMock(Cluster.class);
+     StackId stackId = new StackId("HDP", "2.0.1");
+
+     StackEntity fromStack = new StackEntity();
+     fromStack.setStackName(stackId.getStackName());
+     fromStack.setStackVersion(stackId.getStackVersion());
+
+     RepositoryVersionEntity fromRepo = new RepositoryVersionEntity();
+     fromRepo.setId(0L);
+     fromRepo.setOperatingSystems(os_json);
+     fromRepo.setVersionXsd("version_definition.xsd");
+     fromRepo.setType(RepositoryType.STANDARD);
+     fromRepo.setStack(fromStack);
+     fromRepo.setVersion("2.0.1.0-1234");
+
+
+     StackEntity stackEntity = new StackEntity();
+     stackEntity.setStackName("HDP");
+     stackEntity.setStackVersion("2.1.1");
+
+     File f = new File("src/test/resources/hbase_version_test.xml");
+     String xmlString = IOUtils.toString(new FileInputStream(f));
+     // hack to remove ZK
+     xmlString = xmlString.replace("<service idref=\"ZOOKEEPER-346\" />", "");
+
+
+     RepositoryVersionEntity repoVersion = new RepositoryVersionEntity();
+     repoVersion.setId(1l);
+     repoVersion.setOperatingSystems(os_json);
+     repoVersion.setVersionXml(xmlString);
+     repoVersion.setVersionXsd("version_definition.xsd");
+     repoVersion.setType(RepositoryType.PATCH);
+     repoVersion.setStack(stackEntity);
+
+     ambariMetaInfo.getComponent("HDP", "2.1.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
+     ambariMetaInfo.getComponent("HDP", "2.0.1", "HBASE", "HBASE_MASTER").setVersionAdvertised(true);
+
+     final String hostWithoutVersionableComponents = "host3";
+     List<Host> hostsNeedingInstallCommands = new ArrayList<>();
+
+     Map<String, Host> hostsForCluster = new HashMap<>();
+     int hostCount = 10;
+     for (int i = 0; i < hostCount; i++) {
+       String hostname = "host" + i;
+       Host host = createNiceMock(hostname, Host.class);
+       expect(host.getHostName()).andReturn(hostname).anyTimes();
+       expect(host.getOsFamily()).andReturn("redhat6").anyTimes();
+       expect(host.getMaintenanceState(EasyMock.anyLong())).andReturn(
+           MaintenanceState.OFF).anyTimes();
+       expect(host.getAllHostVersions()).andReturn(
+           Collections.<HostVersionEntity>emptyList()).anyTimes();
+       expect(host.getHostAttributes()).andReturn(new HashMap<String, String>()).anyTimes();
+       replay(host);
+       hostsForCluster.put(hostname, host);
+
+       if (StringUtils.equals(hostWithoutVersionableComponents, hostname)) {
+         hostsNeedingInstallCommands.add(host);
+       }
+     }
+
+     Service hdfsService = createNiceMock(Service.class);
+     expect(hdfsService.getName()).andReturn("HDFS").anyTimes();
+     expect(hdfsService.getServiceComponents()).andReturn(new HashMap<String, ServiceComponent>());
+     expect(hdfsService.getDesiredRepositoryVersion()).andReturn(fromRepo).anyTimes();
+
+     Service hbaseService = createNiceMock(Service.class);
+     expect(hbaseService.getName()).andReturn("HBASE").anyTimes();
+     expect(hbaseService.getServiceComponents()).andReturn(new HashMap<String, ServiceComponent>());
+     expect(hbaseService.getDesiredRepositoryVersion()).andReturn(fromRepo).anyTimes();
+
+     Map<String, Service> serviceMap = new HashMap<>();
+     serviceMap.put("HDFS", hdfsService);
+     serviceMap.put("HBASE", hbaseService);
+
+     final ServiceComponentHost schDatanode = createMock(ServiceComponentHost.class);
+     expect(schDatanode.getServiceName()).andReturn("HDFS").anyTimes();
+     expect(schDatanode.getServiceComponentName()).andReturn("DATANODE").anyTimes();
+
+     final ServiceComponentHost schNamenode = createMock(ServiceComponentHost.class);
+     expect(schNamenode.getServiceName()).andReturn("HDFS").anyTimes();
+     expect(schNamenode.getServiceComponentName()).andReturn("NAMENODE").anyTimes();
+
+     final ServiceComponentHost schHBM = createMock(ServiceComponentHost.class);
+     expect(schHBM.getServiceName()).andReturn("HBASE").anyTimes();
+     expect(schHBM.getServiceComponentName()).andReturn("HBASE_MASTER").anyTimes();
+
+     // First host contains versionable components
+     final List<ServiceComponentHost> schsH1 = Arrays.asList(schDatanode, schNamenode);
+
+     // Second host contains versionable components
+     final List<ServiceComponentHost> schsH2 = Arrays.asList(schDatanode);
+
+     // Third host only has hbase
+     final List<ServiceComponentHost> schsH3 = Arrays.asList(schHBM);
+
+     ServiceOsSpecific.Package hdfsPackage = new ServiceOsSpecific.Package();
+     hdfsPackage.setName("hdfs");
+
+     List<ServiceOsSpecific.Package> packages = Collections.singletonList(hdfsPackage);
+
+     ActionManager actionManager = createNiceMock(ActionManager.class);
+
+     RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+     ResourceProvider csvResourceProvider = createNiceMock(ResourceProvider.class);
+
+     Map<String, Map<String, String>> hostConfigTags = new HashMap<>();
+     expect(configHelper.getEffectiveDesiredTags(anyObject(ClusterImpl.class), anyObject(String.class))).andReturn(hostConfigTags);
+
+     expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+     expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+     expect(managementController.getAuthName()).andReturn("admin").anyTimes();
+     expect(managementController.getActionManager()).andReturn(actionManager).anyTimes();
+     expect(managementController.getJdkResourceUrl()).andReturn("/JdkResourceUrl").anyTimes();
+     expect(managementController.getPackagesForServiceHost(anyObject(ServiceInfo.class),
+         EasyMock.<Map<String, String>>anyObject(), anyObject(String.class))).
+     andReturn(packages).anyTimes(); // only one host has the versionable component
+
+     expect(managementController.findConfigurationTagsWithOverrides(anyObject(Cluster.class), EasyMock.anyString()))
+     .andReturn(new HashMap<String, Map<String, String>>()).anyTimes();
+
+     expect(clusters.getCluster(anyObject(String.class))).andReturn(cluster);
+     expect(clusters.getHostsForCluster(anyObject(String.class))).andReturn(
+         hostsForCluster).anyTimes();
+
+     String clusterName = "Cluster100";
+     expect(cluster.getClusterId()).andReturn(1L).anyTimes();
+     expect(cluster.getHosts()).andReturn(hostsForCluster.values()).atLeastOnce();
+     expect(cluster.getServices()).andReturn(serviceMap).anyTimes();
+     expect(cluster.getCurrentStackVersion()).andReturn(stackId);
+     expect(cluster.getServiceComponentHosts(anyObject(String.class))).andAnswer(new IAnswer<List<ServiceComponentHost>>() {
+       @Override
+       public List<ServiceComponentHost> answer() throws Throwable {
+         String hostname = (String) EasyMock.getCurrentArguments()[0];
+         if (hostname.equals("host2")) {
+           return schsH2;
+         } else if (hostname.equals("host3")) {
+           return schsH3;
+         } else {
+           return schsH1;
+         }
+       }
+     }).anyTimes();
+
+     expect(cluster.transitionHostsToInstalling(anyObject(RepositoryVersionEntity.class),
+         anyObject(VersionDefinitionXml.class), eq(false))).andReturn(hostsNeedingInstallCommands).atLeastOnce();
+
+     ExecutionCommand executionCommand = new ExecutionCommand();
+     ExecutionCommandWrapper executionCommandWrapper = createNiceMock(ExecutionCommandWrapper.class);
+
+     expect(executionCommandWrapper.getExecutionCommand()).andReturn(executionCommand).anyTimes();
+
+     Stage stage = createNiceMock(Stage.class);
+     expect(stage.getExecutionCommandWrapper(anyObject(String.class), anyObject(String.class))).
+     andReturn(executionCommandWrapper).anyTimes();
+
+     Map<Role, Float> successFactors = new HashMap<>();
+     expect(stage.getSuccessFactors()).andReturn(successFactors).atLeastOnce();
+
+     // Check that we create proper stage count
+     expect(stageFactory.createNew(anyLong(), anyObject(String.class),
+         anyObject(String.class), anyLong(),
+         anyObject(String.class), anyObject(String.class),
+         anyObject(String.class))).andReturn(stage).
+     times((int) Math.ceil(hostCount / MAX_TASKS_PER_STAGE));
+
+     expect(repositoryVersionDAOMock.findByStackAndVersion(anyObject(StackId.class),
+         anyObject(String.class))).andReturn(repoVersion);
+
+     Capture<org.apache.ambari.server.actionmanager.Request> c = Capture.newInstance();
+     Capture<ExecuteActionRequest> ear = Capture.newInstance();
+
+     actionManager.sendActions(capture(c), capture(ear));
+     expectLastCall().atLeastOnce();
+     expect(actionManager.getRequestTasks(anyLong())).andReturn(Collections.<HostRoleCommand>emptyList()).anyTimes();
+
+     ClusterEntity clusterEntity = new ClusterEntity();
+     clusterEntity.setClusterId(1l);
+     clusterEntity.setClusterName(clusterName);
+
+     StageUtils.setTopologyManager(injector.getInstance(TopologyManager.class));
+     StageUtils.setConfiguration(injector.getInstance(Configuration.class));
+
+     // replay
+     replay(managementController, response, clusters, hdfsService, hbaseService, csvResourceProvider,
+         cluster, repositoryVersionDAOMock, configHelper, schDatanode, schNamenode, schHBM, actionManager,
+         executionCommandWrapper,stage, stageFactory);
+
+     ResourceProvider provider = createProvider(managementController);
+     injector.injectMembers(provider);
+
+     // add the property map to a set for the request.  add more maps for multiple creates
+     Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
+
+     Map<String, Object> properties = new LinkedHashMap<>();
+
+     // add properties to the request map
+     properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_CLUSTER_NAME_PROPERTY_ID, "Cluster100");
+     properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_REPOSITORY_VERSION_PROPERTY_ID, "2.2.0.1-885");
+     properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_STACK_PROPERTY_ID, "HDP");
+     properties.put(ClusterStackVersionResourceProvider.CLUSTER_STACK_VERSION_VERSION_PROPERTY_ID, "2.1.1");
+
+     propertySet.add(properties);
+
+     // create the request
+     Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+     SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+
+     RequestStatus status = provider.createResources(request);
+     Assert.assertNotNull(status);
+
+     // check that the success factor was populated in the stage
+     Float successFactor = successFactors.get(Role.INSTALL_PACKAGES);
+     Assert.assertEquals(Float.valueOf(0.85f), successFactor);
+
+     Assert.assertNotNull(executionCommand.getRepositoryFile());
+     Assert.assertNotNull(executionCommand.getRoleParameters());
+     Map<String, Object> roleParams = executionCommand.getRoleParameters();
+     Assert.assertTrue(roleParams.containsKey(KeyNames.CLUSTER_VERSION_SUMMARY));
+     Assert.assertEquals(ClusterVersionSummary.class,
+         roleParams.get(KeyNames.CLUSTER_VERSION_SUMMARY).getClass());
+
+     Assert.assertEquals(2, executionCommand.getRepositoryFile().getRepositories().size());
+     for (CommandRepository.Repository repo : executionCommand.getRepositoryFile().getRepositories()) {
+       Assert.assertFalse(repo.isAmbariManaged());
+     }
+
+   }
+
    private ClusterStackVersionResourceProvider createProvider(AmbariManagementController amc) {
      ResourceProviderFactory factory = injector.getInstance(ResourceProviderFactory.class);
      AbstractControllerResourceProvider.init(factory);

http://git-wip-us.apache.org/repos/asf/ambari/blob/1afee609/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py b/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
index 92dd634..a199d00 100644
--- a/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
+++ b/ambari-server/src/test/python/stacks/2.2/common/test_conf_select.py
@@ -185,4 +185,16 @@ class TestConfSelect(RMFTestCase):
 
     conf_select.convert_conf_directories_to_symlinks("hadoop", "2.3.0.0-1234", packages["hadoop"])
 
-    self.assertEqual(pprint.pformat(self.env.resource_list), "[]")
\ No newline at end of file
+    self.assertEqual(pprint.pformat(self.env.resource_list), "[]")
+
+
+  def test_restrictions(self):
+
+    Script.config.update({'roleParameters': {'cluster_version_summary': {'services': {'HIVE': {'upgrade': True}}}}})
+
+    restricted = conf_select.get_restricted_packages()
+    self.assertTrue("hive" in restricted)
+    self.assertTrue("hive-hcatalog" in restricted)
+    self.assertTrue("hive2" in restricted)
+    self.assertTrue("tez_hive2" in restricted)
+    self.assertTrue("hadoop" not in restricted)


[20/51] [abbrv] ambari git commit: AMBARI-22369. Remove Auto-Installation of Mysql Connector (ncole)

Posted by nc...@apache.org.
AMBARI-22369. Remove Auto-Installation of Mysql Connector (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: cbce5e87971264819e4e7d62621c5463947fd863
Parents: f74b2f8
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Nov 7 09:00:28 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Tue Nov 7 09:23:03 2017 -0500

----------------------------------------------------------------------
 .../libraries/functions/package_conditions.py             |  6 +-----
 .../common-services/HIVE/0.12.0.2.0/metainfo.xml          |  5 -----
 .../resources/common-services/HIVE/2.1.0.3.0/metainfo.xml | 10 ----------
 .../common-services/OOZIE/4.2.0.2.3/metainfo.xml          |  5 -----
 .../common-services/OOZIE/4.2.0.3.0/metainfo.xml          |  5 -----
 .../common-services/SQOOP/1.4.4.2.0/metainfo.xml          |  5 -----
 .../common-services/SQOOP/1.4.4.3.0/metainfo.xml          | 10 ----------
 .../stacks/BIGTOP/0.8/services/HIVE/metainfo.xml          |  4 ----
 .../stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml         |  4 ----
 .../stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml |  4 ----
 .../HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml       |  4 ----
 .../stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml   |  4 ----
 .../stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml  |  4 ----
 .../resources/stacks/HDP/2.1/services/HIVE/metainfo.xml   |  5 -----
 .../resources/stacks/HDP/2.2/services/HIVE/metainfo.xml   | 10 ----------
 .../resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml  |  5 -----
 .../resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml  | 10 ----------
 .../stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml   |  9 ---------
 .../stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml  |  9 ---------
 .../resources/stacks/HDP/2.3/services/HIVE/metainfo.xml   | 10 ----------
 .../resources/stacks/HDP/2.5/services/HIVE/metainfo.xml   | 10 ----------
 .../resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml  | 10 ----------
 22 files changed, 1 insertion(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
index 5a16061..31e78b9 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
@@ -20,7 +20,7 @@ Ambari Agent
 
 """
 __all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
-           "should_install_mysql", "should_install_mysql_connector", "should_install_ranger_tagsync"]
+           "should_install_mysql", "should_install_ranger_tagsync"]
 
 import os
 from resource_management.libraries.script import Script
@@ -85,10 +85,6 @@ def should_install_mysql():
     return False
   return _has_applicable_local_component(config, "MYSQL_SERVER")
 
-def should_install_mysql_connector():
-  mysql_jdbc_driver_jar = "/usr/share/java/mysql-connector-java.jar"
-  return not os.path.exists(mysql_jdbc_driver_jar)
-
 def should_install_hive_atlas():
   atlas_hosts = default('/clusterHostInfo/atlas_server_hosts', [])
   has_atlas = len(atlas_hosts) > 0

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
index d84a85d..c2c8189 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/metainfo.xml
@@ -276,11 +276,6 @@
             <package>
               <name>webhcat-tar-pig</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
           </packages>
         </osSpecific>
         <osSpecific>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
index db490c9..48dda31 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/metainfo.xml
@@ -369,16 +369,6 @@
 
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
index d818074..fca2bba 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.2.3/metainfo.xml
@@ -123,11 +123,6 @@
               <name>zip</name>
             </package>
             <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-            <package>
               <name>extjs</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
index d351cbe..47b3705 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/metainfo.xml
@@ -126,11 +126,6 @@
               <name>zip</name>
             </package>
             <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-            <package>
               <name>extjs</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
index a7ec1ec..56071ec 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/metainfo.xml
@@ -74,11 +74,6 @@
             <package>
               <name>sqoop</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
           </packages>
         </osSpecific>
       </osSpecifics>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
index 999d93a..e02d9f4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/metainfo.xml
@@ -69,16 +69,6 @@
       </components>
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
index d14ce67..d9ee0a3 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HIVE/metainfo.xml
@@ -233,10 +233,6 @@
             <package>
               <name>postgresql-jdbc</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         <osSpecific>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
index 20c3b32..8382662 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/OOZIE/metainfo.xml
@@ -121,10 +121,6 @@
             <package>
               <name>oozie-client</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
index 633f3a6..ca92e98 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/HIVE/metainfo.xml
@@ -57,10 +57,6 @@
             <package>
               <name>webhcat-tar-pig</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         <osSpecific>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
index 27d4ba4..150cbde 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6.GlusterFS/services/OOZIE/metainfo.xml
@@ -40,10 +40,6 @@
             <package>
               <name>zip</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
index 7bad9fc..7ac6a63 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
@@ -57,10 +57,6 @@
             <package>
               <name>webhcat-tar-pig</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         <osSpecific>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
index a62ef78..82e74ae 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/OOZIE/metainfo.xml
@@ -40,10 +40,6 @@
             <package>
               <name>zip</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
index 28dfb37..f3eaa8c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.1/services/HIVE/metainfo.xml
@@ -55,11 +55,6 @@
             <package>
               <name>webhcat-tar-pig</name>
             </package>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
           </packages>
         </osSpecific>
         <osSpecific>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
index 051cad1..49a4e69 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
@@ -58,16 +58,6 @@
       
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>amazon2015,redhat6,redhat7,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
index cb84a5d..87afb5c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
@@ -65,11 +65,6 @@
               <name>zip</name>
             </package>
             <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-            <package>
               <name>extjs</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
index 884019c..c0e6b3e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
@@ -23,16 +23,6 @@
       <version>1.4.5.2.2</version>
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
index 0e12f09..7340b79 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HIVE/metainfo.xml
@@ -24,15 +24,6 @@
 
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat5,redhat6,suse11</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
index 5238914..5b02eea 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/SQOOP/metainfo.xml
@@ -23,15 +23,6 @@
       <version>1.4.6.2.3</version>
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat5,redhat6,suse11</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
index accbedd..53b8dd0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HIVE/metainfo.xml
@@ -24,16 +24,6 @@
       
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
index f2a1161..fb72d98 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/metainfo.xml
@@ -142,16 +142,6 @@
       </requiredServices>
       <osSpecifics>
         <osSpecific>
-          <osFamily>any</osFamily>
-          <packages>
-            <package>
-              <name>mysql-connector-java</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_mysql_connector</condition>
-            </package>
-          </packages>
-        </osSpecific>
-        <osSpecific>
           <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
           <packages>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/cbce5e87/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
----------------------------------------------------------------------
diff --git a/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml b/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
index 5d1c898..3fb083b 100755
--- a/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
+++ b/contrib/management-packs/odpi-ambari-mpack/src/main/resources/stacks/ODPi/2.0/services/HIVE/metainfo.xml
@@ -307,16 +307,6 @@
     <metricsFileName>metrics.json</metricsFileName>
     <osSpecifics>
         <osSpecific>
-            <osFamily>any</osFamily>
-            <packages>
-                <package>
-                    <name>mysql-connector-java</name>
-                    <condition>should_install_mysql_connector</condition>
-                    <skipUpgrade>true</skipUpgrade>
-                </package>
-            </packages>
-        </osSpecific>
-        <osSpecific>
             <osFamily>redhat7,amazon2015,redhat6,suse11,suse12</osFamily>
             <packages>
                 <package>


[10/51] [abbrv] ambari git commit: AMBARI-22354 Service Action Menu issues. (atkach)

Posted by nc...@apache.org.
AMBARI-22354 Service Action Menu issues. (atkach)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1b020cd98e8aca05097a8a829927e2d0415d480c
Parents: b8f7369
Author: Andrii Tkach <at...@apache.org>
Authored: Fri Nov 3 12:48:55 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Nov 3 12:48:55 2017 +0200

----------------------------------------------------------------------
 .../app/styles/theme/bootstrap-ambari.css       | 35 +++++++++++++++-----
 .../admin/kerberos/step2_controller_test.js     |  2 +-
 .../vendor/scripts/theme/bootstrap-ambari.js    |  7 ----
 3 files changed, 28 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/app/styles/theme/bootstrap-ambari.css
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/theme/bootstrap-ambari.css b/ambari-web/app/styles/theme/bootstrap-ambari.css
index 7d1ad61..e85bb32 100644
--- a/ambari-web/app/styles/theme/bootstrap-ambari.css
+++ b/ambari-web/app/styles/theme/bootstrap-ambari.css
@@ -537,20 +537,27 @@ h2.table-title {
 }
 .wizard .wizard-body .wizard-content {
   background: #ebecf1;
-  padding-top: 25px;
+  padding-top: 15px;
   float: left;
   margin-bottom: -99999px;
   padding-bottom: 99999px;
 }
+.wizard .wizard-body .wizard-content .step-header {
+  font-family: 'Roboto', sans-serif;
+  font-weight: normal;
+  color: #666;
+  font-size: 14px;
+  font-style: normal;
+  line-height: 1;
+  margin-bottom: 5px;
+}
 .wizard .wizard-body .wizard-content .step-title {
   font-family: 'Roboto', sans-serif;
   font-weight: normal;
   font-style: normal;
   line-height: 1;
   color: #333;
-  font-weight: bold;
-  font-size: 18px;
-  color: #666;
+  font-size: 16px;
 }
 .wizard .wizard-body .wizard-content .step-description {
   font-family: 'Roboto', sans-serif;
@@ -558,7 +565,7 @@ h2.table-title {
   font-style: normal;
   line-height: 1;
   color: #333;
-  font-size: 14px;
+  font-size: 12px;
   line-height: 1.4;
   color: #999;
 }
@@ -568,7 +575,7 @@ h2.table-title {
   margin-top: 20px;
 }
 .wizard .wizard-body .wizard-content .panel.panel-default .panel-body {
-  padding: 30px 20px;
+  padding: 10px 20px;
 }
 .wizard .wizard-body .wizard-nav {
   min-height: 550px;
@@ -1042,16 +1049,28 @@ input.radio:checked + label:after {
 }
 .navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a,
 .navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a {
-  color: #666;
+  color: #333;
 }
 .navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a i,
 .navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a i {
-  color: #666;
+  color: #333;
 }
 .navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a:hover,
 .navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a:hover {
   background: #f5f5f5;
 }
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled {
+  color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled i,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled i {
+  color: #666;
+}
+.navigation-bar-container ul.nav.side-nav-menu .more-actions .dropdown-menu > li > a.disabled:hover,
+.navigation-bar-container ul.nav.side-nav-footer .more-actions .dropdown-menu > li > a.disabled:hover {
+  background: #f5f5f5;
+}
 .navigation-bar-container ul.nav.side-nav-menu .menu-item-name,
 .navigation-bar-container ul.nav.side-nav-footer .menu-item-name {
   display: inline-block;

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
index 794fe4a..a9103a8 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
@@ -451,7 +451,7 @@ describe('App.KerberosWizardStep2Controller', function() {
     });
 
     it("ipa type configs", function() {
-      var configs = [{name: 'group'}];
+      var configs = [{name: 'ipa_user_group'}];
       controller.setConfigVisibility('ipa', configs, Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'));
       expect(configs[0].isVisible).to.be.true;
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1b020cd9/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
----------------------------------------------------------------------
diff --git a/ambari-web/vendor/scripts/theme/bootstrap-ambari.js b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
index 5fd713a..6102bc3 100644
--- a/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
+++ b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js
@@ -158,13 +158,6 @@ $(document).ready(function () {
           });
         });
       }
-      $dropdownMenu.on('click', function () {
-        // some action was triggered, should hide this icon
-        var moreIcon = $(this).parent();
-        setTimeout(function () {
-          moreIcon.hide();
-        }, 1000);
-      });
       $navigationContainer.children('.side-nav-menu').scroll(function () {
         $moreActions.removeClass('open');
       });


[09/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)

Posted by nc...@apache.org.
AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b8f7369bf31ee0186db50816206068cf8bc890df
Parents: fe02abf
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Nov 2 18:14:18 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Fri Nov 3 12:39:30 2017 +0200

----------------------------------------------------------------------
 ambari-admin/pom.xml                            |    2 +-
 .../app/assets/fonts/Roboto-Regular-webfont.eot |  Bin 0 -> 79547 bytes
 .../app/assets/fonts/Roboto-Regular-webfont.svg | 7606 ++++++++++++++++++
 .../app/assets/fonts/Roboto-Regular-webfont.ttf |  Bin 0 -> 234464 bytes
 .../assets/fonts/Roboto-Regular-webfont.woff    |  Bin 0 -> 105700 bytes
 .../main/resources/ui/admin-web/app/index.html  |   78 +-
 .../app/scripts/controllers/AppCtrl.js          |  177 +
 .../app/scripts/controllers/NavbarCtrl.js       |  106 -
 .../app/scripts/controllers/SideNavCtrl.js      |   68 +
 .../app/scripts/controllers/mainCtrl.js         |  168 +-
 .../ui/admin-web/app/scripts/i18n.config.js     |   11 +-
 .../ui/admin-web/app/scripts/routes.js          |   69 +-
 .../app/scripts/theme/bootstrap-ambari.js       |  269 +
 .../resources/ui/admin-web/app/styles/main.css  |  433 +-
 .../app/styles/theme/bootstrap-ambari.css       | 1518 ++++
 .../ui/admin-web/app/styles/top-nav.css         |  197 +
 .../ui/admin-web/app/views/groups/list.html     |    4 +-
 .../ui/admin-web/app/views/leftNavbar.html      |  126 -
 .../resources/ui/admin-web/app/views/main.html  |   59 +-
 .../app/views/remoteClusters/list.html          |    3 +-
 .../ui/admin-web/app/views/sideNav.html         |  106 +
 .../admin-web/app/views/stackVersions/list.html |    5 +-
 .../ui/admin-web/app/views/users/list.html      |    4 +-
 .../src/main/resources/ui/admin-web/bower.json  |    2 +-
 .../src/main/resources/ui/admin-web/gulpfile.js |   10 +-
 .../main/resources/ui/admin-web/package.json    |    6 +-
 .../test/unit/controllers/AppCtrl_test.js       |  211 +
 .../test/unit/controllers/mainCtrl_test.js      |  215 -
 .../test/unit/services/Utility_test.js          |    3 +-
 29 files changed, 10334 insertions(+), 1122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-admin/pom.xml b/ambari-admin/pom.xml
index cb82e45..281280a 100644
--- a/ambari-admin/pom.xml
+++ b/ambari-admin/pom.xml
@@ -192,7 +192,7 @@
             <exclude>src/main/resources/ui/admin-web/bower_components/**</exclude>
             <exclude>src/main/resources/ui/admin-web/dist/**</exclude>
             <exclude>src/main/resources/ui/admin-web/node/**</exclude>
-            <exclude>src/main/resources/ui/admin-web/app/assets/data/**</exclude>
+            <exclude>src/main/resources/ui/admin-web/app/assets/**</exclude>
             <exclude>src/main/resources/ui/admin-web/node_modules/**</exclude>
             <exclude>src/main/resources/ui/admin-web/app/bower_components/**</exclude>
             <exclude>src/main/resources/ui/admin-web/test/bower_components/**</exclude>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot
new file mode 100644
index 0000000..d4e185d
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.eot differ


[18/51] [abbrv] ambari git commit: AMBARI-22332 Falcon Service check failed during cluster deploy (dgrinenko)

Posted by nc...@apache.org.
AMBARI-22332 Falcon Service check failed during cluster deploy (dgrinenko)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ec3f1e4dcf4d0e53f10b7f7fe913b1bfdbcab82a
Parents: 976153f
Author: Dmytro Grinenko <ha...@apache.org>
Authored: Tue Nov 7 08:11:09 2017 +0200
Committer: Dmytro Grinenko <ha...@apache.org>
Committed: Tue Nov 7 08:13:08 2017 +0200

----------------------------------------------------------------------
 .../main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ec3f1e4d/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
index 79296c3..1066f6c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/FALCON/metainfo.xml
@@ -30,7 +30,7 @@
               <name>falcon_${stack_version}</name>
             </package>
             <package>
-              <name>atlas-metadata_${stack_version}-hive-plugin</name>
+              <name>atlas-metadata_${stack_version}-falcon-plugin</name>
               <condition>should_install_falcon_atlas_hook</condition>
             </package>
           </packages>
@@ -42,7 +42,7 @@
               <name>falcon-${stack_version}</name>
             </package>
             <package>
-              <name>atlas-metadata-${stack_version}-hive-plugin</name>
+              <name>atlas-metadata-${stack_version}-falcon-plugin</name>
               <condition>should_install_falcon_atlas_hook</condition>
             </package>
           </packages>


[46/51] [abbrv] ambari git commit: AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
deleted file mode 100644
index 2b3e326..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.
- */
-
-import {TestBed, inject} from '@angular/core/testing';
-import {StoreModule} from '@ngrx/store';
-import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
-import {AppStateService, appState} from '@app/services/storage/app-state.service';
-import {ClustersService, clusters} from '@app/services/storage/clusters.service';
-import {ComponentsService, components} from '@app/services/storage/components.service';
-import {HostsService, hosts} from '@app/services/storage/hosts.service';
-import {UtilsService} from '@app/services/utils.service';
-import {HttpClientService} from '@app/services/http-client.service';
-import {ListItem} from '@app/classes/list-item';
-import {Node} from '@app/classes/models/node';
-
-import {FilteringService} from './filtering.service';
-
-describe('FilteringService', () => {
-  beforeEach(() => {
-    const httpClient = {
-      get: () => {
-        return {
-          subscribe: () => {
-          }
-        }
-      }
-    };
-    TestBed.configureTestingModule({
-      imports: [
-        StoreModule.provideStore({
-          appSettings,
-          appState,
-          clusters,
-          components,
-          hosts
-        })
-      ],
-      providers: [
-        FilteringService,
-        AppSettingsService,
-        AppStateService,
-        ClustersService,
-        ComponentsService,
-        HostsService,
-        UtilsService,
-        {
-          provide: HttpClientService,
-          useValue: httpClient
-        }
-      ]
-    });
-  });
-
-  it('should create service', inject([FilteringService], (service: FilteringService) => {
-    expect(service).toBeTruthy();
-  }));
-
-  describe('#getListItemFromString()', () => {
-    it('should convert string to ListItem', inject([FilteringService], (service: FilteringService) => {
-      const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
-      expect(getListItemFromString('customName')).toEqual({
-        label: 'customName',
-        value: 'customName'
-      });
-    }));
-  });
-
-  describe('#getListItemFromNode()', () => {
-    it('should convert Node to ListItem', inject([FilteringService], (service: FilteringService) => {
-      const getListItemFromNode: (node: Node) => ListItem = service['getListItemFromNode'];
-      expect(getListItemFromNode({
-        name: 'customName',
-        value: '1',
-        isParent: true,
-        isRoot: true
-      })).toEqual({
-        label: 'customName (1)',
-        value: 'customName'
-      });
-    }));
-  });
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
deleted file mode 100644
index 85dc408..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * 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.
- */
-
-import {Injectable, Input} from '@angular/core';
-import {FormGroup} from '@angular/forms';
-import {Response} from '@angular/http';
-import {Subject} from 'rxjs/Subject';
-import {Observable} from 'rxjs/Observable';
-import 'rxjs/add/observable/timer';
-import 'rxjs/add/operator/takeUntil';
-import * as moment from 'moment-timezone';
-import {ListItem} from '@app/classes/list-item';
-import {FilterCondition, filters} from '@app/classes/filtering';
-import {Node} from '@app/classes/models/node';
-import {AppSettingsService} from '@app/services/storage/app-settings.service';
-import {ClustersService} from '@app/services/storage/clusters.service';
-import {ComponentsService} from '@app/services/storage/components.service';
-import {HostsService} from '@app/services/storage/hosts.service';
-import {AppStateService} from '@app/services/storage/app-state.service';
-import {HttpClientService} from '@app/services/http-client.service';
-
-@Injectable()
-export class FilteringService {
-
-  constructor(private httpClient: HttpClientService, private appSettings: AppSettingsService, private clustersStorage: ClustersService, private componentsStorage: ComponentsService, private hostsStorage: HostsService, private appState: AppStateService) {
-    this.loadClusters();
-    this.loadComponents();
-    this.loadHosts();
-    appSettings.getParameter('timeZone').subscribe(value => this.timeZone = value || this.defaultTimeZone);
-    clustersStorage.getAll().subscribe((clusters: string[]): void => {
-      this.filters.clusters.options = [...this.filters.clusters.options, ...clusters.map(this.getListItemFromString)];
-    });
-    componentsStorage.getAll().subscribe((components: Node[]): void => {
-     this.filters.components.options = [...this.filters.components.options, ...components.map(this.getListItemFromNode)];
-    });
-    hostsStorage.getAll().subscribe((hosts: Node[]): void => {
-      this.filters.hosts.options = [...this.filters.hosts.options, ...hosts.map(this.getListItemFromNode)];
-    });
-    appState.getParameter('activeFiltersForm').subscribe((form: FormGroup) => this.activeFiltersForm = form);
-  }
-
-  /**
-   * Get instance for dropdown list from string
-   * @param name {string}
-   * @returns {ListItem}
-   */
-  private getListItemFromString(name: string): ListItem {
-    return {
-      label: name,
-      value: name
-    };
-  }
-
-  /**
-   * Get instance for dropdown list from Node object
-   * @param node {Node}
-   * @returns {ListItem}
-   */
-  private getListItemFromNode(node: Node): ListItem {
-    return {
-      label: `${node.name} (${node.value})`,
-      value: node.name
-    };
-  }
-
-  private readonly defaultTimeZone = moment.tz.guess();
-
-  timeZone: string = this.defaultTimeZone;
-
-  /**
-   * A configurable property to indicate the maximum capture time in milliseconds.
-   * @type {number}
-   * @default 600000 (10 minutes)
-   */
-  @Input()
-  maximumCaptureTimeLimit: number = 600000;
-
-  filters: {[key: string]: FilterCondition} = Object.assign({}, filters);
-
-  activeFiltersForm: FormGroup;
-
-  queryParameterNameChange: Subject<any> = new Subject();
-
-  queryParameterAdd: Subject<any> = new Subject();
-
-  private stopTimer: Subject<any> = new Subject();
-
-  private stopAutoRefreshCountdown: Subject<any> = new Subject();
-
-  captureSeconds: number = 0;
-
-  private readonly autoRefreshInterval: number = 30000;
-
-  autoRefreshRemainingSeconds: number = 0;
-
-  private startCaptureTime: number;
-
-  private stopCaptureTime: number;
-
-  startCaptureTimer(): void {
-    this.startCaptureTime = new Date().valueOf();
-    const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
-    Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
-      this.captureSeconds = seconds;
-      if (this.captureSeconds >= maxCaptureTimeInSeconds) {
-        this.stopCaptureTimer();
-      }
-    });
-  }
-
-  stopCaptureTimer(): void {
-    const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
-    this.stopCaptureTime = new Date().valueOf();
-    this.captureSeconds = 0;
-    this.stopTimer.next();
-    this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
-    Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
-      this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
-      if (!this.autoRefreshRemainingSeconds) {
-        this.stopAutoRefreshCountdown.next();
-        this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
-      }
-    });
-  }
-
-  loadClusters(): void {
-    this.httpClient.get('clusters').subscribe((response: Response): void => {
-      const clusterNames = response.json();
-      if (clusterNames) {
-        this.clustersStorage.addInstances(clusterNames);
-      }
-    });
-  }
-
-  loadComponents(): void {
-    this.httpClient.get('components').subscribe((response: Response): void => {
-      const jsonResponse = response.json(),
-        components = jsonResponse && jsonResponse.vNodeList.map((item): Node => Object.assign(item, {
-            value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
-              return currentValue + Number(currentItem.value);
-            }, 0)
-          }));
-      if (components) {
-        this.componentsStorage.addInstances(components);
-      }
-    });
-  }
-
-  loadHosts(): void {
-    this.httpClient.get('hosts').subscribe((response: Response): void => {
-      const jsonResponse = response.json(),
-        hosts = jsonResponse && jsonResponse.vNodeList;
-      if (hosts) {
-        this.hostsStorage.addInstances(hosts);
-      }
-    });
-  }
-
-  setCustomTimeRange(startTime: number, endTime: number): void {
-    this.activeFiltersForm.controls.timeRange.setValue({
-      type: 'CUSTOM',
-      start: moment(startTime),
-      end: moment(endTime)
-    });
-  }
-
-  private getStartTime = (value: any, current: string): string => {
-    let time;
-    if (value) {
-      const endTime = moment(moment(current).valueOf());
-      switch (value.type) {
-        case 'LAST':
-          time = endTime.subtract(value.interval, value.unit);
-          break;
-        case 'CURRENT':
-          time = moment().tz(this.timeZone).startOf(value.unit);
-          break;
-        case 'PAST':
-          time = endTime.startOf(value.unit);
-          break;
-        case 'CUSTOM':
-          time = value.start;
-          break;
-        default:
-          break;
-      }
-    }
-    return time ? time.toISOString() : '';
-  };
-
-  private getEndTime = (value: any): string => {
-    let time;
-    if (value) {
-      switch (value.type) {
-        case 'LAST':
-          time = moment();
-          break;
-        case 'CURRENT':
-          time = moment().tz(this.timeZone).endOf(value.unit);
-          break;
-        case 'PAST':
-          time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
-          break;
-        case 'CUSTOM':
-          time = value.end;
-          break;
-        default:
-          break;
-      }
-    }
-    return time ? time.toISOString() : '';
-  };
-
-  private getQuery(isExclude: boolean): (value: any[]) => string {
-    return (value: any[]): string => {
-      let parameters;
-      if (value && value.length) {
-        parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
-          return {
-            [parameter.name]: parameter.value.replace(/\s/g, '+')
-          };
-        });
-      }
-      return parameters && parameters.length ? JSON.stringify(parameters) : '';
-    }
-  }
-
-  readonly valueGetters = {
-    to: this.getEndTime,
-    from: this.getStartTime,
-    sortType: value => value && value.type,
-    sortBy: value => value && value.key,
-    page: value => value == null ? value : value.toString(),
-    includeQuery: this.getQuery(false),
-    excludeQuery: this.getQuery(true)
-  };
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
index ee0e1e7..47cb25d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts
@@ -31,7 +31,8 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ListItem} from '@app/classes/list-item';
+import {NodeItem} from '@app/classes/models/node-item';
 
 import {LogsContainerService} from './logs-container.service';
 
@@ -79,8 +80,7 @@ describe('LogsContainerService', () => {
         {
           provide: HttpClientService,
           useValue: httpClient
-        },
-        FilteringService
+        }
       ]
     });
   });
@@ -88,4 +88,29 @@ describe('LogsContainerService', () => {
   it('should create service', inject([LogsContainerService], (service: LogsContainerService) => {
     expect(service).toBeTruthy();
   }));
+
+  describe('#getListItemFromString()', () => {
+    it('should convert string to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+      const getListItemFromString: (name: string) => ListItem = service['getListItemFromString'];
+      expect(getListItemFromString('customName')).toEqual({
+        label: 'customName',
+        value: 'customName'
+      });
+    }));
+  });
+
+  describe('#getListItemFromNode()', () => {
+    it('should convert NodeItem to ListItem', inject([LogsContainerService], (service: LogsContainerService) => {
+      const getListItemFromNode: (node: NodeItem) => ListItem = service['getListItemFromNode'];
+      expect(getListItemFromNode({
+        name: 'customName',
+        value: '1',
+        isParent: true,
+        isRoot: true
+      })).toEqual({
+        label: 'customName (1)',
+        value: 'customName'
+      });
+    }));
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
index e187b00..f45887b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts
@@ -17,9 +17,14 @@
  */
 
 import {Injectable} from '@angular/core';
+import {FormGroup, FormControl} from '@angular/forms';
 import {Response} from '@angular/http';
+import {Subject} from 'rxjs/Subject';
+import {Observable} from 'rxjs/Observable';
+import 'rxjs/add/observable/timer';
+import 'rxjs/add/operator/takeUntil';
+import * as moment from 'moment-timezone';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {AuditLogsService} from '@app/services/storage/audit-logs.service';
 import {AuditLogsFieldsService} from '@app/services/storage/audit-logs-fields.service';
 import {ServiceLogsService} from '@app/services/storage/service-logs.service';
@@ -27,30 +32,411 @@ import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-field
 import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
+import {AppSettingsService} from '@app/services/storage/app-settings.service';
 import {TabsService} from '@app/services/storage/tabs.service';
+import {ClustersService} from '@app/services/storage/clusters.service';
+import {ComponentsService} from '@app/services/storage/components.service';
+import {HostsService} from '@app/services/storage/hosts.service';
 import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
+import {FilterCondition, TimeUnitListItem, SortingListItem} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
 import {Tab} from '@app/classes/models/tab';
 import {AuditLogField} from '@app/classes/models/audit-log-field';
 import {ServiceLogField} from '@app/classes/models/service-log-field';
 import {BarGraph} from '@app/classes/models/bar-graph';
+import {NodeItem} from '@app/classes/models/node-item';
 
 @Injectable()
 export class LogsContainerService {
 
-  constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService) {
+  constructor(
+    private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService,
+    private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService,
+    private serviceLogsFieldsStorage: ServiceLogsFieldsService,
+    private serviceLogsHistogramStorage: ServiceLogsHistogramDataService,
+    private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService,
+    private appSettings: AppSettingsService, private tabsStorage: TabsService, private clustersStorage: ClustersService,
+    private componentsStorage: ComponentsService, private hostsStorage: HostsService
+  ) {
+    const formItems = Object.keys(this.filters).reduce((currentObject: any, key: string): {[key: string]: FormControl} => {
+      let formControl = new FormControl(),
+        item = {
+          [key]: formControl
+        };
+      formControl.setValue(this.filters[key].defaultSelection);
+      return Object.assign(currentObject, item);
+    }, {});
+    this.filtersForm = new FormGroup(formItems);
+    this.loadClusters();
+    this.loadComponents();
+    this.loadHosts();
     appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => this.activeLog = value);
-    appState.getParameter('isServiceLogsFileView').subscribe((value: boolean): void => {
-      const activeLog = this.activeLog,
-        filtersForm = this.filtering.activeFiltersForm;
-      if (value && activeLog) {
-        filtersForm.controls.hosts.setValue(activeLog.host_name);
-        filtersForm.controls.components.setValue(activeLog.component_name);
-      }
-      this.isServiceLogsFileView = value;
-    });
+    appState.getParameter('isServiceLogsFileView').subscribe((value: boolean) => this.isServiceLogsFileView = value);
     appState.getParameter('activeLogsType').subscribe((value: string) => this.activeLogsType = value);
+    appSettings.getParameter('timeZone').subscribe((value: string) => this.timeZone = value || this.defaultTimeZone);
+    tabsStorage.mapCollection((tab: Tab): Tab => {
+      let currentAppState = tab.appState || {};
+      const appState = Object.assign({}, currentAppState, {
+        activeFilters: this.getFiltersData(tab.type)
+      });
+      return Object.assign({}, tab, {
+        appState
+      });
+    });
+    appState.getParameter('activeFilters').subscribe((filters: object): void => {
+      this.filtersFormChange.next();
+      if (filters) {
+        const controls = this.filtersForm.controls;
+        Object.keys(controls).forEach((key: string): void => {
+          controls[key].setValue(filters.hasOwnProperty(key) ? filters[key] : null);
+        });
+      }
+      this.loadLogs();
+      this.filtersForm.valueChanges.takeUntil(this.filtersFormChange).subscribe((value: object): void => {
+        this.tabsStorage.mapCollection((tab: Tab): Tab => {
+          const currentAppState = tab.appState || {},
+            appState = Object.assign({}, currentAppState, tab.isActive ? {
+              activeFilters: value
+            } : null);
+          return Object.assign({}, tab, {
+            appState
+          });
+        });
+        this.loadLogs();
+      });
+    });
   }
 
+  private readonly paginationOptions: string[] = ['10', '25', '50', '100'];
+
+  filters: {[key: string]: FilterCondition} = {
+    clusters: {
+      label: 'filter.clusters',
+      options: [],
+      defaultSelection: []
+    },
+    timeRange: {
+      options: [
+        [
+          {
+            label: 'filter.timeRange.7d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 7
+            }
+          },
+          {
+            label: 'filter.timeRange.30d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 30
+            }
+          },
+          {
+            label: 'filter.timeRange.60d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 60
+            }
+          },
+          {
+            label: 'filter.timeRange.90d',
+            value: {
+              type: 'LAST',
+              unit: 'd',
+              interval: 90
+            }
+          },
+          {
+            label: 'filter.timeRange.6m',
+            value: {
+              type: 'LAST',
+              unit: 'M',
+              interval: 6
+            }
+          },
+          {
+            label: 'filter.timeRange.1y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 1
+            }
+          },
+          {
+            label: 'filter.timeRange.2y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 2
+            }
+          },
+          {
+            label: 'filter.timeRange.5y',
+            value: {
+              type: 'LAST',
+              unit: 'y',
+              interval: 5
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.yesterday',
+            value: {
+              type: 'PAST',
+              unit: 'd'
+            }
+          },
+          // TODO implement time range calculation
+          /*
+           {
+           label: 'filter.timeRange.beforeYesterday',
+           value: {
+           type: 'PAST',
+           unit: 'd'
+           }
+           },
+           {
+           label: 'filter.timeRange.thisDayLastWeek',
+           value: {
+           type: 'PAST',
+           unit: 'd'
+           }
+           },
+           */
+          {
+            label: 'filter.timeRange.previousWeek',
+            value: {
+              type: 'PAST',
+              unit: 'w'
+            }
+          },
+          {
+            label: 'filter.timeRange.previousMonth',
+            value: {
+              type: 'PAST',
+              unit: 'M'
+            }
+          },
+          {
+            label: 'filter.timeRange.previousYear',
+            value: {
+              type: 'PAST',
+              unit: 'y'
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.today',
+            value: {
+              type: 'CURRENT',
+              unit: 'd'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisWeek',
+            value: {
+              type: 'CURRENT',
+              unit: 'w'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisMonth',
+            value: {
+              type: 'CURRENT',
+              unit: 'M'
+            }
+          },
+          {
+            label: 'filter.timeRange.thisYear',
+            value: {
+              type: 'CURRENT',
+              unit: 'y'
+            }
+          }
+        ],
+        [
+          {
+            label: 'filter.timeRange.5min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 5
+            }
+          },
+          {
+            label: 'filter.timeRange.15min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 15
+            }
+          },
+          {
+            label: 'filter.timeRange.30min',
+            value: {
+              type: 'LAST',
+              unit: 'm',
+              interval: 30
+            }
+          },
+          {
+            label: 'filter.timeRange.1hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 1
+            }
+          },
+          {
+            label: 'filter.timeRange.3hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 3
+            }
+          },
+          {
+            label: 'filter.timeRange.6hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 6
+            }
+          },
+          {
+            label: 'filter.timeRange.12hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 12
+            }
+          },
+          {
+            label: 'filter.timeRange.24hr',
+            value: {
+              type: 'LAST',
+              unit: 'h',
+              interval: 24
+            }
+          },
+        ]
+      ],
+      defaultSelection: {
+        value: {
+          type: 'LAST',
+          unit: 'h',
+          interval: 1
+        },
+        label: 'filter.timeRange.1hr'
+      }
+    },
+    components: {
+      label: 'filter.components',
+      iconClass: 'fa fa-cubes',
+      options: [],
+      defaultSelection: []
+    },
+    levels: {
+      label: 'filter.levels',
+      iconClass: 'fa fa-sort-amount-asc',
+      options: [
+        {
+          label: 'levels.fatal',
+          value: 'FATAL'
+        },
+        {
+          label: 'levels.error',
+          value: 'ERROR'
+        },
+        {
+          label: 'levels.warn',
+          value: 'WARN'
+        },
+        {
+          label: 'levels.info',
+          value: 'INFO'
+        },
+        {
+          label: 'levels.debug',
+          value: 'DEBUG'
+        },
+        {
+          label: 'levels.trace',
+          value: 'TRACE'
+        },
+        {
+          label: 'levels.unknown',
+          value: 'UNKNOWN'
+        }
+      ],
+      defaultSelection: []
+    },
+    hosts: {
+      label: 'filter.hosts',
+      iconClass: 'fa fa-server',
+      options: [],
+      defaultSelection: []
+    },
+    sorting: {
+      label: 'sorting.title',
+      options: [
+        {
+          label: 'sorting.time.asc',
+          value: {
+            key: 'logtime',
+            type: 'asc'
+          }
+        },
+        {
+          label: 'sorting.time.desc',
+          value: {
+            key: 'logtime',
+            type: 'desc'
+          }
+        }
+      ],
+      defaultSelection: [
+        {
+          label: 'sorting.time.desc',
+          value: {
+            key: 'logtime',
+            type: 'desc'
+          }
+        }
+      ]
+    },
+    pageSize: {
+      label: 'pagination.title',
+      options: this.paginationOptions.map((option: string): ListItem => {
+        return {
+          label: option,
+          value: option
+        }
+      }),
+      defaultSelection: [
+        {
+          label: '10',
+          value: '10'
+        }
+      ]
+    },
+    page: {
+      defaultSelection: 0
+    },
+    query: {}
+  };
+
+  readonly filtersFormItemsMap: {[key: string]: string[]} = {
+    serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
+    auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
+  };
+
   readonly colors = {
     WARN: '#FF8916',
     ERROR: '#E81D1D',
@@ -93,14 +479,71 @@ export class LogsContainerService {
     }
   };
 
+  private readonly defaultTimeZone = moment.tz.guess();
+
+  timeZone: string = this.defaultTimeZone;
+
   totalCount: number = 0;
 
+  /**
+   * A configurable property to indicate the maximum capture time in milliseconds.
+   * @type {number}
+   * @default 600000 (10 minutes)
+   */
+  private readonly maximumCaptureTimeLimit: number = 600000;
+
   isServiceLogsFileView: boolean = false;
 
+  filtersForm: FormGroup;
+
   activeLog: ActiveServiceLogEntry | null = null;
 
   activeLogsType: string;
 
+  private filtersFormChange: Subject<any> = new Subject();
+
+  /**
+   * Get instance for dropdown list from string
+   * @param name {string}
+   * @returns {ListItem}
+   */
+  private getListItemFromString(name: string): ListItem {
+    return {
+      label: name,
+      value: name
+    };
+  }
+
+  /**
+   * Get instance for dropdown list from NodeItem object
+   * @param node {NodeItem}
+   * @returns {ListItem}
+   */
+  private getListItemFromNode(node: NodeItem): ListItem {
+    return {
+      label: `${node.name} (${node.value})`,
+      value: node.name
+    };
+  }
+
+  queryParameterNameChange: Subject<any> = new Subject();
+
+  queryParameterAdd: Subject<any> = new Subject();
+
+  private stopTimer: Subject<any> = new Subject();
+
+  private stopAutoRefreshCountdown: Subject<any> = new Subject();
+
+  captureSeconds: number = 0;
+
+  private readonly autoRefreshInterval: number = 30000;
+
+  autoRefreshRemainingSeconds: number = 0;
+
+  private startCaptureTime: number;
+
+  private stopCaptureTime: number;
+
   loadLogs = (logsType: string = this.activeLogsType): void => {
     this.httpClient.get(logsType, this.getParams('listFilters')).subscribe((response: Response): void => {
       const jsonResponse = response.json(),
@@ -128,7 +571,7 @@ export class LogsContainerService {
         }
       });
     }
-  }
+  };
 
   loadLogContext(id: string, hostName: string, componentName: string, scrollType: 'before' | 'after' | '' = ''): void {
     const params = {
@@ -161,22 +604,18 @@ export class LogsContainerService {
     });
   }
 
-  private getParams(filtersMapName: string): any {
+  private getParams(filtersMapName: string): {[key: string]: string} {
     let params = {};
     Object.keys(this[filtersMapName]).forEach((key: string): void => {
-      const inputValue = this.filtering.activeFiltersForm.getRawValue()[key],
+      const inputValue = this.filtersForm.getRawValue()[key],
         paramNames = this[filtersMapName][key];
-      paramNames.forEach(paramName => {
+      paramNames.forEach((paramName: string): void => {
         let value;
-        const valueGetter = this.filtering.valueGetters[paramName];
-        if (valueGetter) {
-          if (paramName === 'from') {
-            value = valueGetter(inputValue, params['to']);
-          } else {
-            value = valueGetter(inputValue);
-          }
+        const valueGetter = this.valueGetters[paramName] || this.defaultValueGetter;
+        if (paramName === 'from') {
+          value = valueGetter(inputValue, params['to']);
         } else {
-          value = inputValue;
+          value = valueGetter(inputValue);
         }
         if (value != null && value !== '') {
           params[paramName] = value;
@@ -222,12 +661,197 @@ export class LogsContainerService {
     return Object.keys(keysObject).map((key: string): {fieldClass} => new fieldClass(key));
   }
 
+  private getStartTime = (selection: TimeUnitListItem, current: string): string => {
+    let time;
+    const value = selection && selection.value;
+    if (value) {
+      const endTime = moment(moment(current).valueOf());
+      switch (value.type) {
+        case 'LAST':
+          time = endTime.subtract(value.interval, value.unit);
+          break;
+        case 'CURRENT':
+          time = moment().tz(this.timeZone).startOf(value.unit);
+          break;
+        case 'PAST':
+          time = endTime.startOf(value.unit);
+          break;
+        case 'CUSTOM':
+          time = value.start;
+          break;
+        default:
+          break;
+      }
+    }
+    return time ? time.toISOString() : '';
+  };
+
+  private getEndTime = (selection: TimeUnitListItem): string => {
+    let time;
+    const value = selection && selection.value;
+    if (value) {
+      switch (value.type) {
+        case 'LAST':
+          time = moment();
+          break;
+        case 'CURRENT':
+          time = moment().tz(this.timeZone).endOf(value.unit);
+          break;
+        case 'PAST':
+          time = moment().tz(this.timeZone).startOf(value.unit).millisecond(-1);
+          break;
+        case 'CUSTOM':
+          time = value.end;
+          break;
+        default:
+          break;
+      }
+    }
+    return time ? time.toISOString() : '';
+  };
+
+  private getQuery(isExclude: boolean): (value: any[]) => string {
+    return (value: any[]): string => {
+      let parameters;
+      if (value && value.length) {
+        parameters = value.filter(item => item.isExclude === isExclude).map(parameter => {
+          return {
+            [parameter.name]: parameter.value.replace(/\s/g, '+')
+          };
+        });
+      }
+      return parameters && parameters.length ? JSON.stringify(parameters) : '';
+    }
+  }
+
+  private getSortType(selection: SortingListItem[] = []): 'asc' | 'desc' {
+    return selection[0] && selection[0].value ? selection[0].value.type : 'desc';
+  }
+
+  private getSortKey(selection: SortingListItem[] = []): string {
+    return selection[0] && selection[0].value ? selection[0].value.key : '';
+  }
+
+  private getPage(value: number | undefined): string | undefined {
+    return typeof value === 'undefined' ? value : value.toString();
+  }
+
+  private defaultValueGetter(selection: ListItem | ListItem[] | null): string {
+    if (Array.isArray(selection)) {
+      return selection.map((item: ListItem): any => item.value).join(',');
+    } else if (selection) {
+      return selection.value;
+    } else {
+      return '';
+    }
+  }
+
+  private readonly valueGetters = {
+    to: this.getEndTime,
+    from: this.getStartTime,
+    sortType: this.getSortType,
+    sortBy: this.getSortKey,
+    page: this.getPage,
+    includeQuery: this.getQuery(false),
+    excludeQuery: this.getQuery(true)
+  };
+
   switchTab(activeTab: Tab): void {
+    this.tabsStorage.mapCollection((tab: Tab): Tab => {
+      return Object.assign({}, tab, {
+        isActive: tab.id === activeTab.id
+      });
+    });
     this.appState.setParameters(activeTab.appState);
-    this.tabsStorage.mapCollection((tab: Tab): Tab => Object.assign({}, tab, {
-      isActive: tab.id === activeTab.id
-    }));
-    this.loadLogs();
+  }
+
+  startCaptureTimer(): void {
+    this.startCaptureTime = new Date().valueOf();
+    const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000;
+    Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => {
+      this.captureSeconds = seconds;
+      if (this.captureSeconds >= maxCaptureTimeInSeconds) {
+        this.stopCaptureTimer();
+      }
+    });
+  }
+
+  stopCaptureTimer(): void {
+    const autoRefreshIntervalSeconds = this.autoRefreshInterval / 1000;
+    this.stopCaptureTime = new Date().valueOf();
+    this.captureSeconds = 0;
+    this.stopTimer.next();
+    this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+    Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => {
+      this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds;
+      if (!this.autoRefreshRemainingSeconds) {
+        this.stopAutoRefreshCountdown.next();
+        this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime);
+      }
+    });
+  }
+
+  loadClusters(): Observable<Response> {
+    const request = this.httpClient.get('clusters');
+    request.subscribe((response: Response): void => {
+      const clusterNames = response.json();
+      if (clusterNames) {
+        this.filters.clusters.options.push(...clusterNames.map(this.getListItemFromString));
+        this.clustersStorage.addInstances(clusterNames);
+      }
+    });
+    return request;
+  }
+
+  loadComponents(): Observable<Response> {
+    const request = this.httpClient.get('components');
+    request.subscribe((response: Response): void => {
+      const jsonResponse = response.json(),
+        components = jsonResponse && jsonResponse.vNodeList.map((item): NodeItem => Object.assign(item, {
+            value: item.logLevelCount.reduce((currentValue: number, currentItem): number => {
+              return currentValue + Number(currentItem.value);
+            }, 0)
+          }));
+      if (components) {
+        this.filters.components.options.push(...components.map(this.getListItemFromNode));
+        this.componentsStorage.addInstances(components);
+      }
+    });
+    return request;
+  }
+
+  loadHosts(): Observable<Response> {
+    const request = this.httpClient.get('hosts');
+    request.subscribe((response: Response): void => {
+      const jsonResponse = response.json(),
+        hosts = jsonResponse && jsonResponse.vNodeList;
+      if (hosts) {
+        this.filters.hosts.options.push(...hosts.map(this.getListItemFromNode));
+        this.hostsStorage.addInstances(hosts);
+      }
+    });
+    return request;
+  }
+
+  setCustomTimeRange(startTime: number, endTime: number): void {
+    this.filtersForm.controls.timeRange.setValue({
+      label: 'filter.timeRange.custom',
+      value: {
+        type: 'CUSTOM',
+        start: moment(startTime),
+        end: moment(endTime)
+      }
+    });
+  }
+
+  getFiltersData(listType: string): object {
+    const itemsList = this.filtersFormItemsMap[listType],
+      keys = Object.keys(this.filters).filter((key: string): boolean => itemsList.indexOf(key) > -1);
+    return keys.reduce((currentObject: object, key: string): object => {
+      return Object.assign(currentObject, {
+        [key]: this.filters[key].defaultSelection
+      });
+    }, {});
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
index a4a0cf8..23d3726 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.spec.ts
@@ -31,56 +31,273 @@ describe('UtilsService', () => {
     expect(service).toBeTruthy();
   }));
 
-  describe('#updateMultiSelectValue()', () => {
+  describe('#isEqual()', () => {
     const cases = [
       {
-        currentValue: '',
-        value: 'v0',
-        isChecked: true,
-        result: 'v0',
-        title: 'check; no checked items before'
+        valueA: 1,
+        valueB: 1,
+        result: true,
+        title: 'same numbers'
       },
       {
-        currentValue: 'v1,v2',
-        value: 'v3',
-        isChecked: true,
-        result: 'v1,v2,v3',
-        title: 'check'
+        valueA: 1,
+        valueB: 2,
+        result: false,
+        title: 'different numbers'
       },
       {
-        currentValue: 'v4,v5',
-        value: 'v4',
-        isChecked: false,
-        result: 'v5',
-        title: 'uncheck'
+        valueA: 'a',
+        valueB: 'a',
+        result: true,
+        title: 'same strings'
       },
       {
-        currentValue: 'v6,v7',
-        value: 'v6',
-        isChecked: true,
-        result: 'v6,v7',
-        title: 'avoid repeating check action'
+        valueA: 'a',
+        valueB: 'b',
+        result: false,
+        title: 'different strings'
       },
       {
-        currentValue: 'v8,v9',
-        value: 'v10',
-        isChecked: false,
-        result: 'v8,v9',
-        title: 'avoid repeating uncheck action'
+        valueA: '1',
+        valueB: 1,
+        result: false,
+        title: 'different types'
       },
       {
-        currentValue: 'v11',
-        value: 'v11',
-        isChecked: false,
-        result: '',
-        title: 'uncheck last item'
+        valueA: true,
+        valueB: true,
+        result: true,
+        title: 'same booleans'
+      },
+      {
+        valueA: false,
+        valueB: true,
+        result: false,
+        title: 'different booleans'
+      },
+      {
+        valueA: {},
+        valueB: {},
+        result: true,
+        title: 'empty objects'
+      },
+      {
+        valueA: {
+          p0: 'v0'
+        },
+        valueB: {
+          p0: 'v0'
+        },
+        result: true,
+        title: 'same objects'
+      },
+      {
+        valueA: {
+          p0: 'v0'
+        },
+        valueB: {
+          p0: 'v1'
+        },
+        result: false,
+        title: 'different objects'
+      },
+      {
+        valueA: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        valueB: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        result: true,
+        title: 'same objects in depth'
+      },
+      {
+        valueA: {
+          p0: {
+            p1: 'v1'
+          }
+        },
+        valueB: {
+          p0: {
+            p1: 'v2'
+          }
+        },
+        result: false,
+        title: 'different objects in depth'
+      },
+      {
+        valueA: [],
+        valueB: [],
+        result: true,
+        title: 'empty arrays'
+      },
+      {
+        valueA: [1, 'a'],
+        valueB: [1, 'a'],
+        result: true,
+        title: 'same arrays'
+      },
+      {
+        valueA: [1, 'a'],
+        valueB: [1, 'b'],
+        result: false,
+        title: 'different arrays'
+      },
+      {
+        valueA: [1, 1],
+        valueB: [1, 1, 1],
+        result: false,
+        title: 'arrays of different length'
+      },
+      {
+        valueA: [{}],
+        valueB: [{}],
+        result: true,
+        title: 'arrays of empty objects'
+      },
+      {
+        valueA: [
+          {
+            p0: 'v0'
+          }
+        ],
+        valueB: [
+          {
+            p0: 'v0'
+          }
+        ],
+        result: true,
+        title: 'arrays of same objects'
+      },
+      {
+        valueA: [
+          {
+            p0: 'v0'
+          }
+        ],
+        valueB: [
+          {
+            p0: 'v1'
+          }
+        ],
+        result: false,
+        title: 'arrays of different objects'
+      },
+      {
+        valueA: function() {},
+        valueB: function() {},
+        result: true,
+        title: 'same functions'
+      },
+      {
+        valueA: function(a) {
+          return a;
+        },
+        valueB: function(b) {
+          return !b;
+        },
+        result: false,
+        title: 'different functions'
+      },
+      {
+        valueA: new Date(1),
+        valueB: new Date(1),
+        result: true,
+        title: 'same dates'
+      },
+      {
+        valueA: new Date(1),
+        valueB: new Date(2),
+        result: false,
+        title: 'different dates'
+      },
+      {
+        valueA: new RegExp('a'),
+        valueB: new RegExp('a'),
+        result: true,
+        title: 'same regexps'
+      },
+      {
+        valueA: new RegExp('a', 'i'),
+        valueB: new RegExp('a', 'g'),
+        result: false,
+        title: 'same regexps with different flags'
+      },
+      {
+        valueA: new RegExp('a'),
+        valueB: new RegExp('b'),
+        result: false,
+        title: 'different regexps'
+      },
+      {
+        valueA: new Number(1),
+        valueB: new Number(1),
+        result: true,
+        title: 'same number objects'
+      },
+      {
+        valueA: new Number(1),
+        valueB: new Number(2),
+        result: false,
+        title: 'different number objects'
+      },
+      {
+        valueA: new String('a'),
+        valueB: new String('a'),
+        result: true,
+        title: 'same string objects'
+      },
+      {
+        valueA: new String('a'),
+        valueB: new String('b'),
+        result: false,
+        title: 'different string objects'
+      },
+      {
+        valueA: new Boolean(true),
+        valueB: new Boolean(true),
+        result: true,
+        title: 'same boolean objects'
+      },
+      {
+        valueA: new Boolean(true),
+        valueB: new Boolean(false),
+        result: false,
+        title: 'different boolean objects'
+      },
+      {
+        valueA: null,
+        valueB: null,
+        result: true,
+        title: 'null values'
+      },
+      {
+        valueA: undefined,
+        valueB: undefined,
+        result: true,
+        title: 'undefined values'
+      },
+      {
+        valueA: undefined,
+        valueB: null,
+        result: false,
+        title: 'undefined vs null'
       }
     ];
 
     cases.forEach(test => {
-      it(test.title, inject([UtilsService], (service: UtilsService) => {
-        expect(service.updateMultiSelectValue(test.currentValue, test.value, test.isChecked)).toEqual(test.result);
-      }));
+      describe(test.title, () => {
+        it('equality', inject([UtilsService], (service: UtilsService) => {
+          expect(service.isEqual(test.valueA, test.valueB)).toEqual(test.result);
+        }));
+        it('symmetry', inject([UtilsService], (service: UtilsService) => {
+          expect(service.isEqual(test.valueA, test.valueB)).toEqual(service.isEqual(test.valueB, test.valueA));
+        }));
+      });
     });
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
index 3448dd4..175b585 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/utils.service.ts
@@ -22,27 +22,56 @@ import * as moment from 'moment-timezone';
 @Injectable()
 export class UtilsService {
 
-  valueHasChanged(currentValue: any, newValue: any): boolean {
-    if (newValue == null) {
+  /**
+   * Comparison of two instances of any data type be value instead of reference
+   * @param valueA
+   * @param valueB
+   * @returns {boolean}
+   */
+  isEqual = (valueA: any, valueB: any): boolean => {
+    if (valueA === valueB) {
+      return true;
+    }
+    if (valueA instanceof Date && valueB instanceof Date) {
+      return valueA.valueOf() === valueB.valueOf();
+    }
+    if ((typeof valueA === 'function' && typeof valueB === 'function') ||
+      (valueA instanceof RegExp && valueB instanceof RegExp) ||
+      (valueA instanceof String && valueB instanceof String) ||
+      (valueA instanceof Number && valueB instanceof Number) ||
+      (valueA instanceof Boolean && valueB instanceof Boolean)) {
+      return valueA.toString() === valueB.toString();
+    }
+    if (!(valueA instanceof Object) || !(valueB instanceof Object)) {
       return false;
     }
-    if (typeof newValue === 'object') {
-      return JSON.stringify(currentValue) !== JSON.stringify(newValue);
-    } else {
-      return currentValue !== newValue;
+    if (valueA.constructor !== valueB.constructor) {
+      return false;
     }
-  }
-
-  updateMultiSelectValue(currentValue: string, value: string, isChecked: boolean): string {
-    let valuesArray = currentValue ? currentValue.split(',') : [],
-      valuePosition = valuesArray.indexOf(value);
-    if (isChecked && valuePosition === -1) {
-      valuesArray.push(value);
-    } else if (!isChecked && valuePosition > -1) {
-      valuesArray.splice(valuePosition, 1);
-    }
-    return valuesArray.join(',');
-  }
+    if (valueA.isPrototypeOf(valueB) || valueB.isPrototypeOf(valueA)) {
+      return false;
+    }
+    for (const key in valueA) {
+      if (!valueA.hasOwnProperty(key)) {
+        continue;
+      }
+      if (!valueB.hasOwnProperty(key)) {
+        return false;
+      }
+      if (valueA[key] === valueB[key]) {
+        continue;
+      }
+      if (typeof valueA[key] !== 'object' || !this.isEqual(valueA[key], valueB[key])) {
+        return false;
+      }
+    }
+    for (const key in valueB) {
+      if (valueB.hasOwnProperty(key) && !valueA.hasOwnProperty(key)) {
+        return false;
+      }
+    }
+    return true;
+  };
 
   isEnterPressed(event: KeyboardEvent): boolean {
     return event.keyCode === 13;


[29/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC integration [addendum - fix unit tests] (rlevas)

Posted by nc...@apache.org.
AMBARI-22293.  Improve KDC integration [addendum - fix unit tests] (rlevas)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 08d382652052172aeb15082a919a18666de93eb7
Parents: 0f67d1c
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Nov 8 12:26:00 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Nov 8 12:26:00 2017 -0500

----------------------------------------------------------------------
 .../KDCKerberosOperationHandlerTest.java        | 22 +++++++++++++++++---
 .../MITKerberosOperationHandlerTest.java        |  6 +++---
 2 files changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/08d38265/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
index 271c787..095b92a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
@@ -19,7 +19,9 @@
 package org.apache.ambari.server.serveraction.kerberos;
 
 import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.getCurrentArguments;
 
 import java.lang.reflect.Method;
 import java.util.Map;
@@ -27,6 +29,7 @@ import java.util.Map;
 import org.apache.ambari.server.utils.ShellCommandUtil;
 import org.apache.commons.lang.StringUtils;
 import org.easymock.EasyMock;
+import org.easymock.IAnswer;
 import org.easymock.IArgumentMatcher;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -37,9 +40,12 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
 
   static Method methodExecuteCommand;
 
+  static Method methodGetExecutable;
+
   @BeforeClass
   public static void beforeKDCKerberosOperationHandlerTest() throws Exception {
     methodExecuteCommand = KDCKerberosOperationHandler.class.getDeclaredMethod("executeCommand", String[].class, Map.class, ShellCommandUtil.InteractiveHandler.class);
+    methodGetExecutable = KerberosOperationHandler.class.getDeclaredMethod("getExecutable", String.class);
   }
 
   @Test
@@ -66,7 +72,17 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
 
   @Override
   protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
-    return createMockedHandler(methodExecuteCommand);
+    KDCKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand, methodGetExecutable);
+
+    expect(handler.getExecutable(anyString()))
+        .andAnswer(new IAnswer<String>() {
+          @Override
+          public String answer() throws Throwable {
+            Object[] args = getCurrentArguments();
+            return args[0].toString();
+          }
+        }).anyTimes();
+    return handler;
   }
 
   @Override
@@ -74,7 +90,7 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
     ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
     expect(result.isSuccessful()).andReturn(true);
 
-    expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+    expect(handler.executeCommand(arrayContains("kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
         .andReturn(result)
         .anyTimes();
   }
@@ -87,7 +103,7 @@ abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationH
     expect(result.getStdout()).andReturn("STDOUT data").once();
     expect(result.getStderr()).andReturn("STDERR data").once();
 
-    expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+    expect(handler.executeCommand(arrayContains("kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
         .andReturn(result)
         .anyTimes();
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/08d38265/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index 848d479..f94adbe 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -275,7 +275,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
         .andReturn("Authenticating as principal admin/admin with password.")
         .anyTimes();
 
-    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+    expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "add_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
         .andReturn(result)
         .anyTimes();
   }
@@ -292,7 +292,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
         .andReturn("Authenticating as principal admin/admin with password.")
         .anyTimes();
 
-    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+    expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
         .andReturn(result)
         .anyTimes();
   }
@@ -329,7 +329,7 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
             "Policy: [none]", (service) ? "service/host" : "user"))
         .anyTimes();
 
-    expect(handler.executeCommand(arrayContains(new String[]{"/usr/sbin/kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+    expect(handler.executeCommand(arrayContains(new String[]{"kadmin", "get_principal"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
         .andReturn(result)
         .anyTimes();
   }


[26/51] [abbrv] ambari git commit: AMBARI-22372. DLM install failed on an unsecure upgraded cluster, due to missing configs. (Jaimin via Ishan)

Posted by nc...@apache.org.
AMBARI-22372. DLM install failed on an unsecure upgraded cluster, due to missing configs. (Jaimin via Ishan)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b8004df033be9b7ace43bf2d28820cf93e8bc4db
Parents: dd0421a
Author: Ishan Bhatt <is...@gmail.com>
Authored: Tue Nov 7 10:56:05 2017 -0800
Committer: Ishan Bhatt <is...@gmail.com>
Committed: Tue Nov 7 10:56:05 2017 -0800

----------------------------------------------------------------------
 .../HIVE/0.12.0.2.0/configuration/hive-site.xml | 38 ++++++++++++++++++++
 1 file changed, 38 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b8004df0/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
index 762530b..5520c10 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/configuration/hive-site.xml
@@ -480,6 +480,12 @@ limitations under the License.
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>beacon-env</type>
+        <name>set_hive_configs</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
   <property>
@@ -489,6 +495,12 @@ limitations under the License.
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>beacon-env</type>
+        <name>set_hive_configs</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
   <property>
@@ -498,6 +510,12 @@ limitations under the License.
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>beacon-env</type>
+        <name>set_hive_configs</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
   <property>
@@ -507,6 +525,16 @@ limitations under the License.
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>beacon-env</type>
+        <name>set_hive_configs</name>
+      </property>
+      <property>
+        <type>hive-site</type>
+        <name>hive.metastore.warehouse.dir</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
   <property>
@@ -516,6 +544,16 @@ limitations under the License.
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>beacon-env</type>
+        <name>set_hive_configs</name>
+      </property>
+      <property>
+        <type>hive-site</type>
+        <name>hive.metastore.warehouse.dir</name>
+      </property>
+    </depends-on>
     <on-ambari-upgrade add="false"/>
   </property>
 </configuration>


[19/51] [abbrv] ambari git commit: AMBARI-22374 Log Search UI: button with caret doesn't toggle dropdown is some cases. (Istvan Tobias via ababiichuk)

Posted by nc...@apache.org.
AMBARI-22374 Log Search UI: button with caret doesn't toggle dropdown is some cases. (Istvan Tobias via ababiichuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f74b2f873b147e7c5639e2a342fc0627b8335f47
Parents: ec3f1e4
Author: Istvan Tobias <to...@gmail.com>
Authored: Tue Nov 7 15:27:38 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Nov 7 15:27:38 2017 +0200

----------------------------------------------------------------------
 .../menu-button/menu-button.component.html      |  17 +--
 .../menu-button/menu-button.component.less      |  22 ++-
 .../menu-button/menu-button.component.ts        | 144 ++++++++++++++++---
 3 files changed, 154 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
index ca70927..5e2b15f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.html
@@ -15,14 +15,15 @@
   limitations under the License.
 -->
 
-<div #dropdown [ngClass]="{'dropdown': hasSubItems, 'text-center': true}">
-  <a [ngClass]="iconClass + ' icon'" (mousedown)="onMouseDown($event)" (mouseup)="onMouseUp($event)"
-     (click)="$event.stopPropagation()"></a>
-  <a #dropdownToggle class="dropdown-toggle caret" data-toggle="dropdown" *ngIf="hasCaret"></a>
-  <br>
-  <a *ngIf="label" (mousedown)="onMouseDown($event)" [ngClass]="labelClass" (mouseup)="onMouseUp($event)"
-     (click)="$event.stopPropagation()">{{label}}</a>
-  <ul data-component="dropdown-list" *ngIf="hasSubItems" [items]="subItems" (selectedItemChange)="updateValue($event)"
+<div #dropdown [ngClass]="{'dropdown': hasSubItems, 'text-center': true, 'open': dropdownIsOpen}">
+  <a class="dropdown-toggle" [ngClass]="(labelClass || '') + (hasCaret ? ' has-caret' : '')"
+    (click)="onMouseClick($event)"
+    (mousedown)="onMouseDown($event)">
+    <i *ngIf="iconClass" [ngClass]="['icon', iconClass]"></i>
+    <i *ngIf="hasCaret" [ngClass]="['fa ', caretClass ]"></i>
+    <span *ngIf="label" class="menu-button-label">{{label}}</span>
+  </a>
+  <ul data-component="dropdown-list" *ngIf="hasSubItems" [items]="subItems" (selectedItemChange)="onDropdownItemChange($event)"
       [isMultipleChoice]="isMultipleChoice" [additionalLabelComponentSetter]="additionalLabelComponentSetter"
       [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"></ul>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
index 615db24..0207561 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.less
@@ -21,14 +21,26 @@
   cursor: pointer;
   display: inline-block;
   position: relative;
-  a:hover, a:focus {
+  a {
+    text-align: center;
     text-decoration: none;
+    i {
+      color: @link-color;
+      display: inline-block;
+      position: relative;
+      &.fa-caret-down {
+        padding: 0 .25em;
+      }
+    }
+    .menu-button-label {
+      display: block;
+    }
   }
-
-  .icon {
-    padding: @icon-padding;
+  a:hover, a:focus {
+    i {
+      color: @link-hover-color;
+    }
   }
-
   .unstyled-link {
     color: inherit;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f74b2f87/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
index 0aa7c7e..5932e1b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
@@ -19,7 +19,6 @@
 import {Component, Input, ViewChild, ElementRef} from '@angular/core';
 import {ListItem} from '@app/classes/list-item';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import * as $ from 'jquery';
 
 @Component({
   selector: 'menu-button',
@@ -64,6 +63,37 @@ export class MenuButtonComponent {
   @Input()
   badge: string;
 
+  @Input()
+  caretClass: string = 'fa-caret-down';
+
+  /**
+   * The minimum time to handle a mousedown as a longclick. Default is 500 ms (0.5sec)
+   * @default 500
+   * @type {number}
+   */
+  @Input()
+  minLongClickDelay: number = 500;
+
+  /**
+   * The maximum milliseconds to wait for longclick ends. The default is 0 which means no upper limit.
+   * @default 0
+   * @type {number}
+   */
+  @Input()
+  maxLongClickDelay: number = 0;
+
+  /**
+   * This is a private property to indicate the mousedown timestamp, so that we can check it when teh click event
+   * has been triggered.
+   */
+  private mouseDownTimestamp: number;
+
+  /**
+   * Indicates if the dropdown list is open or not. So that we use internal state to display or hide the dropdown.
+   * @type {boolean}
+   */
+  private dropdownIsOpen: boolean = false;
+
   get hasSubItems(): boolean {
     return Boolean(this.subItems && this.subItems.length);
   }
@@ -72,26 +102,108 @@ export class MenuButtonComponent {
     return this.hasSubItems && !this.hideCaret;
   }
 
-  private clickStartTime: number;
-
-  private readonly longClickInterval = 1000;
-
-  onMouseDown(event: MouseEvent): void {
-    if (this.action && event.button === 0) {
-      this.clickStartTime = (new Date()).getTime();
+  /**
+   * Handling the click event on the component element.
+   * Two goal:
+   * - check if we have a 'longclick' event and open the dropdown (if any) when longclick event happened
+   * - trigger the action or the dropdown open depending on the target element (caret will open the dropdown otherwise
+   * trigger the action.
+   * @param {MouseEvent} event
+   */
+  onMouseClick(event: MouseEvent): void {
+    let el = <HTMLElement>event.target;
+    let now = Date.now();
+    let mdt = this.mouseDownTimestamp; // mousedown time
+    let isLongClick = mdt && mdt + this.minLongClickDelay <= now && (
+      !this.maxLongClickDelay || mdt + this.maxLongClickDelay >= now
+    );
+    let openDropdown = this.hasSubItems && (
+      el.classList.contains(this.caretClass) || isLongClick || !this.actions[this.action]
+    );
+    if (openDropdown && this.dropdown) {
+      if (this.toggleDropdown()) {
+        this.listenToClickOut();
+      }
+    } else if (this.action) {
+      this.actions[this.action]();
     }
+    this.mouseDownTimestamp = 0;
+    event.preventDefault();
   }
 
-  onMouseUp(event: MouseEvent): void {
-    if (event.button === 0) {
-      const clickEndTime = (new Date()).getTime();
-      if (this.hasSubItems && (!this.action || clickEndTime - this.clickStartTime >= this.longClickInterval)) {
-        $(this.dropdown.nativeElement).toggleClass('open');
-      } else if (this.action) {
-        this.actions[this.action]();
+  /**
+   * Listening the click event on the document so that we can hide our dropdown list if the event source is not the
+   * component.
+   */
+  private listenToClickOut = (): void => {
+    this.dropdownIsOpen && document.addEventListener('click', this.onDocumentMouseClick);
+  };
+
+  /**
+   * Handling the click event on the document to hide the dropdown list if it needs.
+   * @param {MouseEvent} event
+   */
+  private onDocumentMouseClick = (event: MouseEvent): void => {
+    let el = <HTMLElement>event.target;
+    if (!this.dropdown.nativeElement.contains(el)) {
+      this.closeDropdown();
+      this.removeDocumentClickListener()
+    }
+  };
+
+  /**
+   * Handling the mousedown event, so that we can check the long clicks and open the dropdown if any.
+   * @param {MouseEvent} event
+   */
+  onMouseDown = (event: MouseEvent): void => {
+    if (this.hasSubItems) {
+      let el = <HTMLElement>event.target;
+      if (!el.classList.contains(this.caretClass)) {
+        this.mouseDownTimestamp = Date.now();
       }
-      event.stopPropagation();
     }
+  };
+
+  /**
+   * The goal is to have one and only one place where we open the dropdown. So that later if we need to change the way
+   * how we do, it will be easier.
+   */
+  private openDropdown():void {
+    this.dropdownIsOpen = true;
+  }
+
+  /**
+   * The goal is to have one and only one place where we close the dropdown. So that later if we need to change the way
+   * how we do, it will be easier.
+   */
+  private closeDropdown():void {
+    this.dropdownIsOpen = false;
+  }
+
+  /**
+   * Just a simple helper method to make the dropdown toggle more easy.
+   * @returns {boolean} It will return the open state of the dropdown;
+   */
+  private toggleDropdown(): boolean {
+    this[this.dropdownIsOpen ? 'closeDropdown' : 'openDropdown']();
+    return this.dropdownIsOpen;
+  }
+
+  /**
+   * The goal is to simply remove the click event listeners from the document.
+   */
+  private removeDocumentClickListener(): void {
+    document.removeEventListener('click', this.onDocumentMouseClick);
+  }
+
+  /**
+   * The main goal if this function is tho handle the item change event on the child dropdown list.
+   * Should update the value and close the dropdown if it is not multiple choice type.
+   * @param {ListItem} options The selected item(s) from the dropdown list.
+   */
+  onDropdownItemChange(options: ListItem) {
+    this.updateValue(options);
+    !this.isMultipleChoice && this.closeDropdown();
   }
 
   updateValue(options: ListItem) {


[07/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf
new file mode 100644
index 0000000..305f0d5
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.ttf differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff
new file mode 100644
index 0000000..ac7452a
Binary files /dev/null and b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.woff differ

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 52e41f6..e9983aa 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -44,53 +44,47 @@
 <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
 <![endif]-->
 
-<div id="top-nav" ng-controller="MainCtrl">
-  <header class="navbar navbar-static-top navbar-inverse">
-    <div class="navbar-inner">
-      <div class="container">
-        <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="logo"><img src="/img/ambari-logo.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-logo"></a>
-        <a href="{{fromSiteRoot('/#/main/dashboard')}}" class="brand" title="{{'common.apacheAmbari' | translate}}" data-qa="ambari-title">{{'common.ambari' | translate}}</a>
-        <ul class="nav navbar-nav navbar-right">
-          <li>
-            <div class="btn-group navbar-views-dropdown" dropdown is-open="viewsdropdown.isopen" ng-mouseover="viewsdropdown.isopen=true" ng-mouseout="viewsdropdown.isopen=false">
-              <a href="{{fromSiteRoot('/#/main/views')}}" ng-click="gotoViewsDashboard()" class="dropdown-toggle"><i class="fa fa-th"></i></a>
-              <ul class="dropdown-menu" role="menu">
-                <li ng-repeat="instance in viewInstances"><a href="{{fromSiteRoot('/#/main/views/' + instance.viewUrl)}}" target="_blank">{{instance.label}}</a></li>
-                <li ng-show="!viewInstances.length" class="disabled"><a>{{'common.noViews' | translate}}</a></li>
-              </ul>
-            </div>
-          </li>
-          <li>
-            <div class="btn-group" dropdown is-open="status.isopen">
-              <button type="button" class="btn btn-default dropdown-toggle navbar-btn" ng-disabled="disabled">
-                <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span>
-              </button>
-              <ul class="dropdown-menu" role="menu">
-                <li><a href ng-click="about()">{{'common.about' | translate}}</a></li>
-                <li class="divider"></li>
-                <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li>
-              </ul>
-            </div>
-          </li>
-        </ul>
-      </div>
-    </div>
-  </header>
-</div>
+<div id="wrapper" ng-controller="AppCtrl">
 
+  <div ng-include="'views/sideNav.html'" ng-controller="SideNavCtrl"></div>
 
-<div class="container">
-  <div class="row">
-    <div class="col-sm-3">
-      <div ng-include="'views/leftNavbar.html'" ng-controller="NavbarCtrl"></div>
+  <div id="main">
+    <div id="top-nav">
+     <nav class="navbar navbar-default navbar-static-top">
+       <div class="container">
+         <div class="navbar-header navbar-nav">
+           <ol class="breadcrumb">
+             <li ng-repeat="breadcrumb in breadcrumbs" ng-class="$last && 'active'">{{breadcrumb}}</li>
+           </ol>
+         </div>
+         <ul class="nav navbar-nav navbar-right">
+           <li>
+             <p class="navbar-text">{{cluster.Clusters.cluster_name}}</p>
+           </li>
+           <li class="dropdown">
+             <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" ng-disabled="disabled">
+               <i class="fa fa-user"></i>&nbsp;{{currentUser}}&nbsp;<span class="caret"></span>
+             </a>
+             <ul class="dropdown-menu">
+               <li><a href ng-click="about()">{{'common.about' | translate}}</a></li>
+               <li role="separator" class="divider"></li>
+               <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li>
+             </ul>
+           </li>
+         </ul>
+       </div>
+     </nav>
     </div>
-    <div class="col-sm-9">
-      <ng-view></ng-view>
+    <div class="container main-container">
+      <div class="row">
+        <div class="col-sm-12">
+          <ng-view></ng-view>
+        </div>
+      </div>
     </div>
   </div>
 </div>
 
-
 <!-- build:js scripts/vendor.js -->
 <!-- bower:js -->
 <script src="bower_components/jquery/dist/jquery.js"></script>
@@ -119,6 +113,7 @@
 <script src="bower_components/bootstrap/js/scrollspy.js"></script>
 <script src="bower_components/bootstrap/js/collapse.js"></script>
 <script src="bower_components/bootstrap/js/tab.js"></script>
+<script src="scripts/theme/bootstrap-ambari.js"></script>
 
 <!-- endbuild -->
 
@@ -127,7 +122,8 @@
 <script src="scripts/routes.js"></script>
 <script src="scripts/i18n.config.js"></script>
 <script src="scripts/controllers/mainCtrl.js"></script>
-<script src="scripts/controllers/NavbarCtrl.js"></script>
+<script src="scripts/controllers/AppCtrl.js"></script>
+<script src="scripts/controllers/SideNavCtrl.js"></script>
 <script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script>
 <script src="scripts/controllers/loginActivities/LoginActivitiesMainCtrl.js"></script>
 <script src="scripts/controllers/loginActivities/LoginMessageMainCtrl.js"></script>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
new file mode 100644
index 0000000..4ac5b38
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
@@ -0,0 +1,177 @@
+/**
+ * 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('AppCtrl',['$scope','$rootScope', '$route', '$window','Auth', 'Alert', '$modal', 'Cluster', '$translate', '$http', 'Settings', 'Utility', '$q', function($scope, $rootScope, $route, $window, Auth, Alert, $modal, Cluster, $translate, $http, Settings, Utility, $q) {
+  var $t = $translate.instant;
+  $scope.signOut = function () {
+    Auth.signout().finally(function () {
+      $window.location.pathname = Settings.siteRoot;
+    });
+  };
+
+  //todo replace with breadcrumb service
+  $scope.$watch(function () {
+    return $route.current;
+  }, function (value) {
+    var breadcrumbs = [$t('common.admin')];
+    if (value && value.$$route.label) {
+      breadcrumbs.push(value.$$route.label);
+    }
+    $scope.breadcrumbs = breadcrumbs;
+  });
+
+
+  $scope.ambariVersion = null;
+  $rootScope.supports = {};
+  $rootScope.authDataLoad = $q.defer();
+
+  Utility.getUserPref('user-pref-' + Auth.getCurrentUser() + '-supports').then(function (data) {
+    $rootScope.supports = data.data ? data.data : {};
+  });
+
+  $http.get(Settings.baseUrl + '/users/' + Auth.getCurrentUser() + '/authorizations?fields=*')
+    .then(function (data) {
+      var auth = !!data.data && !!data.data.items ? data.data.items.map(function (a) {
+          return a.AuthorizationInfo.authorization_id;
+        }) : [],
+        canPersistData = auth.indexOf('CLUSTER.MANAGE_USER_PERSISTED_DATA') > -1;
+      $rootScope.authDataLoad.resolve(canPersistData);
+      if (auth.indexOf('AMBARI.RENAME_CLUSTER') == -1) {
+        $window.location = $rootScope.fromSiteRoot("/#/main/dashboard");
+      }
+    });
+
+  $scope.about = function () {
+    var ambariVersion = $scope.ambariVersion;
+    var modalInstance = $modal.open({
+      templateUrl: 'views/modals/AboutModal.html',
+      controller: ['$scope', function ($scope) {
+        $scope.ok = function () {
+          modalInstance.close();
+        };
+        $scope.ambariVersion = ambariVersion;
+      }]
+    });
+  };
+
+  $scope.currentUser = Auth.getCurrentUser();
+
+  $scope.cluster = null;
+  $scope.isLoaded = null;
+
+  function loadAmbariVersion() {
+    Cluster.getAmbariVersion().then(function (version) {
+      $scope.ambariVersion = version;
+    });
+  }
+
+  function loadClusterData() {
+    Cluster.getStatus().then(function (cluster) {
+      $rootScope.cluster = cluster;
+      $scope.cluster = cluster;
+      $scope.isLoaded = true;
+      if (cluster && cluster.Clusters.provisioning_state === 'INIT') {
+        setTimeout(loadClusterData, 1000);
+      }
+    }).catch(function (data) {
+      Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
+    });
+  }
+
+  loadClusterData();
+  loadAmbariVersion();
+
+  $scope.startInactiveTimeoutMonitoring = function (timeout) {
+    var TIME_OUT = timeout;
+    var active = true;
+    var lastActiveTime = Date.now();
+
+    var keepActive = function () {
+      if (active) {
+        lastActiveTime = Date.now();
+      }
+    };
+
+    $(window).bind('mousemove', keepActive);
+    $(window).bind('keypress', keepActive);
+    $(window).bind('click', keepActive);
+
+    var checkActiveness = function () {
+      var remainTime = TIME_OUT - (Date.now() - lastActiveTime);
+      if (remainTime < 0) {
+        active = false;
+        $(window).unbind('mousemove', keepActive);
+        $(window).unbind('keypress', keepActive);
+        $(window).unbind('click', keepActive);
+        clearInterval($rootScope.userActivityTimeoutInterval);
+        $scope.signOut();
+      } else if (remainTime < 60000 && !$rootScope.timeoutModal) {
+        $rootScope.timeoutModal = $modal.open({
+          templateUrl: 'views/modals/TimeoutWarning.html',
+          backdrop: false,
+          controller: ['$scope', 'Auth', function ($scope, Auth) {
+            $scope.remainTime = 60;
+            $scope.title = $t('main.autoLogOut');
+            $scope.primaryText = $t('main.controls.remainLoggedIn');
+            $scope.secondaryText = $t('main.controls.logOut');
+            $scope.remain = function () {
+              $rootScope.timeoutModal.close();
+              delete $rootScope.timeoutModal;
+            };
+            $scope.logout = function () {
+              $rootScope.timeoutModal.close();
+              delete $rootScope.timeoutModal;
+              Auth.signout().finally(function () {
+                $window.location.pathname = Settings.siteRoot;
+              });
+            };
+            $scope.countDown = function () {
+              $scope.remainTime--;
+              $scope.$apply();
+              if ($scope.remainTime == 0) {
+                Auth.signout().finally(function () {
+                  $window.location.pathname = Settings.siteRoot;
+                });
+              }
+            };
+            setInterval($scope.countDown, 1000);
+          }]
+        });
+      }
+    };
+    $rootScope.userActivityTimeoutInterval = window.setInterval(checkActiveness, 1000);
+  };
+
+  // Send noop requests every 10 seconds just to keep backend session alive
+  $scope.startNoopPolling = function () {
+    $rootScope.noopPollingInterval = setInterval(Cluster.getAmbariTimeout, 10000);
+  };
+
+  if (!$rootScope.userActivityTimeoutInterval) {
+    Cluster.getAmbariTimeout().then(function (timeout) {
+      $rootScope.userTimeout = Number(timeout) * 1000;
+      if ($rootScope.userTimeout > 0)
+        $scope.startInactiveTimeoutMonitoring($rootScope.userTimeout);
+    });
+  }
+  if (!$rootScope.noopPollingInterval) {
+    $scope.startNoopPolling();
+  }
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
deleted file mode 100644
index cbf38e8..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/NavbarCtrl.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('NavbarCtrl',['$scope', 'Cluster', '$location', 'Alert', 'ROUTES', 'ConfirmationModal', '$rootScope', 'Stack', '$translate', 'Settings', function($scope, Cluster, $location, Alert, ROUTES, ConfirmationModal, $rootScope, Stack, $translate, Settings) {
-  var $t = $translate.instant;
-  $scope.cluster = null;
-  $scope.totalRepos = 0;
-  $scope.editCluster = {
-    name        : '',
-    editingName : false
-  };
-  $scope.settings = Settings;
-
-  function loadClusterData() {
-    Cluster.getStatus().then(function (cluster) {
-      $scope.cluster = cluster;
-      Stack.allRepos({version: '',
-        cluster: {
-          options: [],
-          current: null
-        }}, {}).then(function (repos) {
-          $scope.totalRepos = repos.itemTotal;
-        });
-      if (cluster && cluster.Clusters.provisioning_state === 'INIT') {
-        setTimeout(loadClusterData, 1000);
-      }
-    }).catch(function (data) {
-      Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
-    });
-  }
-  loadClusterData();
-
-  $scope.toggleEditName = function($event) {
-    if ($event && $event.keyCode !== 27) {
-      // 27 = Escape key
-      return false;
-    }
-
-    $scope.editCluster.name         = $scope.cluster.Clusters.cluster_name;
-    $scope.editCluster.editingName  = !$scope.editCluster.editingName;
-  };
-
-  $scope.clusterDisplayName = function () {
-    var name="";
-    if($scope.cluster && $scope.cluster.Clusters)
-    {
-       name = $scope.cluster.Clusters.cluster_name;
-    }
-    return name.length > 13 ? name.substr(0, 13) + "..." : name;
-  };
-
-  $scope.confirmClusterNameChange = function() {
-    ConfirmationModal.show(
-      $t('common.clusterNameChangeConfirmation.title'),
-      $t('common.clusterNameChangeConfirmation.message', {
-        clusterName: $scope.editCluster.name
-      })
-    )
-      .then(function() {
-        $scope.saveClusterName();
-      }).catch(function() {
-        // user clicked cancel
-        $scope.toggleEditName();
-      });
-  };
-
-  $scope.saveClusterName = function() {
-    var oldClusterName = $scope.cluster.Clusters.cluster_name,
-        newClusterName = $scope.editCluster.name;
-
-    Cluster.editName(oldClusterName, newClusterName).then(function(data) {
-      $scope.cluster.Clusters.cluster_name = newClusterName;
-      Alert.success($t('common.alerts.clusterRenamed', {clusterName: newClusterName}));
-    }).catch(function(data) {
-      Alert.error($t('common.alerts.cannotRenameCluster', {clusterName: newClusterName}), data.data.message);
-    });
-
-    $scope.toggleEditName();
-  };
-
-  $scope.isActive = function(path) {
-  	var route = ROUTES;
-  	angular.forEach(path.split('.'), function(routeObj) {
-  		route = route[routeObj];
-  	});
-  	var r = new RegExp( route.url.replace(/(:\w+)/, '\\w+'));
-  	return r.test($location.path());
-  };
-}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
new file mode 100644
index 0000000..558d110
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/SideNavCtrl.js
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('SideNavCtrl', ['$scope', '$location', 'ROUTES', '$rootScope', 'Stack', 'Settings', function($scope, $location, ROUTES, $rootScope, Stack, Settings) {
+  $scope.totalRepos = 0;
+  $scope.settings = Settings;
+
+  $scope.$watch(function() {
+    return $rootScope.cluster;
+  }, function() {
+    $scope.cluster = $rootScope.cluster;
+  }, true);
+
+  function loadRepos() {
+    Stack.allRepos({version: '',
+      cluster: {
+        options: [],
+        current: null
+      }}, {}).then(function (repos) {
+      $scope.totalRepos = repos.itemTotal;
+    });
+  }
+
+  function initNavigationBar () {
+    $('body').on('DOMNodeInserted', '.navigation-bar', function() {
+      $('.navigation-bar').navigationBar({
+        fitHeight: true,
+        collapseNavBarClass: 'fa-angle-double-left',
+        expandNavBarClass: 'fa-angle-double-right'
+      });
+      //initTooltips();
+      $('body').off('DOMNodeInserted', '.navigation-bar');
+    });
+  }
+
+  function initTooltips () {
+    $('[rel="tooltip"]').tooltip();
+  }
+
+  initNavigationBar();
+  loadRepos();
+
+  $scope.isActive = function(path) {
+    var route = ROUTES;
+    angular.forEach(path.split('.'), function(routeObj) {
+      route = route[routeObj];
+    });
+    var r = new RegExp( route.url.replace(/(:\w+)/, '\\w+'));
+    return r.test($location.path());
+  };
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
index c945644..30f7568 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
@@ -18,166 +18,10 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('MainCtrl',['$scope','$rootScope','$window','Auth', 'Alert', '$modal', 'Cluster', 'View', '$translate', '$http', 'Settings', 'Utility', '$q', function($scope, $rootScope, $window, Auth, Alert, $modal, Cluster, View, $translate, $http, Settings, Utility, $q) {
-  var $t = $translate.instant;
-  $scope.signOut = function() {
-    Auth.signout().finally(function() {
-      $window.location.pathname = Settings.siteRoot;
-    });
-  };
-
-  $scope.ambariVersion = null;
-  $rootScope.supports = {};
-  $rootScope.authDataLoad = $q.defer();
-
-  Utility.getUserPref('user-pref-' + Auth.getCurrentUser() + '-supports').then(function(data) {
-    $rootScope.supports = data.data ? data.data : {};
-  });
-
-  $http.get(Settings.baseUrl + '/users/' + Auth.getCurrentUser() + '/authorizations?fields=*')
-    .then(function(data) {
-      var auth = !!data.data && !!data.data.items ? data.data.items.map(function (a) {
-          return a.AuthorizationInfo.authorization_id;
-        }) : [],
-        canPersistData = auth.indexOf('CLUSTER.MANAGE_USER_PERSISTED_DATA') > -1;
-      $rootScope.authDataLoad.resolve(canPersistData);
-      if(auth.indexOf('AMBARI.RENAME_CLUSTER') == -1) {
-        $window.location = $rootScope.fromSiteRoot("/#/main/dashboard");
-      }
-    });
-
-  $scope.about = function() {
-   var ambariVersion = $scope.ambariVersion;
-  	var modalInstance = $modal.open({
-  		templateUrl:'views/modals/AboutModal.html',
-  		controller: ['$scope', function($scope) {
-  			$scope.ok = function() {
-  				modalInstance.close();
-  			};
-        $scope.ambariVersion = ambariVersion;
-  		}]
-  	});
-  };
-
-  $scope.currentUser = Auth.getCurrentUser();
-
-  $scope.cluster = null;
-  $scope.isLoaded = null;
-
-  function loadAmbariVersion() {
-    Cluster.getAmbariVersion().then(function(version){
-      $scope.ambariVersion = version;
-    });
-  }
-
-  function loadClusterData(){
-    Cluster.getStatus().then(function(cluster) {
-      $scope.cluster = cluster;
-      $scope.isLoaded = true;
-      if(cluster && cluster.Clusters.provisioning_state === 'INIT'){
-        setTimeout(loadClusterData, 1000);
-      }
-    }).catch(function(data) {
-      Alert.error($t('common.alerts.cannotLoadClusterStatus'), data.statusText);
-    });
-  }
-  loadClusterData();
-  loadAmbariVersion();
-
-  $scope.viewInstances = [];
-
-  $scope.updateInstances = function () {
-    View.getAllVisibleInstance().then(function(instances) {
-      $scope.viewInstances = instances.map(function(i) {
-        i.viewUrl = i.view_name + '/' + i.version + '/' + i.instance_name;
-        return i;
-      });
-    });
-  };
-
-  $scope.gotoViewsDashboard =function() {
-    window.location = Settings.siteRoot + '#/main/views';
-  };
-
-  $scope.$root.$on('instancesUpdate', function (event, data) {
-    $scope.updateInstances();
-  });
-
-  $scope.startInactiveTimeoutMonitoring = function(timeout) {
-    var TIME_OUT = timeout;
-    var active = true;
-    var lastActiveTime = Date.now();
-
-    var keepActive = function() {
-      if (active) {
-        lastActiveTime = Date.now();
-      }
-    };
-
-    $(window).bind('mousemove', keepActive);
-    $(window).bind('keypress', keepActive);
-    $(window).bind('click', keepActive);
-
-    var checkActiveness = function() {
-      var remainTime = TIME_OUT - (Date.now() - lastActiveTime);
-      if (remainTime < 0) {
-        active = false;
-        $(window).unbind('mousemove', keepActive);
-        $(window).unbind('keypress', keepActive);
-        $(window).unbind('click', keepActive);
-        clearInterval($rootScope.userActivityTimeoutInterval);
-        $scope.signOut();
-      } else if (remainTime < 60000 && !$rootScope.timeoutModal) {
-        $rootScope.timeoutModal = $modal.open({
-          templateUrl: 'views/modals/TimeoutWarning.html',
-          backdrop: false,
-          controller: ['$scope', 'Auth', function($scope, Auth) {
-            $scope.remainTime = 60;
-            $scope.title = $t('main.autoLogOut');
-            $scope.primaryText = $t('main.controls.remainLoggedIn');
-            $scope.secondaryText = $t('main.controls.logOut');
-            $scope.remain = function() {
-              $rootScope.timeoutModal.close();
-              delete $rootScope.timeoutModal;
-            };
-            $scope.logout = function() {
-              $rootScope.timeoutModal.close();
-              delete $rootScope.timeoutModal;
-              Auth.signout().finally(function() {
-                $window.location.pathname = Settings.siteRoot;
-              });
-            };
-            $scope.countDown = function() {
-              $scope.remainTime--;
-              $scope.$apply();
-              if ($scope.remainTime == 0) {
-                Auth.signout().finally(function() {
-                  $window.location.pathname = Settings.siteRoot;
-                });
-              }
-            };
-            setInterval($scope.countDown, 1000);
-          }]
-        });
-      }
-    };
-    $rootScope.userActivityTimeoutInterval = window.setInterval(checkActiveness, 1000);
-  };
-
-  // Send noop requests every 10 seconds just to keep backend session alive
-  $scope.startNoopPolling = function() {
-    $rootScope.noopPollingInterval = setInterval(Cluster.getAmbariTimeout, 10000);
-  };
-
-  if (!$rootScope.userActivityTimeoutInterval) {
-    Cluster.getAmbariTimeout().then(function(timeout) {
-      $rootScope.userTimeout = Number(timeout) * 1000;
-      if ($rootScope.userTimeout > 0)
-        $scope.startInactiveTimeoutMonitoring($rootScope.userTimeout);
-    });
-  }
-  if (!$rootScope.noopPollingInterval) {
-    $scope.startNoopPolling();
-  }
-  $scope.updateInstances();
+.controller('MainCtrl',['$scope','$rootScope', function($scope, $rootScope) {
+  $scope.$watch(function() {
+    return $rootScope.cluster;
+  }, function() {
+    $scope.cluster = $rootScope.cluster;
+  }, true);
 }]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index 183a276..cb52df1 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -39,6 +39,7 @@ angular.module('ambariAdminConsole')
     'common.versions': 'Versions',
     'common.stack': 'Stack',
     'common.details': 'Details',
+    'common.dashboard': 'Dashboard',
     'common.goToDashboard': 'Go to Dashboard',
     'common.exportBlueprint': 'Export Blueprint',
     'common.blueprint': 'Blueprint',
@@ -70,7 +71,6 @@ angular.module('ambariAdminConsole')
     'common.renameCluster': 'Rename Cluster',
     'common.renameClusterTip': 'Only alpha-numeric characters, up to 80 characters',
     'common.clusterCreationInProgress': 'Cluster creation in progress...',
-    'common.userGroupManagement': 'User + Group Management',
     'common.all': 'All',
     'common.group': 'Group',
     'common.user': 'User',
@@ -96,6 +96,10 @@ angular.module('ambariAdminConsole')
     'common.undo': 'Undo',
     'common.fromGroupMark': '(from group)',
     'common.copy': '_Copy',
+    'common.clusterInformation': 'Cluster Information',
+    'common.clusterManagement': 'Cluster Management',
+    'common.userManagement': 'User Management',
+    'common.admin': 'Admin',
 
     'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change',
     'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?',
@@ -277,7 +281,7 @@ angular.module('ambariAdminConsole')
 
     'clusters.alerts.cannotLoadClusterData': 'Cannot load cluster data',
 
-    'groups.createLocal': 'Create Local Group',
+    'groups.createLocal': 'Add Groups',
     'groups.name': 'Group name',
     'groups.members': 'Members',
     'groups.membersPlural': '{{n}} member{{n == 1 ? "" : "s"}}',
@@ -298,7 +302,7 @@ angular.module('ambariAdminConsole')
     'users.yourPassword': 'Your Password',
     'users.newPassword': 'New User Password',
     'users.newPasswordConfirmation': 'New User Password Confirmation',
-    'users.create': 'Create Local User',
+    'users.create': 'Add Users',
     'users.active': 'Active',
     'users.inactive': 'Inactive',
     'users.status': 'Status',
@@ -369,6 +373,7 @@ angular.module('ambariAdminConsole')
     'versions.installOn': 'Install on...',
 
     'versions.register.title': 'Register Version',
+    'versions.add.title': 'Add Version',
 
     'versions.register.error.header': 'Unable to Register',
     'versions.register.error.body': 'You are attempting to register a version with a Base URL that is already in use with an existing registered version. You *must* review your Base URLs and confirm they are unique for the version you are trying to register.',

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index a1ca59c..d2d8253 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -22,7 +22,8 @@ angular.module('ambariAdminConsole')
   root: {
     url: '/',
     templateUrl: 'views/main.html',
-    controller: 'MainCtrl'
+    controller: 'MainCtrl',
+    label: 'Welcome'
   },
   authentication: {
     main: {
@@ -47,122 +48,144 @@ angular.module('ambariAdminConsole')
     list: {
       url: '/users',
       templateUrl: 'views/users/list.html',
-      controller: 'UsersListCtrl'
+      controller: 'UsersListCtrl',
+      label: 'Users'
     },
     edit: {
       url: '/users/:id/edit',
       templateUrl: 'views/users/create.html',
-      controller: 'UsersCreateCtrl'
+      controller: 'UsersCreateCtrl',
+      label: 'Users'
     },
     create: {
       url: '/users/new',
       templateUrl: 'views/users/create.html',
-      controller: 'UsersCreateCtrl'
+      controller: 'UsersCreateCtrl',
+      label: 'Users'
     },
     show: {
       url: '/users/:id*',
       templateUrl: 'views/users/show.html',
-      controller: 'UsersShowCtrl'
+      controller: 'UsersShowCtrl',
+      label: 'Users'
     }
   },
   groups: {
     list: {
       url: '/groups',
       templateUrl: 'views/groups/list.html',
-      controller: 'GroupsListCtrl'
+      controller: 'GroupsListCtrl',
+      label: 'Groups'
     },
     edit: {
       url: '/groups/:id/edit',
       templateUrl: 'views/groups/edit.html',
-      controller: 'GroupsEditCtrl'
+      controller: 'GroupsEditCtrl',
+      label: 'Groups'
     },
     create: {
       url: '/groups/new',
       templateUrl: 'views/groups/create.html',
-      controller: 'GroupsCreateCtrl'
+      controller: 'GroupsCreateCtrl',
+      label: 'Groups'
     }
   },
   views: {
     list: {
       url: '/views',
       templateUrl: 'views/ambariViews/listTable.html',
-      controller: 'ViewsListCtrl'
+      controller: 'ViewsListCtrl',
+      label: 'Views'
     },
     listViewUrls: {
       url: '/viewUrls',
       templateUrl: 'views/ambariViews/listUrls.html',
-      controller: 'ViewsListCtrl'
+      controller: 'ViewsListCtrl',
+      label: 'Views'
     },
     createViewUrl:{
       url: '/urls/new',
       templateUrl: 'views/urls/create.html',
-      controller: 'ViewUrlCtrl'
+      controller: 'ViewUrlCtrl',
+      label: 'Views'
     },
     linkViewUrl:{
       url: '/urls/link/:viewName/:viewVersion/:viewInstanceName',
       templateUrl: 'views/urls/create.html',
-      controller: 'ViewUrlCtrl'
+      controller: 'ViewUrlCtrl',
+      label: 'Views'
     },
     editViewUrl:{
       url: '/urls/edit/:urlName',
       templateUrl: 'views/urls/edit.html',
-      controller: 'ViewUrlEditCtrl'
+      controller: 'ViewUrlEditCtrl',
+      label: 'Views'
     },
     clone: {
       url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
       templateUrl: 'views/ambariViews/create.html',
-      controller: 'CreateViewInstanceCtrl'
+      controller: 'CreateViewInstanceCtrl',
+      label: 'Views'
     },
     edit: {
       url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
       templateUrl: 'views/ambariViews/edit.html',
-      controller: 'ViewsEditCtrl'
+      controller: 'ViewsEditCtrl',
+      label: 'Views'
     },
     create: {
       url: '/views/:viewId/new',
       templateUrl: 'views/ambariViews/create.html',
-      controller: 'CreateViewInstanceCtrl'
+      controller: 'CreateViewInstanceCtrl',
+      label: 'Views'
     }
   },
   stackVersions: {
     list: {
       url: '/stackVersions',
       templateUrl: 'views/stackVersions/list.html',
-      controller: 'StackVersionsListCtrl'
+      controller: 'StackVersionsListCtrl',
+      label: 'Cluster Information'
     },
     create: {
       url: '/stackVersions/create',
       templateUrl: 'views/stackVersions/stackVersionPage.html',
-      controller: 'StackVersionsCreateCtrl'
+      controller: 'StackVersionsCreateCtrl',
+      label: 'Cluster Information'
     },
     edit: {
       url: '/stackVersions/:stackName/:versionId/edit',
       templateUrl: 'views/stackVersions/stackVersionPage.html',
-      controller: 'StackVersionsEditCtrl'
+      controller: 'StackVersionsEditCtrl',
+      label: 'Cluster Information'
     }
   },
   remoteClusters: {
     list: {
       url: '/remoteClusters',
       templateUrl: 'views/remoteClusters/list.html',
-      controller: 'RemoteClustersListCtrl'
+      controller: 'RemoteClustersListCtrl',
+      label: 'Remote Clusters'
     },
     create: {
       url: '/remoteClusters/create',
       templateUrl: 'views/remoteClusters/remoteClusterPage.html',
-      controller: 'RemoteClustersCreateCtrl'
+      controller: 'RemoteClustersCreateCtrl',
+      label: 'Remote Clusters'
     },
      edit: {
      url: '/remoteClusters/:clusterName/edit',
      templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
-     controller: 'RemoteClustersEditCtrl'
+     controller: 'RemoteClustersEditCtrl',
+       label: 'Remote Clusters'
      }
   },
   clusters: {
     manageAccess: {
       url: '/clusters/:id/manageAccess',
       templateUrl: 'views/clusters/manageAccess.html',
-      controller: 'ClustersManageAccessCtrl'
+      controller: 'ClustersManageAccessCtrl',
+      label: 'Roles'
     },
     userAccessList: {
       url: '/clusters/:id/userAccessList',

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
new file mode 100644
index 0000000..434d1e9
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/theme/bootstrap-ambari.js
@@ -0,0 +1,269 @@
+/**
+ * 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.
+ */
+
+'use strict';
+
+$(document).ready(function () {
+  var $accordionToggler = $(this).find('[data-toggle="collapseAccordion"]');
+  $accordionToggler.off('click').on('click', function (event) {
+    var $this = $(this);
+    $this.siblings('.panel-body').slideToggle(500);
+    $this.children().children('.panel-toggle').toggleClass('fa-angle-down fa-angle-up');
+    event.stopPropagation();
+    return false;
+  });
+});
+'use strict';
+
+(function ($) {
+
+  /**
+   * jQuery plugin for navigation bars
+   * Usage:
+   * <pre>
+   *   $('.navigation-bar').navigationBar();
+   * </pre>
+   *
+   * @param {object} options see <code>$.fn.navigationBar.defaults</code>
+   * @returns {$}
+   */
+
+  $.fn.navigationBar = function (options) {
+
+    var settings = $.extend({}, $.fn.navigationBar.defaults, options);
+
+    return this.each(function () {
+      var _this = this;
+
+      var containerSelector = '.navigation-bar-container';
+      var $navigationContainer = $(this).find(containerSelector);
+      var $sideNavToggler = $(this).find('[data-toggle=' + settings.navBarToggleDataAttr + ']');
+      var $subMenuToggler = $(this).find('[data-toggle=' + settings.subMenuNavToggleDataAttr + ']');
+      var firstLvlMenuItemsSelector = '.side-nav-menu>li';
+      var secondLvlMenuItemsSelector = '.side-nav-menu>li>ul>li';
+      var $moreActions = $(this).find('.more-actions');
+      var $dropdownMenu = $moreActions.children('.dropdown-menu');
+
+      $subMenuToggler.each(function (index, toggler) {
+        return $(toggler).parent().addClass('has-sub-menu');
+      });
+
+      if (settings.fitHeight) {
+        $(this).addClass('navigation-bar-fit-height');
+
+        // make scrolling effect on side nav ONLY, i.e. not effected on ambari main contents
+        $(this).find('.side-nav-menu').on('DOMMouseScroll mousewheel', function (ev) {
+          var $this = $(this),
+              scrollTop = this.scrollTop,
+              scrollHeight = this.scrollHeight,
+              height = $this.innerHeight(),
+              delta = ev.originalEvent.wheelDelta,
+              up = delta > 0;
+          var prevent = function prevent() {
+            ev.stopPropagation();
+            ev.preventDefault();
+            ev.returnValue = false;
+            return false;
+          };
+
+          if (!up && -delta > scrollHeight - height - scrollTop) {
+            // Scrolling down, but this will take us past the bottom.
+            $this.scrollTop(scrollHeight);
+            return prevent();
+          } else if (up && delta > scrollTop) {
+            // Scrolling up, but this will take us past the top.
+            $this.scrollTop(0);
+            return prevent();
+          }
+        });
+      }
+
+      //set main content left margin based on the width of side-nav
+      var containerWidth = $navigationContainer.width();
+      if (settings.moveLeftContent) {
+        $(settings.content).css('margin-left', containerWidth);
+      }
+      if (settings.moveLeftFooter) {
+        $(settings.footer).css('margin-left', containerWidth);
+      }
+
+      function popStateHandler() {
+        var path = window.location.pathname + window.location.hash;
+        $navigationContainer.find('li a').each(function (index, link) {
+          var $link = $(link);
+          var href = $link.attr('data-href') || $link.attr('href');
+          if (path.indexOf(href) !== -1 && ['', '#'].indexOf(href) === -1) {
+            $link.parent().addClass('active');
+          } else {
+            $link.parent().removeClass('active');
+          }
+        });
+      }
+
+      if (settings.handlePopState) {
+        popStateHandler();
+        $(window).bind('popstate', popStateHandler);
+      }
+
+      function clickHandler(el) {
+        var $li = $(el).parent();
+        var activeClass = settings.activeClass;
+
+        var activeMenuItems = firstLvlMenuItemsSelector + '.' + activeClass;
+        var activeSubMenuItems = secondLvlMenuItemsSelector + '.' + activeClass;
+        $navigationContainer.find(activeMenuItems).removeClass(activeClass);
+        $navigationContainer.find(activeSubMenuItems).removeClass(activeClass);
+        $li.addClass(activeClass);
+      }
+
+      /**
+       * Click on menu item
+       */
+      $(firstLvlMenuItemsSelector + '>a').on('click', function () {
+        clickHandler(this);
+      });
+
+      /**
+       * Click on sub menu item
+       */
+      $(secondLvlMenuItemsSelector + '>a').on('click', function () {
+        clickHandler(this);
+        $(this).parent().parent().parent().addClass(settings.activeClass);
+      });
+
+      /**
+       * Slider for sub menu
+       */
+      $subMenuToggler.off('click').on('click', function (event) {
+        // ignore click if navigation-bar is collapsed
+        if ($navigationContainer.hasClass('collapsed')) {
+          return false;
+        }
+        var $this = $(this);
+        $this.siblings('.sub-menu').slideToggle(600, function () {
+          var $topMenuItem = $this.parent();
+          var $subMenu = $topMenuItem.find('ul');
+          return $subMenu.is(':visible') ? $topMenuItem.removeClass('collapsed') : $topMenuItem.addClass('collapsed');
+        });
+        $this.children('.toggle-icon').toggleClass(settings.menuLeftClass + ' ' + settings.menuDownClass);
+        event.stopPropagation();
+        return false;
+      });
+
+      if (settings.fitHeight) {
+        $moreActions.on('click', function () {
+          // set actions submenu position
+          var $moreIcon = $(this);
+          var $header = $('.side-nav-header');
+          $dropdownMenu.css({
+            top: $moreIcon.offset().top - $header.offset().top + 20 + 'px',
+            left: $moreIcon.offset().left + 'px'
+          });
+        });
+      }
+      $dropdownMenu.on('click', function () {
+        // some action was triggered, should hide this icon
+        var moreIcon = $(this).parent();
+        setTimeout(function () {
+          moreIcon.hide();
+        }, 1000);
+      });
+      $navigationContainer.children('.side-nav-menu').scroll(function () {
+        $moreActions.removeClass('open');
+      });
+
+      /**
+       * Expand/collapse navigation bar
+       */
+      $sideNavToggler.click(function () {
+
+        $navigationContainer.toggleClass('collapsed').promise().done(function () {
+          var subMenuSelector = 'ul.sub-menu';
+          var $subMenus = $navigationContainer.find(subMenuSelector);
+          var $subMenuItems = $navigationContainer.find('.side-nav-menu>li');
+          if ($navigationContainer.hasClass('collapsed')) {
+            // set sub menu invisible when collapsed
+            $subMenus.hide();
+            $moreActions.hide();
+            // set the hover effect when collapsed, should show sub-menu on hovering
+            $subMenuItems.hover(function () {
+              $(this).find(subMenuSelector).show();
+              // set sub-menu position
+              var $parent = $(this);
+              var $header = $('.side-nav-header');
+              if (settings.fitHeight) {
+                $(this).find(subMenuSelector).css({
+                  position: 'fixed',
+                  top: $parent.offset().top - $header.offset().top + 'px',
+                  left: 50 + 'px'
+                });
+              }
+            }, function () {
+              $(this).find(subMenuSelector).hide();
+            });
+          } else {
+            // keep showing all sub menu
+            $subMenus.show().each(function (index, item) {
+              return $(item).parent().removeClass('collapsed');
+            });
+            $subMenuItems.unbind('mouseenter mouseleave');
+            $navigationContainer.find('.toggle-icon').removeClass(settings.menuLeftClass).addClass(settings.menuDownClass);
+            $moreActions.show();
+            // set sub-menu position
+            if (settings.fitHeight) {
+              $(_this).find(subMenuSelector).css({
+                position: 'relative',
+                top: 0,
+                left: 0
+              });
+            }
+          }
+
+          $navigationContainer.on('transitionend', function () {
+            //set main content left margin based on the width of side-nav
+            var containerWidth = $navigationContainer.width();
+            if (settings.moveLeftContent) {
+              $(settings.content).css('margin-left', containerWidth);
+            }
+            if (settings.moveLeftFooter) {
+              $(settings.footer).css('margin-left', containerWidth);
+            }
+          });
+          $sideNavToggler.find('span').toggleClass(settings.collapseNavBarClass + ' ' + settings.expandNavBarClass);
+        });
+        return false;
+      });
+    });
+  };
+
+  $.fn.navigationBar.defaults = {
+    handlePopState: true,
+    fitHeight: false,
+    content: '#main',
+    footer: 'footer',
+    moveLeftContent: true,
+    moveLeftFooter: true,
+    menuLeftClass: 'glyphicon-menu-right',
+    menuDownClass: 'glyphicon-menu-down',
+    collapseNavBarClass: 'fa-angle-double-left',
+    expandNavBarClass: 'fa-angle-double-right',
+    activeClass: 'active',
+    navBarToggleDataAttr: 'collapse-side-nav',
+    subMenuNavToggleDataAttr: 'collapse-sub-menu'
+  };
+})(jQuery);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index 946007d..66f23af 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -415,79 +415,6 @@ a.gotoinstance{
   background-color: #da4f49;
   color: white;
 }
-/*
-  Style topnav menu
-*/
-.navbar-views-dropdown > a{
-  color: #c3c3c3;
-  font-size: 1.3em;
-  padding: 10px 25px 18px;
-  display: block;
-  box-shadow: none!important;
-  background: none!important;
-  text-decoration: none;
-}
-.navbar-views-dropdown > a:hover{
-  color: #fff;
-}
-.navbar-views-dropdown > a > i{
-  display: block;
-  margin-top: 1px;
-  margin-bottom: -12px;
-}
-.navbar-views-dropdown .dropdown-menu, .verison-label-row .dropdown-menu {
-  margin-top: -2px;
-}
-
-.navbar-views-dropdown .dropdown-menu a:hover{
-  background: #666;
-  color: #fff;
-}
-.navbar-views-dropdown .dropdown-menu .disabled a:hover{
-  background: none;
-  color: #999;
-}
-#top-nav .navbar.navbar-static-top{
-  min-height: 40px;
-}
-#top-nav .navbar-inverse{
-  background: none;
-  border: none;
-}
-#top-nav .navbar.navbar-static-top .navbar-inner {
-  background-color: #313d54;
-  -webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
-  -moz-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
-  box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1);
-  max-height: 40px;
-  height: 40px;
-}
-#top-nav .dropdown-toggle.navbar-btn{
-  margin: 4px 0 0 0;
-}
-#top-nav .navbar.navbar-static-top .logo {
-  float: left;
-  padding-top: 2px;
-}
-#top-nav .navbar.navbar-static-top .logo img {
-  height: 32px;
-}
-#top-nav .navbar.navbar-static-top .brand {
-  color: #ffffff;
-  font-size: 16px;
-  font-weight: normal;
-  line-height: 32px;
-  margin-left: 0;
-  padding: 2px 5px 0 10px;
-  text-shadow: 0 1px 0 #555555;
-  display: block;
-  float: left;
-  text-decoration: none;
-
-}
-#top-nav .navbar.navbar-static-top .brand.cluster-name{
-  margin-left: 10px;
-}
 
 .create-view-form, .register-version-form, .edit-version-form {
   padding-bottom: 50px;
@@ -579,24 +506,6 @@ a.gotoinstance{
   border: 0;
 }
 
-.container{
-  padding-left: 0;
-  width: 940px;
-}
-
-
-@media (min-width: 1200px) {
-  .container, .navbar-static-top .container, .navbar-fixed-top .container, .navbar-fixed-bottom .container{
-    width: 1130px;
-  }
-  .container{
-    width: 1170px;
-  }
-  .mainpage .panel-body #main-operations-boxes .col-sm-5 {
-    width: 44%;
-  }
-}
-
 ul.nav li > a{
   cursor: pointer;
 }
@@ -701,318 +610,6 @@ table.no-border tr td{
 /*.login-message-pane .well {height: 74px;}
 .login-message-pane input {margin-left: 3px;}*/
 
-
-.btn {
-  display: inline-block;
-  *display: inline;
-  padding: 4px 14px;
-  margin-bottom: 0;
-  *margin-left: .3em;
-  font-size: 14px;
-  line-height: 20px;
-  *line-height: 20px;
-  color: #333333;
-  text-align: center;
-  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
-  vertical-align: middle;
-  cursor: pointer;
-  background-color: #f5f5f5;
-  *background-color: #e6e6e6;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
-  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
-  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
-  background-repeat: repeat-x;
-  border: 1px solid #bbbbbb;
-  *border: 0;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  border-color: #e6e6e6 #e6e6e6 #bfbfbf;
-  border-bottom-color: #a2a2a2;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-  *zoom: 1;
-  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn:hover,
-.btn:active,
-.btn.active,
-.btn.disabled,
-.btn[disabled] {
-  color: #333333;
-  background-color: #e6e6e6;
-  *background-color: #d9d9d9;
-}
-
-.btn:active,
-.btn.active {
-  background-color: #cccccc \9;
-}
-
-.btn:first-child {
-  *margin-left: 0;
-}
-
-.btn:hover {
-  color: #333333;
-  text-decoration: none;
-  background-color: #e6e6e6;
-  *background-color: #d9d9d9;
-  /* Buttons in IE7 don't get borders, so darken on hover */
-
-  background-position: 0 -15px;
-  -webkit-transition: background-position 0.1s linear;
-     -moz-transition: background-position 0.1s linear;
-       -o-transition: background-position 0.1s linear;
-          transition: background-position 0.1s linear;
-}
-
-.btn:focus {
-  outline: thin dotted #333;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-
-.btn.active,
-.btn:active {
-  background-color: #e6e6e6;
-  background-color: #d9d9d9 \9;
-  background-image: none;
-  outline: 0;
-  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn.disabled,
-.btn[disabled] {
-  cursor: default;
-  background-color: #e6e6e6;
-  background-image: none;
-  opacity: 0.65;
-  filter: alpha(opacity=65);
-  -webkit-box-shadow: none;
-     -moz-box-shadow: none;
-          box-shadow: none;
-}
-
-
-
-.btn-primary.active,
-.btn-warning.active,
-.btn-danger.active,
-.btn-success.active,
-.btn-info.active,
-.btn-inverse.active {
-  color: rgba(255, 255, 255, 0.75);
-}
-
-.btn {
-  border-color: #c5c5c5;
-  border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
-}
-
-.btn-primary {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #006dcc;
-  *background-color: #0044cc;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
-  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
-  background-image: -o-linear-gradient(top, #0088cc, #0044cc);
-  background-image: linear-gradient(to bottom, #0088cc, #0044cc);
-  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
-  background-repeat: repeat-x;
-  border-color: #0044cc #0044cc #002a80;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-primary:hover,
-.btn-primary:active,
-.btn-primary.active,
-.btn-primary.disabled,
-.btn-primary[disabled],
-.btn-primary.disabled:hover,
-.btn-primary[disabled]:hover
- {
-  color: #ffffff;
-  background-color: #0044cc;
-  *background-color: #003bb3;
-}
-
-.btn-primary:active,
-.btn-primary.active {
-  background-color: #003399 \9;
-}
-
-.btn-warning {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #faa732;
-  *background-color: #f89406;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
-  background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
-  background-image: -o-linear-gradient(top, #fbb450, #f89406);
-  background-image: linear-gradient(to bottom, #fbb450, #f89406);
-  background-image: -moz-linear-gradient(top, #fbb450, #f89406);
-  background-repeat: repeat-x;
-  border-color: #f89406 #f89406 #ad6704;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-warning:hover,
-.btn-warning:active,
-.btn-warning.active,
-.btn-warning.disabled,
-.btn-warning[disabled] {
-  color: #ffffff;
-  background-color: #f89406;
-  *background-color: #df8505;
-}
-
-.btn-warning:active,
-.btn-warning.active {
-  background-color: #c67605 \9;
-}
-
-.btn-danger {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #da4f49;
-  *background-color: #bd362f;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
-  background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
-  background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
-  background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
-  background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
-  background-repeat: repeat-x;
-  border-color: #bd362f #bd362f #802420;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-danger:hover,
-.btn-danger:active,
-.btn-danger.active,
-.btn-danger.disabled,
-.btn-danger[disabled] {
-  color: #ffffff;
-  background-color: #bd362f;
-  *background-color: #a9302a;
-}
-
-.btn-danger:active,
-.btn-danger.active {
-  background-color: #942a25 \9;
-}
-
-.btn-success {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #5bb75b;
-  *background-color: #51a351;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
-  background-image: -webkit-linear-gradient(top, #62c462, #51a351);
-  background-image: -o-linear-gradient(top, #62c462, #51a351);
-  background-image: linear-gradient(to bottom, #62c462, #51a351);
-  background-image: -moz-linear-gradient(top, #62c462, #51a351);
-  background-repeat: repeat-x;
-  border-color: #51a351 #51a351 #387038;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-success:hover,
-.btn-success:active,
-.btn-success.active,
-.btn-success.disabled,
-.btn-success[disabled] {
-  color: #ffffff;
-  background-color: #51a351;
-  *background-color: #499249;
-}
-
-.btn-success:active,
-.btn-success.active {
-  background-color: #408140 \9;
-}
-
-.btn-info {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #49afcd;
-  *background-color: #2f96b4;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
-  background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
-  background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
-  background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
-  background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
-  background-repeat: repeat-x;
-  border-color: #2f96b4 #2f96b4 #1f6377;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-info:hover,
-.btn-info:active,
-.btn-info.active,
-.btn-info.disabled,
-.btn-info[disabled] {
-  color: #ffffff;
-  background-color: #2f96b4;
-  *background-color: #2a85a0;
-}
-
-.btn-info:active,
-.btn-info.active {
-  background-color: #24748c \9;
-}
-
-.btn-inverse {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #363636;
-  *background-color: #222222;
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
-  background-image: -webkit-linear-gradient(top, #444444, #222222);
-  background-image: -o-linear-gradient(top, #444444, #222222);
-  background-image: linear-gradient(to bottom, #444444, #222222);
-  background-image: -moz-linear-gradient(top, #444444, #222222);
-  background-repeat: repeat-x;
-  border-color: #222222 #222222 #000000;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);
-}
-
-.btn-inverse:hover,
-.btn-inverse:active,
-.btn-inverse.active,
-.btn-inverse.disabled,
-.btn-inverse[disabled] {
-  color: #ffffff;
-  background-color: #222222;
-  *background-color: #151515;
-}
-
-.btn-inverse:active,
-.btn-inverse.active {
-  background-color: #080808 \9;
-}
-
 button.btn,
 input[type="submit"].btn {
   *padding-top: 3px;
@@ -1050,6 +647,10 @@ button.btn.btn-xs{
   border-radius: 3px;
 }
 
+a.btn-primary {
+  color: #fff;
+}
+
 .clusterDisplayName {
   display:inline-block;
   width:90%;
@@ -1872,4 +1473,28 @@ legend {
 .ellipsis-overflow {
   overflow: hidden;
   text-overflow: ellipsis;
-}
\ No newline at end of file
+}
+
+.pull-right {
+  float: right;
+}
+
+body {
+  height: 100%;
+  background-color: #f0f0f0;
+}
+
+#main {
+  transition: .5s ease;
+  overflow: visible;
+  min-width: 980px;
+}
+
+#side-nav .ambari-header-link:hover {
+  text-decoration: none;
+}
+
+.main-container {
+  background-color: #fff;
+  padding: 15px;
+}


[50/51] [abbrv] ambari git commit: AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO. Fix import (dlysnichenko)

Posted by nc...@apache.org.
AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO. Fix import (dlysnichenko)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 6e706d427f1f9bcfc61f986ea1a1d5f5a28d500f
Parents: 76349ac
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Mon Nov 13 16:35:23 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Mon Nov 13 16:35:23 2017 +0200

----------------------------------------------------------------------
 .../src/main/java/org/apache/ambari/server/checks/LZOCheck.java     | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6e706d42/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
index 3000b79..9c0286b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
@@ -19,7 +19,6 @@ package org.apache.ambari.server.checks;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.PrereqCheckRequest;


[48/51] [abbrv] ambari git commit: AMBARI-22417. Ambari checks fail with FIPS mode is activated on the OS (rlevas)

Posted by nc...@apache.org.
AMBARI-22417. Ambari checks fail with FIPS mode is activated on the OS (rlevas)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5122671d0076612f4b39f4ae51c2ad627544d768
Parents: 7c4a7e4
Author: Robert Levas <rl...@hortonworks.com>
Authored: Mon Nov 13 05:20:25 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Mon Nov 13 05:20:25 2017 -0500

----------------------------------------------------------------------
 .../libraries/functions/curl_krb_request.py     | 22 +++++++-------------
 1 file changed, 7 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5122671d/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py b/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
index 95e8625..55395ce 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/curl_krb_request.py
@@ -21,28 +21,20 @@ Ambari Agent
 """
 
 __all__ = ["curl_krb_request"]
+import hashlib
 import logging
 import os
+
 import time
 
+from get_kinit_path import get_kinit_path
+from get_klist_path import get_klist_path
 from resource_management.core import global_lock
 from resource_management.core import shell
 from resource_management.core.exceptions import Fail
-from get_kinit_path import get_kinit_path
-from get_klist_path import get_klist_path
 from resource_management.libraries.functions.get_user_call_output import get_user_call_output
 
-# hashlib is supplied as of Python 2.5 as the replacement interface for md5
-# and other secure hashes.  In 2.6, md5 is deprecated.  Import hashlib if
-# available, avoiding a deprecation warning under 2.6.  Import md5 otherwise,
-# preserving 2.4 compatibility.
-try:
-  import hashlib
-  _md5 = hashlib.md5
-except ImportError:
-  import md5
-  _md5 = md5.new
-
+HASH_ALGORITHM = hashlib.sha224
 CONNECTION_TIMEOUT_DEFAULT = 10
 MAX_TIMEOUT_DEFAULT = CONNECTION_TIMEOUT_DEFAULT + 2
 
@@ -103,10 +95,10 @@ def curl_krb_request(tmp_dir, keytab, principal, url, cache_file_prefix,
   is_kinit_required = False
 
   # Create the kerberos credentials cache (ccache) file and set it in the environment to use
-  # when executing curl. Use the md5 hash of the combination of the principal and keytab file
+  # when executing curl. Use a hash of the combination of the principal and keytab file
   # to generate a (relatively) unique cache filename so that we can use it as needed. Scope
   # this file by user in order to prevent sharing of cache files by multiple users.
-  ccache_file_name = _md5("{0}|{1}".format(principal, keytab)).hexdigest()
+  ccache_file_name = HASH_ALGORITHM("{0}|{1}".format(principal, keytab)).hexdigest()
 
   curl_krb_cache_path = os.path.join(tmp_dir, "curl_krb_cache")
   if not os.path.exists(curl_krb_cache_path):


[47/51] [abbrv] ambari git commit: AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)

Posted by nc...@apache.org.
AMBARI-22416 Log Search UI: fixes for filtering form. (ababiichuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 7c4a7e4c52e00282e5b8b901cef14c143fd3da2b
Parents: 068d82f
Author: ababiichuk <ab...@hortonworks.com>
Authored: Fri Nov 10 18:16:45 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Fri Nov 10 23:53:24 2017 +0200

----------------------------------------------------------------------
 .../ambari-logsearch-web/src/app/app.module.ts  |   2 -
 .../src/app/classes/filtering.ts                | 355 +---------
 .../src/app/classes/models/app-state.ts         |   6 +-
 .../src/app/classes/models/node-item.ts         |  30 +
 .../src/app/classes/models/node.ts              |  30 -
 .../src/app/classes/models/store.ts             |   6 +-
 .../src/app/classes/models/tab.ts               |  12 +-
 .../src/app/components/app.component.ts         |   6 +-
 .../dropdown-button.component.html              |   4 +-
 .../dropdown-button.component.spec.ts           |   2 -
 .../dropdown-button.component.ts                |  55 +-
 .../dropdown-list/dropdown-list.component.html  |   2 +-
 .../dropdown-list.component.spec.ts             |   6 +-
 .../filter-button.component.spec.ts             |   2 -
 .../filter-button/filter-button.component.ts    |  35 +-
 .../filter-dropdown.component.spec.ts           |  14 +-
 .../filter-dropdown.component.ts                |  22 +-
 .../filters-panel/filters-panel.component.html  |   6 +-
 .../filters-panel.component.spec.ts             |   6 +-
 .../filters-panel/filters-panel.component.ts    |  18 +-
 .../log-context/log-context.component.spec.ts   |   4 +-
 .../logs-container.component.spec.ts            |   2 -
 .../logs-container/logs-container.component.ts  |  26 +-
 .../logs-list/logs-list.component.html          |   3 +-
 .../logs-list/logs-list.component.spec.ts       |  21 +-
 .../components/logs-list/logs-list.component.ts |  10 +-
 .../menu-button/menu-button.component.spec.ts   |   2 -
 .../menu-button/menu-button.component.ts        |   4 +-
 .../pagination-controls.component.ts            |   7 +-
 .../pagination/pagination.component.html        |   2 +-
 .../pagination/pagination.component.spec.ts     |   9 +-
 .../pagination/pagination.component.ts          |  10 +-
 .../search-box/search-box.component.ts          |  12 +-
 .../time-range-picker.component.html            |   3 +-
 .../time-range-picker.component.spec.ts         |  29 +-
 .../time-range-picker.component.ts              |  47 +-
 .../timezone-picker.component.spec.ts           |   2 -
 .../services/component-actions.service.spec.ts  |   2 -
 .../app/services/component-actions.service.ts   |  24 +-
 .../component-generator.service.spec.ts         |   2 -
 .../src/app/services/filtering.service.spec.ts  |  97 ---
 .../src/app/services/filtering.service.ts       | 253 -------
 .../app/services/logs-container.service.spec.ts |  31 +-
 .../src/app/services/logs-container.service.ts  | 678 ++++++++++++++++++-
 .../src/app/services/utils.service.spec.ts      | 285 +++++++-
 .../src/app/services/utils.service.ts           |  65 +-
 46 files changed, 1257 insertions(+), 992 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 56562df..37f3a49 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -34,7 +34,6 @@ import {environment} from '@envs/environment';
 import {mockApiDataService} from '@app/services/mock-api-data.service'
 import {HttpClientService} from '@app/services/http-client.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ComponentGeneratorService} from '@app/services/component-generator.service';
@@ -164,7 +163,6 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
   providers: [
     HttpClientService,
     ComponentActionsService,
-    FilteringService,
     UtilsService,
     LogsContainerService,
     ComponentGeneratorService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
index dde144b..2a7205f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/filtering.ts
@@ -16,354 +16,37 @@
  * limitations under the License.
  */
 
-import {FormGroup, FormControl} from '@angular/forms';
+import {Moment, unitOfTime} from 'moment';
 import {ListItem} from '@app/classes/list-item';
 
 export interface TimeUnit {
   type: 'CURRENT' | 'LAST' | 'PAST';
-  unit: 'ms' | 's' | 'm' | 'h' | 'd' | 'w' | 'M' | 'Y';
+  unit: unitOfTime.DurationConstructor;
   interval?: number;
 }
 
+export interface CustomTimeRange {
+  type: 'CUSTOM';
+  start?: Moment;
+  end?: Moment;
+}
+
+export interface SortingConditions {
+  key: string;
+  type: 'asc' | 'desc';
+}
+
 export interface TimeUnitListItem extends ListItem {
-  value: TimeUnit;
+  value: TimeUnit | CustomTimeRange;
+}
+
+export interface SortingListItem extends ListItem {
+  value: SortingConditions;
 }
 
 export interface FilterCondition {
   label?: string;
   options?: (ListItem | TimeUnitListItem[])[];
-  defaultValue?: string | number | {[key: string]: any};
-  defaultLabel?: string;
+  defaultSelection?: ListItem | ListItem[] | number;
   iconClass?: string;
 }
-
-const paginationOptions: string[] = ['10', '25', '50', '100'];
-
-export const filters: {[key: string]: FilterCondition} = {
-  clusters: {
-    label: 'filter.clusters',
-    options: [],
-    defaultValue: ''
-  },
-  timeRange: {
-    options: [
-      [
-        {
-          label: 'filter.timeRange.7d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 7
-          }
-        },
-        {
-          label: 'filter.timeRange.30d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 30
-          }
-        },
-        {
-          label: 'filter.timeRange.60d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 60
-          }
-        },
-        {
-          label: 'filter.timeRange.90d',
-          value: {
-            type: 'LAST',
-            unit: 'd',
-            interval: 90
-          }
-        },
-        {
-          label: 'filter.timeRange.6m',
-          value: {
-            type: 'LAST',
-            unit: 'M',
-            interval: 6
-          }
-        },
-        {
-          label: 'filter.timeRange.1y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 1
-          }
-        },
-        {
-          label: 'filter.timeRange.2y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 2
-          }
-        },
-        {
-          label: 'filter.timeRange.5y',
-          value: {
-            type: 'LAST',
-            unit: 'Y',
-            interval: 5
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.yesterday',
-          value: {
-            type: 'PAST',
-            unit: 'd'
-          }
-        },
-        // TODO implement time range calculation
-        /*
-         {
-         label: 'filter.timeRange.beforeYesterday',
-         value: {
-         type: 'PAST',
-         unit: 'd'
-         }
-         },
-         {
-         label: 'filter.timeRange.thisDayLastWeek',
-         value: {
-         type: 'PAST',
-         unit: 'd'
-         }
-         },
-         */
-        {
-          label: 'filter.timeRange.previousWeek',
-          value: {
-            type: 'PAST',
-            unit: 'w'
-          }
-        },
-        {
-          label: 'filter.timeRange.previousMonth',
-          value: {
-            type: 'PAST',
-            unit: 'M'
-          }
-        },
-        {
-          label: 'filter.timeRange.previousYear',
-          value: {
-            type: 'PAST',
-            unit: 'Y'
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.today',
-          value: {
-            type: 'CURRENT',
-            unit: 'd'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisWeek',
-          value: {
-            type: 'CURRENT',
-            unit: 'w'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisMonth',
-          value: {
-            type: 'CURRENT',
-            unit: 'M'
-          }
-        },
-        {
-          label: 'filter.timeRange.thisYear',
-          value: {
-            type: 'CURRENT',
-            unit: 'Y'
-          }
-        }
-      ],
-      [
-        {
-          label: 'filter.timeRange.5min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 5
-          }
-        },
-        {
-          label: 'filter.timeRange.15min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 15
-          }
-        },
-        {
-          label: 'filter.timeRange.30min',
-          value: {
-            type: 'LAST',
-            unit: 'm',
-            interval: 30
-          }
-        },
-        {
-          label: 'filter.timeRange.1hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 1
-          }
-        },
-        {
-          label: 'filter.timeRange.3hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 3
-          }
-        },
-        {
-          label: 'filter.timeRange.6hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 6
-          }
-        },
-        {
-          label: 'filter.timeRange.12hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 12
-          }
-        },
-        {
-          label: 'filter.timeRange.24hr',
-          value: {
-            type: 'LAST',
-            unit: 'h',
-            interval: 24
-          }
-        },
-      ]
-    ],
-    defaultValue: {
-      type: 'LAST',
-      unit: 'h',
-      interval: 1
-    },
-    defaultLabel: 'filter.timeRange.1hr'
-  },
-  components: {
-    label: 'filter.components',
-    iconClass: 'fa fa-cubes',
-    options: [],
-    defaultValue: ''
-  },
-  levels: {
-    label: 'filter.levels',
-    iconClass: 'fa fa-sort-amount-asc',
-    options: [
-      {
-        label: 'levels.fatal',
-        value: 'FATAL'
-      },
-      {
-        label: 'levels.error',
-        value: 'ERROR'
-      },
-      {
-        label: 'levels.warn',
-        value: 'WARN'
-      },
-      {
-        label: 'levels.info',
-        value: 'INFO'
-      },
-      {
-        label: 'levels.debug',
-        value: 'DEBUG'
-      },
-      {
-        label: 'levels.trace',
-        value: 'TRACE'
-      },
-      {
-        label: 'levels.unknown',
-        value: 'UNKNOWN'
-      }
-    ],
-    defaultValue: ''
-  },
-  hosts: {
-    label: 'filter.hosts',
-    iconClass: 'fa fa-server',
-    options: [],
-    defaultValue: ''
-  },
-  sorting: {
-    label: 'sorting.title',
-    options: [
-      {
-        label: 'sorting.time.asc',
-        value: {
-          key: 'logtime',
-          type: 'asc'
-        }
-      },
-      {
-        label: 'sorting.time.desc',
-        value: {
-          key: 'logtime',
-          type: 'desc'
-        }
-      }
-    ],
-    defaultValue: '',
-    defaultLabel: ''
-  },
-  pageSize: {
-    label: 'pagination.title',
-    options: paginationOptions.map((option: string): ListItem => {
-      return {
-        label: option,
-        value: option
-      }
-    }),
-    defaultValue: '10',
-    defaultLabel: '10'
-  },
-  page: {
-    defaultValue: 0
-  },
-  query: {}
-};
-
-export const filtersFormItemsMap: {[key: string]: string[]} = {
-  serviceLogs: ['clusters', 'timeRange', 'components', 'levels', 'hosts', 'sorting', 'pageSize', 'page', 'query'],
-  auditLogs: ['clusters', 'timeRange', 'sorting', 'pageSize', 'page', 'query'] // TODO add all the required fields
-};
-
-export const getFiltersForm = (listType: string): FormGroup => {
-  const itemsList = filtersFormItemsMap[listType],
-    keys = Object.keys(filters).filter((key: string): boolean => itemsList.indexOf(key) > -1),
-    items = keys.reduce((currentObject: any, key: string): any => {
-      let formControl = new FormControl(),
-        item = {
-          [key]: formControl
-        };
-      formControl.setValue(filters[key].defaultValue);
-      return Object.assign(currentObject, item);
-    }, {});
-  return new FormGroup(items);
-};

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
index 2c5c083..afed497 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/app-state.ts
@@ -16,9 +16,7 @@
  * limitations under the License.
  */
 
-import {FormGroup} from '@angular/forms';
 import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry';
-import {Tab, initialTabs} from '@app/classes/models/tab';
 
 export interface AppState {
   isAuthorized: boolean;
@@ -28,7 +26,7 @@ export interface AppState {
   isServiceLogsFileView: boolean;
   isServiceLogContextView: boolean;
   activeLog: ActiveServiceLogEntry | null;
-  activeFiltersForm: FormGroup;
+  activeFilters: object;
 }
 
 export const initialState: AppState = {
@@ -39,5 +37,5 @@ export const initialState: AppState = {
   isServiceLogsFileView: false,
   isServiceLogContextView: false,
   activeLog: null,
-  activeFiltersForm: initialTabs.find((tab: Tab): boolean => tab.isActive).appState.activeFiltersForm
+  activeFilters: null
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
new file mode 100644
index 0000000..ef5f772
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node-item.ts
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+import {CommonEntry} from '@app/classes/models/common-entry';
+
+export interface NodeItem {
+  name: string;
+  type?: string;
+  value: string;
+  isParent: boolean;
+  isRoot: boolean;
+  childs?: NodeItem[];
+  logLevelCount?: CommonEntry[];
+  vNodeList?: CommonEntry[];
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
deleted file mode 100644
index a14e51a..0000000
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/node.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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.
- */
-
-import {CommonEntry} from '@app/classes/models/common-entry';
-
-export interface Node {
-  name: string;
-  type?: string;
-  value: string;
-  isParent: boolean;
-  isRoot: boolean;
-  childs?: Node[];
-  logLevelCount?: CommonEntry[];
-  vNodeList?: CommonEntry[];
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
index d912b35..f996d92 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/store.ts
@@ -24,7 +24,7 @@ import {AuditLog} from '@app/classes/models/audit-log';
 import {ServiceLog} from '@app/classes/models/service-log';
 import {BarGraph} from '@app/classes/models/bar-graph';
 import {Graph} from '@app/classes/models/graph';
-import {Node} from '@app/classes/models/node';
+import {NodeItem} from '@app/classes/models/node-item';
 import {UserConfig} from '@app/classes/models/user-config';
 import {Filter} from '@app/classes/models/filter';
 import {AuditLogField} from '@app/classes/models/audit-log-field';
@@ -50,11 +50,11 @@ export interface AppStore {
   serviceLogsHistogramData: BarGraph[];
   serviceLogsTruncated: ServiceLog[];
   graphs: Graph[];
-  hosts: Node[];
+  hosts: NodeItem[];
   userConfigs: UserConfig[];
   filters: Filter[];
   clusters: string[];
-  components: Node[];
+  components: NodeItem[];
   serviceLogsFields: ServiceLogField[];
   auditLogsFields: AuditLogField[];
   tabs: Tab[];

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
index bb8028a..05ea59d 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/classes/models/tab.ts
@@ -16,15 +16,13 @@
  * limitations under the License.
  */
 
-import {getFiltersForm} from '@app/classes/filtering';
-
 export interface Tab {
   id: string;
   type: string;
-  isActive: boolean;
+  isActive?: boolean;
   isCloseable?: boolean;
   label: string;
-  appState: any;
+  appState?: object;
 }
 
 export const initialTabs: Tab[] = [
@@ -35,8 +33,7 @@ export const initialTabs: Tab[] = [
     label: 'common.serviceLogs',
     appState: {
       activeLogsType: 'serviceLogs',
-      isServiceLogsFileView: false,
-      activeFiltersForm: getFiltersForm('serviceLogs')
+      isServiceLogsFileView: false
     }
   },
   {
@@ -46,8 +43,7 @@ export const initialTabs: Tab[] = [
     label: 'common.auditLogs',
     appState: {
       activeLogsType: 'auditLogs',
-      isServiceLogsFileView: false,
-      activeFiltersForm: getFiltersForm('auditLogs')
+      isServiceLogsFileView: false
     }
   }
 ];

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
index 4de47ea..038dd2a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.ts
@@ -30,12 +30,12 @@ import {HttpClientService} from '@app/services/http-client.service';
 export class AppComponent {
 
   constructor(private httpClient: HttpClientService, private translate: TranslateService, private appState: AppStateService) {
-    appState.getParameter('isAuthorized').subscribe(value => this.isAuthorized = value);
+    appState.getParameter('isAuthorized').subscribe((value: boolean) => this.isAuthorized = value);
     appState.setParameter('isInitialLoading', true);
-    this.httpClient.get('status').subscribe(() => this.appState.setParameters({
+    httpClient.get('status').subscribe(() => appState.setParameters({
       isAuthorized: true,
       isInitialLoading: false
-    }), () => this.appState.setParameter('isInitialLoading', false));
+    }), () => appState.setParameter('isInitialLoading', false));
     translate.setDefaultLang('en');
     translate.use('en');
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
index 798a609..b5f1e56 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.html
@@ -22,10 +22,10 @@
       <span *ngIf="iconClass" [ngClass]="iconClass"></span>
       <span *ngIf="label">{{label | translate}}</span>
     </span>
-    <span *ngIf="showSelectedValue && !isMultipleChoice">{{selectedLabel | translate}}</span>
+    <span *ngIf="showSelectedValue && !isMultipleChoice && selection.length">{{selection[0].label | translate}}</span>
     <span *ngIf="!hideCaret" class="caret"></span>
   </button>
   <ul data-component="dropdown-list" [ngClass]="{'dropdown-menu': true, 'dropdown-menu-right': isRightAlign}"
-      [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateValue($event)"
+      [items]="options" [isMultipleChoice]="isMultipleChoice" (selectedItemChange)="updateSelection($event)"
       [actionArguments]="additionalArgs"></ul>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
index f11ca09..bd41c04 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {HttpClientService} from '@app/services/http-client.service';
@@ -85,7 +84,6 @@ describe('DropdownButtonComponent', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         UtilsService,
         ComponentActionsService,
         {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
index 0bf4422..148e1b4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-button/dropdown-button.component.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-import {Component, OnInit, Input} from '@angular/core';
+import {Component, Input} from '@angular/core';
 import {ListItem} from '@app/classes/list-item';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {UtilsService} from '@app/services/utils.service';
@@ -26,14 +26,10 @@ import {UtilsService} from '@app/services/utils.service';
   templateUrl: './dropdown-button.component.html',
   styleUrls: ['./dropdown-button.component.less']
 })
-export class DropdownButtonComponent implements OnInit {
+export class DropdownButtonComponent {
 
   constructor(protected actions: ComponentActionsService, protected utils: UtilsService) {
   }
-
-  ngOnInit() {
-    this.selectedLabel = this.defaultLabel;
-  }
   
   @Input()
   label?: string;
@@ -48,13 +44,7 @@ export class DropdownButtonComponent implements OnInit {
   showSelectedValue: boolean = true;
 
   @Input()
-  options?: ListItem[];
-
-  @Input()
-  defaultValue?: string;
-
-  @Input()
-  defaultLabel?: string;
+  options: ListItem[] = [];
 
   @Input()
   action?: string;
@@ -71,36 +61,33 @@ export class DropdownButtonComponent implements OnInit {
   @Input()
   isDropup: boolean = false;
 
-  protected selectedValue?: any;
-
-  selectedLabel: string;
+  protected selectedItems?: ListItem[] = [];
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(value: any) {
-    this.selectedValue = value;
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
   }
 
-  updateValue(eventOptions: ListItem): void {
-    const value = eventOptions && eventOptions.value,
-      action = this.action && this.actions[this.action];
+  updateSelection(item: ListItem): void {
+    const action = this.action && this.actions[this.action];
     if (this.isMultipleChoice) {
-      this.value = this.utils.updateMultiSelectValue(this.value, value, eventOptions.isChecked);
-      this.options.find(item => item.value === value).isChecked = eventOptions.isChecked;
+      this.options.find((option: ListItem): boolean => {
+        return this.utils.isEqual(option.value, item.value);
+      }).isChecked = item.isChecked;
+      const checkedItems = this.options.filter((option: ListItem): boolean => option.isChecked);
+      this.selection = checkedItems;
       if (action) {
-        action(this.options.filter(item => item.isChecked).map(item => item.value), ...this.additionalArgs);
+        action(checkedItems.map((option: ListItem): any => option.value), ...this.additionalArgs);
       }
-    } else {
-      if (this.utils.valueHasChanged(this.value, value)) {
-        this.value = value;
-        this.selectedLabel = eventOptions.label;
-        if (action) {
-          action(this.value, ...this.additionalArgs);
-        }
+    } else if (!this.utils.isEqual(this.selection[0], item)) {
+      this.selection = [item];
+      if (action) {
+        action(item.value, ...this.additionalArgs);
       }
     }
   }
-  
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
index 5de78ad..df564e5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.html
@@ -17,7 +17,7 @@
 
 <li *ngFor="let item of items">
   <label class="list-item-label" *ngIf="isMultipleChoice">
-    <input type="checkbox" [attr.id]="item.id || item.value" [attr.checked]="item.isChecked ? 'checked' : null"
+    <input type="checkbox" [attr.id]="item.id || item.value" [(ngModel)]="item.isChecked"
            (change)="changeSelectedItem({value: item.value, isChecked: $event.currentTarget.checked})">
     <label [attr.for]="item.id || item.value" class="label-container">
       <span *ngIf="item.iconClass" [ngClass]="item.iconClass"></span>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
index 5455e67..ac2fa84 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/dropdown-list/dropdown-list.component.spec.ts
@@ -17,6 +17,7 @@
  */
 
 import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormsModule} from '@angular/forms';
 import {StoreModule} from '@ngrx/store';
 import {TranslationModules} from '@app/test-config.spec';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
@@ -34,7 +35,6 @@ import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentGeneratorService} from '@app/services/component-generator.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 
 import {DropdownListComponent} from './dropdown-list.component';
@@ -69,7 +69,8 @@ describe('DropdownListComponent', () => {
           components,
           serviceLogsTruncated,
           tabs
-        })
+        }),
+        FormsModule
       ],
       providers: [
         ComponentGeneratorService,
@@ -78,7 +79,6 @@ describe('DropdownListComponent', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
         ComponentActionsService,
         HostsService,
         AuditLogsService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
index 3e40455..f9ae154 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -86,7 +85,6 @@ describe('FilterButtonComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         UtilsService,
         {
           provide: HttpClientService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
index 2c8ecd7..2dcecd1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-button/filter-button.component.ts
@@ -41,34 +41,35 @@ export class FilterButtonComponent extends MenuButtonComponent implements Contro
     super(actions);
   }
 
-  @Input()
-  defaultValue?: string;
-
-  private selectedValue: any;
+  private selectedItems: ListItem[] = [];
 
   private onChange: (fn: any) => void;
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(newValue: any) {
-    this.selectedValue = newValue;
-    this.onChange(newValue);
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
+    if (this.onChange) {
+      this.onChange(items);
+    }
   }
 
-  updateValue(options: ListItem): void {
-    const value = options && options.value;
+  updateSelection(item: ListItem): void {
     if (this.isMultipleChoice) {
-      this.value = this.utils.updateMultiSelectValue(this.value, value, options.isChecked);
-    } else {
-      if (this.utils.valueHasChanged(this.selectedValue, value)) {
-        this.value = value;
-      }
+      this.subItems.find((option: ListItem): boolean => {
+        return this.utils.isEqual(option.value, item.value);
+      }).isChecked = item.isChecked;
+      const checkedItems = this.subItems.filter((option: ListItem): boolean => option.isChecked);
+      this.selection = checkedItems;
+    } else if (!this.utils.isEqual(this.selection[0], item)) {
+      this.selection = [item];
     }
   }
 
-  writeValue() {
+  writeValue(items: ListItem[]) {
+    this.selection = items;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
index c294e8e..f9192f4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.spec.ts
@@ -28,7 +28,9 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {ClustersService, clusters} from '@app/services/storage/clusters.service';
+import {ComponentsService, components} from '@app/services/storage/components.service';
+import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {UtilsService} from '@app/services/utils.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -77,7 +79,10 @@ describe('FilterDropdownComponent', () => {
           serviceLogsFields,
           serviceLogsHistogramData,
           serviceLogsTruncated,
-          tabs
+          tabs,
+          clusters,
+          components,
+          hosts
         }),
         ...TranslationModules
       ],
@@ -91,8 +96,11 @@ describe('FilterDropdownComponent', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
+        ClustersService,
+        ComponentsService,
+        HostsService,
         {
-          provide: FilteringService,
+          provide: LogsContainerService,
           useValue: filtering
         },
         UtilsService,

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
index 9e5a6f1..d677d81 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filter-dropdown/filter-dropdown.component.ts
@@ -20,6 +20,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {ComponentActionsService} from '@app/services/component-actions.service';
 import {UtilsService} from '@app/services/utils.service';
 import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown-button.component';
+import {ListItem} from '@app/classes/list-item';
 
 @Component({
   selector: 'filter-dropdown',
@@ -41,16 +42,25 @@ export class FilterDropdownComponent extends DropdownButtonComponent implements
 
   private onChange: (fn: any) => void;
 
-  get value(): any {
-    return this.selectedValue;
+  get selection(): ListItem[] {
+    return this.selectedItems;
   }
 
-  set value(newValue: any) {
-    this.selectedValue = newValue;
-    this.onChange(newValue);
+  set selection(items: ListItem[]) {
+    this.selectedItems = items;
+    if (this.isMultipleChoice) {
+      this.options.forEach((option: ListItem): void => {
+        const selectionItem = items.find((item: ListItem): boolean => this.utils.isEqual(item.value, option.value));
+        option.isChecked = Boolean(selectionItem);
+      });
+    }
+    if (this.onChange) {
+      this.onChange(items);
+    }
   }
 
-  writeValue() {
+  writeValue(items: ListItem[]) {
+    this.selection = items;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
index fa739a4..2d327a6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.html
@@ -17,13 +17,13 @@
 
 <form [formGroup]="filtersForm">
   <div class="form-inline filter-input-container col-md-8">
-    <filter-dropdown [label]="filters.clusters.label" formControlName="clusters" [options]="filters.clusters.options"
-                     [defaultLabel]="filters.clusters.defaultLabel" [isMultipleChoice]="true"
+    <filter-dropdown *ngIf="isFilterConditionDisplayed('clusters')" [label]="filters.clusters.label"
+                     formControlName="clusters" [options]="filters.clusters.options" [isMultipleChoice]="true"
                      class="filter-input"></filter-dropdown>
     <search-box formControlName="query" [items]="searchBoxItemsTranslated" class="filter-input"
                 [parameterNameChangeSubject]="queryParameterNameChange"
                 [parameterAddSubject]="queryParameterAdd"></search-box>
-    <time-range-picker formControlName="timeRange" [defaultLabel]="filters.timeRange.defaultLabel"
+    <time-range-picker *ngIf="isFilterConditionDisplayed('timeRange')" formControlName="timeRange"
                        class="filter-input"></time-range-picker>
     <timezone-picker class="filter-input"></timezone-picker>
     <!--button class="btn btn-success" type="button">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
index 0bb0204..1f7e8db 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.spec.ts
@@ -18,6 +18,7 @@
 
 import {NO_ERRORS_SCHEMA} from '@angular/core';
 import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {FormGroup, FormControl} from '@angular/forms';
 import {TranslationModules} from '@app/test-config.spec';
 import {StoreModule} from '@ngrx/store';
 import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service';
@@ -32,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {AppStateService, appState} from '@app/services/storage/app-state.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
@@ -88,7 +88,6 @@ describe('FiltersPanelComponent', () => {
         AppStateService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         LogsContainerService,
         {
           provide: HttpClientService,
@@ -104,6 +103,9 @@ describe('FiltersPanelComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(FiltersPanelComponent);
     component = fixture.componentInstance;
+    component.filtersForm = new FormGroup({
+      control: new FormControl()
+    });
     fixture.detectChanges();
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
index 9601a0e..3314252 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/filters-panel/filters-panel.component.ts
@@ -21,10 +21,8 @@ import {FormGroup} from '@angular/forms';
 import {Subject} from 'rxjs/Subject';
 import {TranslateService} from '@ngx-translate/core';
 import {ListItem} from '@app/classes/list-item';
-import {filtersFormItemsMap} from '@app/classes/filtering';
 import {CommonEntry} from '@app/classes/models/common-entry';
 import {LogField} from '@app/classes/models/log-field';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
 
@@ -35,7 +33,10 @@ import {AppStateService} from '@app/services/storage/app-state.service';
 })
 export class FiltersPanelComponent {
 
-  constructor(private translate: TranslateService, private filtering: FilteringService, private logsContainer: LogsContainerService, private appState: AppStateService) {
+  constructor(
+    private translate: TranslateService, private logsContainer: LogsContainerService,
+    private appState: AppStateService
+  ) {
     appState.getParameter('activeLogsType').subscribe(value => {
       this.logsType = value;
       logsContainer.logsTypeMap[value].fieldsModel.getAll().subscribe((fields: LogField[]): void => {
@@ -80,23 +81,24 @@ export class FiltersPanelComponent {
   searchBoxItemsTranslated: CommonEntry[] = [];
 
   get filters(): any {
-    return this.filtering.filters;
+    return this.logsContainer.filters;
   }
 
   get queryParameterNameChange(): Subject<any> {
-    return this.filtering.queryParameterNameChange;
+    return this.logsContainer.queryParameterNameChange;
   }
 
   get queryParameterAdd(): Subject<any> {
-    return this.filtering.queryParameterAdd;
+    return this.logsContainer.queryParameterAdd;
   }
 
   get captureSeconds(): number {
-    return this.filtering.captureSeconds;
+    return this.logsContainer.captureSeconds;
   }
 
   isFilterConditionDisplayed(key: string): boolean {
-    return filtersFormItemsMap[this.logsType].indexOf(key) > -1;
+    return this.logsContainer.filtersFormItemsMap[this.logsType].indexOf(key) > -1
+      && Boolean(this.filtersForm.controls[key]);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
index 4e9bdc9..7bd87ad 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-context/log-context.component.spec.ts
@@ -34,7 +34,6 @@ import {TranslationModules} from '@app/test-config.spec';
 import {ModalComponent} from '@app/components/modal/modal.component';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 
 import {LogContextComponent} from './log-context.component';
 
@@ -90,8 +89,7 @@ describe('LogContextComponent', () => {
         {
           provide: HttpClientService,
           useValue: httpClient
-        },
-        FilteringService
+        }
       ],
       schemas: [CUSTOM_ELEMENTS_SCHEMA]
     })

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
index 0a9418f..2bb8731 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.spec.ts
@@ -33,7 +33,6 @@ import {HostsService, hosts} from '@app/services/storage/hosts.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {UtilsService} from '@app/services/utils.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {TabsComponent} from '@app/components/tabs/tabs.component';
@@ -92,7 +91,6 @@ describe('LogsContainerComponent', () => {
         HostsService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         UtilsService,
         LogsContainerService
       ],

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
index 21949f1..f8acd50 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.ts
@@ -22,7 +22,6 @@ import {Observable} from 'rxjs/Observable';
 import {Subject} from 'rxjs/Subject';
 import 'rxjs/add/operator/map';
 import 'rxjs/add/operator/takeUntil';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
@@ -43,9 +42,11 @@ import {ListItem} from '@app/classes/list-item';
 })
 export class LogsContainerComponent {
 
-  constructor(private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+  constructor(
+    private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private appState: AppStateService,
+    private tabsStorage: TabsService, private logsContainer: LogsContainerService
+  ) {
     this.logsContainer.loadColumnsNames();
-    this.logsTypeChange.first().subscribe(() => this.logsContainer.loadLogs());
     appState.getParameter('activeLogsType').subscribe((value: string): void => {
       this.logsType = value;
       this.logsTypeChange.next();
@@ -75,11 +76,6 @@ export class LogsContainerComponent {
         this.displayedColumns = columns.filter((column: LogField): boolean => column.isAvailable && column.isDisplayed);
       });
     });
-    appState.getParameter('activeFiltersForm').subscribe((form: FormGroup): void => {
-      this.filtersFormChange.next();
-      form.valueChanges.takeUntil(this.filtersFormChange).subscribe(() => this.logsContainer.loadLogs());
-      this.filtersForm = form;
-    });
     serviceLogsHistogramStorage.getAll().subscribe((data: BarGraph[]): void => {
       this.histogramData = this.logsContainer.getHistogramData(data);
     });
@@ -88,12 +84,12 @@ export class LogsContainerComponent {
 
   tabs: Observable<Tab[]> = this.tabsStorage.getAll();
 
-  filtersForm: FormGroup;
+  get filtersForm(): FormGroup {
+    return this.logsContainer.filtersForm;
+  };
 
   private logsType: string;
 
-  private filtersFormChange: Subject<any> = new Subject();
-
   private logsTypeChange: Subject<any> = new Subject();
 
   get logsTypeMapObject(): any {
@@ -117,10 +113,10 @@ export class LogsContainerComponent {
   };
 
   get autoRefreshRemainingSeconds(): number {
-    return this.filtering.autoRefreshRemainingSeconds;
+    return this.logsContainer.autoRefreshRemainingSeconds;
   }
 
-  get autoRefreshMessageParams(): any {
+  get autoRefreshMessageParams(): object {
     return {
       remainingSeconds: this.autoRefreshRemainingSeconds
     };
@@ -133,7 +129,7 @@ export class LogsContainerComponent {
   get totalEventsFoundMessageParams(): object {
     return {
       totalCount: this.totalCount
-    }
+    };
   }
 
   isServiceLogContextView: boolean = false;
@@ -147,7 +143,7 @@ export class LogsContainerComponent {
   }
 
   setCustomTimeRange(startTime: number, endTime: number): void {
-    this.filtering.setCustomTimeRange(startTime, endTime);
+    this.logsContainer.setCustomTimeRange(startTime, endTime);
   }
 
   onSwitchTab(activeTab: Tab): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 10f4af1..7de0b96 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -17,8 +17,7 @@
 
 <form *ngIf="logs && logs.length" [formGroup]="filtersForm" class="row pull-right">
   <filter-dropdown [label]="filters.sorting.label" formControlName="sorting" [options]="filters.sorting.options"
-                   [defaultLabel]="filters.sorting.defaultLabel" [isRightAlign]="true"
-                   class="col-md-12"></filter-dropdown>
+                   [isRightAlign]="true" class="col-md-12"></filter-dropdown>
 </form>
 <div class="panel panel-default">
  <div class="panel-body">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
index 8ee4ca3..21c4f02 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.spec.ts
@@ -28,8 +28,13 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
 import {ClustersService, clusters} from '@app/services/storage/clusters.service';
 import {ComponentsService, components} from '@app/services/storage/components.service';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {UtilsService} from '@app/services/utils.service';
 
 import {LogsListComponent} from './logs-list.component';
@@ -57,7 +62,12 @@ describe('LogsListComponent', () => {
           appState,
           clusters,
           components,
-          hosts
+          hosts,
+          auditLogsFields,
+          serviceLogsFields,
+          serviceLogsHistogramData,
+          serviceLogsTruncated,
+          tabs
         }),
         MomentModule,
         MomentTimezoneModule,
@@ -75,7 +85,12 @@ describe('LogsListComponent', () => {
         ClustersService,
         ComponentsService,
         HostsService,
-        FilteringService,
+        AuditLogsFieldsService,
+        ServiceLogsFieldsService,
+        ServiceLogsHistogramDataService,
+        ServiceLogsTruncatedService,
+        TabsService,
+        LogsContainerService,
         UtilsService
       ],
       schemas: [NO_ERRORS_SCHEMA]

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
index 017bc82..3a56fca 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.ts
@@ -18,7 +18,7 @@
 import {Component, AfterViewInit, Input, ViewChild, ElementRef} from '@angular/core';
 import {FormGroup} from '@angular/forms';
 import 'rxjs/add/operator/map';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {UtilsService} from '@app/services/utils.service';
 import {AuditLog} from '@app/classes/models/audit-log';
 import {ServiceLog} from '@app/classes/models/service-log';
@@ -31,7 +31,7 @@ import {LogField} from '@app/classes/models/log-field';
 })
 export class LogsListComponent implements AfterViewInit {
 
-  constructor(private filtering: FilteringService, private utils: UtilsService) {
+  constructor(private logsContainer: LogsContainerService, private utils: UtilsService) {
   }
 
   ngAfterViewInit() {
@@ -104,11 +104,11 @@ export class LogsListComponent implements AfterViewInit {
   readonly timeFormat: string = 'h:mm:ss A';
 
   get timeZone(): string {
-    return this.filtering.timeZone;
+    return this.logsContainer.timeZone;
   }
 
   get filters(): any {
-    return this.filtering.filters;
+    return this.logsContainer.filters;
   }
 
   isDifferentDates(dateA, dateB): boolean {
@@ -135,7 +135,7 @@ export class LogsListComponent implements AfterViewInit {
   }
 
   updateQuery(event: any) {
-    this.filtering.queryParameterAdd.next({
+    this.logsContainer.queryParameterAdd.next({
       name: this.messageFilterParameterName,
       value: this.selectedText,
       isExclude: event.value

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
index 261e213..71bbf67 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.spec.ts
@@ -33,7 +33,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 
@@ -85,7 +84,6 @@ describe('MenuButtonComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
index 5932e1b..ca89935 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/menu-button/menu-button.component.ts
@@ -202,11 +202,11 @@ export class MenuButtonComponent {
    * @param {ListItem} options The selected item(s) from the dropdown list.
    */
   onDropdownItemChange(options: ListItem) {
-    this.updateValue(options);
+    this.updateSelection(options);
     !this.isMultipleChoice && this.closeDropdown();
   }
 
-  updateValue(options: ListItem) {
+  updateSelection(options: ListItem) {
     // TODO implement value change behaviour
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
index 81676a9..5f85da7 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination-controls/pagination-controls.component.ts
@@ -54,7 +54,9 @@ export class PaginationControlsComponent implements ControlValueAccessor {
     if (this.isValidValue(newValue)) { // this is the last validation check
       this.currentPage = newValue;
       this.currentPageChange.emit(newValue);
-      this.onChange(newValue);
+      if (this.onChange) {
+        this.onChange(newValue);
+      }
     } else {
       throw new Error(`Invalid value ${newValue}. The currentPage should be between 0 and ${this.pagesCount}.`);
     }
@@ -121,7 +123,8 @@ export class PaginationControlsComponent implements ControlValueAccessor {
     return this.pagesCount > 0 && this.value > 0;
   }
 
-  writeValue() {
+  writeValue(value: number) {
+    this.value = value;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
index 679a7e5..4be0a47 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.html
@@ -17,7 +17,7 @@
 
 <form class="pagination-form" [formGroup]="filtersForm">
   <filter-dropdown [label]="filterInstance.label" formControlName="pageSize" [options]="filterInstance.options"
-                   [defaultLabel]="filterInstance.defaultLabel" [isRightAlign]="true" isDropup="true"></filter-dropdown>
+                   [isRightAlign]="true" [isDropup]="true"></filter-dropdown>
   <span>{{'pagination.numbers' | translate: numbersTranslateParams}}</span>
   <pagination-controls formControlName="page" [totalCount]="totalCount" [pagesCount]="pagesCount"
                        (currentPageChange)="setCurrentPage($event)"></pagination-controls>

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
index ff8675d..c820027 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.spec.ts
@@ -39,7 +39,14 @@ describe('PaginationComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(PaginationComponent);
     component = fixture.componentInstance;
-    component.filterInstance = {};
+    component.filterInstance = {
+      defaultSelection: [
+        {
+          label: '10',
+          value: '10'
+        }
+      ]
+    };
     component.filtersForm = new FormGroup({
       pageSize: new FormControl()
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
index cc5589f..890c2ee 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/pagination/pagination.component.ts
@@ -18,6 +18,8 @@
 
 import {Component, OnInit, Input} from '@angular/core';
 import {FormGroup} from '@angular/forms';
+import {ListItem} from '@app/classes/list-item';
+import {FilterCondition} from '@app/classes/filtering';
 
 @Component({
   selector: 'pagination',
@@ -27,9 +29,9 @@ import {FormGroup} from '@angular/forms';
 export class PaginationComponent implements OnInit {
 
   ngOnInit() {
-    this.setPageSizeFromString(this.filterInstance.defaultValue);
-    this.filtersForm.controls.pageSize.valueChanges.subscribe((value: string): void => {
-      this.setPageSizeFromString(value);
+    this.setPageSizeFromString(this.filterInstance.defaultSelection[0].value);
+    this.filtersForm.controls.pageSize.valueChanges.subscribe((selection: ListItem): void => {
+      this.setPageSizeFromString(selection[0].value);
     });
   }
 
@@ -37,7 +39,7 @@ export class PaginationComponent implements OnInit {
   filtersForm: FormGroup;
 
   @Input()
-  filterInstance: any;
+  filterInstance: FilterCondition;
 
   @Input()
   currentCount?: number;

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
index 5520310..18ff715 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/search-box/search-box.component.ts
@@ -159,7 +159,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
     this.isValueInput = true;
     this.currentValue = '';
     setTimeout(() => this.valueInput.focus(), 0);
-  }
+  };
 
   onParameterValueChange(event: KeyboardEvent): void {
     if (this.utils.isEnterPressed(event) && this.currentValue) {
@@ -187,7 +187,7 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
       isExclude: options.isExclude
     });
     this.updateValue();
-  }
+  };
 
   removeParameter(event: MouseEvent, id: number): void {
     this.parameters = this.parameters.filter(parameter => parameter.id !== id);
@@ -196,10 +196,14 @@ export class SearchBoxComponent implements OnInit, OnDestroy, ControlValueAccess
   }
 
   updateValue() {
-    this.onChange(this.parameters);
+    if (this.onChange) {
+      this.onChange(this.parameters);
+    }
   }
 
-  writeValue() {
+  writeValue(parameters: any [] = []) {
+    this.parameters = parameters;
+    this.updateValue();
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
index 973db61..621f995 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.html
@@ -16,7 +16,8 @@
 -->
 
 <button class="btn btn-link dropdown-toggle" data-toggle="dropdown">
-  {{selectedLabel | translate}} <span class="caret"></span>
+  <span *ngIf="selection">{{selection.label | translate}}</span>
+  <span class="caret"></span>
 </button>
 <div class="dropdown-menu row col-md-12">
   <div class="col-md-4" (click)="$event.stopPropagation()">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
index 7612cc3..43e4bd5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.spec.ts
@@ -25,8 +25,15 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service
 import {ClustersService, clusters} from '@app/services/storage/clusters.service';
 import {ComponentsService, components} from '@app/services/storage/components.service';
 import {HostsService, hosts} from '@app/services/storage/hosts.service';
+import {AuditLogsService, auditLogs} from '@app/services/storage/audit-logs.service';
+import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/audit-logs-fields.service';
+import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-logs.service';
+import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service';
+import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
+import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
+import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 
 import {TimeRangePickerComponent} from './time-range-picker.component';
 
@@ -51,7 +58,14 @@ describe('TimeRangePickerComponent', () => {
           appState,
           clusters,
           components,
-          hosts
+          hosts,
+          auditLogs,
+          auditLogsFields,
+          serviceLogs,
+          serviceLogsFields,
+          serviceLogsHistogramData,
+          serviceLogsTruncated,
+          tabs
         }),
         ...TranslationModules
       ],
@@ -60,12 +74,19 @@ describe('TimeRangePickerComponent', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
+        LogsContainerService,
         AppSettingsService,
         AppStateService,
         ClustersService,
         ComponentsService,
-        HostsService
+        HostsService,
+        AuditLogsService,
+        AuditLogsFieldsService,
+        ServiceLogsService,
+        ServiceLogsFieldsService,
+        ServiceLogsHistogramDataService,
+        ServiceLogsTruncatedService,
+        TabsService
       ],
       schemas: [CUSTOM_ELEMENTS_SCHEMA]
     })

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
index af4933a..cacabc3 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts
@@ -16,10 +16,10 @@
  * limitations under the License.
  */
 
-import {Component, OnInit, Input, forwardRef} from '@angular/core';
+import {Component, forwardRef} from '@angular/core';
 import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
 import {Moment} from 'moment';
-import {FilteringService} from '@app/services/filtering.service';
+import {LogsContainerService} from '@app/services/logs-container.service';
 import {ListItem} from '@app/classes/list-item';
 import {TimeUnitListItem} from '@app/classes/filtering';
 
@@ -35,20 +35,11 @@ import {TimeUnitListItem} from '@app/classes/filtering';
     }
   ]
 })
-export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
+export class TimeRangePickerComponent implements ControlValueAccessor {
 
-  constructor(private filtering: FilteringService) {
+  constructor(private logsContainer: LogsContainerService) {
   }
 
-  ngOnInit() {
-    this.selectedLabel = this.defaultLabel;
-  }
-
-  @Input()
-  defaultLabel?: string;
-
-  selectedLabel: string;
-
   startTime: Moment;
 
   endTime: Moment;
@@ -56,18 +47,20 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
   private onChange: (fn: any) => void;
 
   get quickRanges(): (ListItem | TimeUnitListItem[])[] {
-    return this.filtering.filters.timeRange.options;
+    return this.logsContainer.filters.timeRange.options;
   }
 
-  private timeRange?: any;
+  private timeRange?: TimeUnitListItem;
 
-  get value(): any {
+  get selection(): TimeUnitListItem {
     return this.timeRange;
   }
 
-  set value(newValue: any) {
+  set selection(newValue: TimeUnitListItem) {
     this.timeRange = newValue;
-    this.onChange(newValue);
+    if (this.onChange) {
+      this.onChange(newValue);
+    }
   }
 
   setStartTime(timeObject: Moment): void {
@@ -79,20 +72,22 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor {
   }
 
   setTimeRange(value: any, label: string) {
-    this.value = value;
-    this.selectedLabel = label;
+    this.selection = {label, value};
   }
 
   setCustomTimeRange() {
-    this.value = {
-      type: 'CUSTOM',
-      start: this.startTime,
-      end: this.endTime
+    this.selection = {
+      label: 'filter.timeRange.custom',
+      value: {
+        type: 'CUSTOM',
+        start: this.startTime,
+        end: this.endTime
+      }
     };
-    this.selectedLabel = 'filter.timeRange.custom';
   }
 
-  writeValue() {
+  writeValue(selection: TimeUnitListItem) {
+    this.selection = selection;
   }
 
   registerOnChange(callback: any): void {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
index 53afc47..0e4c8a8 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/se
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {ComponentActionsService} from '@app/services/component-actions.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
@@ -90,7 +89,6 @@ describe('TimeZonePickerComponent', () => {
         ServiceLogsTruncatedService,
         TabsService,
         ComponentActionsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
index e6a02c0..6f54e65 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts
@@ -30,7 +30,6 @@ import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage
 import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service';
 import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service';
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
-import {FilteringService} from '@app/services/filtering.service';
 import {HttpClientService} from '@app/services/http-client.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 
@@ -78,7 +77,6 @@ describe('ComponentActionsService', () => {
         ServiceLogsHistogramDataService,
         ServiceLogsTruncatedService,
         TabsService,
-        FilteringService,
         {
           provide: HttpClientService,
           useValue: httpClient

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
index c483cd8..73fc94c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts
@@ -20,15 +20,17 @@ import {Injectable} from '@angular/core';
 import {AppSettingsService} from '@app/services/storage/app-settings.service';
 import {TabsService} from '@app/services/storage/tabs.service';
 import {CollectionModelService} from '@app/classes/models/store';
-import {FilteringService} from '@app/services/filtering.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {ServiceLog} from '@app/classes/models/service-log';
-import {getFiltersForm} from '@app/classes/filtering';
+import {ListItem} from '@app/classes/list-item';
 
 @Injectable()
 export class ComponentActionsService {
 
-  constructor(private appSettings: AppSettingsService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) {
+  constructor(
+    private appSettings: AppSettingsService, private tabsStorage: TabsService,
+    private logsContainer: LogsContainerService
+  ) {
   }
 
   //TODO implement actions
@@ -81,7 +83,6 @@ export class ComponentActionsService {
     const tab = {
       id: log.id,
       type: 'serviceLogs',
-      isActive: true,
       isCloseable: true,
       label: `${log.host} >> ${log.type}`,
       appState: {
@@ -92,7 +93,14 @@ export class ComponentActionsService {
           host_name: log.host,
           component_name: log.type
         },
-        activeFiltersForm: getFiltersForm('serviceLogs')
+        activeFilters: Object.assign(this.logsContainer.getFiltersData('serviceLogs'), {
+          components: this.logsContainer.filters.components.options.find((option: ListItem): boolean => {
+            return option.value === log.type;
+          }),
+          hosts: this.logsContainer.filters.hosts.options.find((option: ListItem): boolean => {
+            return option.value === log.host;
+          })
+        })
       }
     };
     this.tabsStorage.addInstance(tab);
@@ -104,11 +112,11 @@ export class ComponentActionsService {
   }
 
   startCapture(): void {
-    this.filtering.startCaptureTimer();
+    this.logsContainer.startCaptureTimer();
   }
 
   stopCapture(): void {
-    this.filtering.stopCaptureTimer();
+    this.logsContainer.stopCaptureTimer();
   }
 
   setTimeZone(timeZone: string): void {
@@ -121,7 +129,7 @@ export class ComponentActionsService {
     }));
   }
 
-  proceedWithExclude = (item: string): void => this.filtering.queryParameterNameChange.next({
+  proceedWithExclude = (item: string): void => this.logsContainer.queryParameterNameChange.next({
     item: item,
     isExclude: true
   });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7c4a7e4c/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
index 5dc38b4..a161190 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts
@@ -32,7 +32,6 @@ import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/s
 import {TabsService, tabs} from '@app/services/storage/tabs.service';
 import {LogsContainerService} from '@app/services/logs-container.service';
 import {HttpClientService} from '@app/services/http-client.service';
-import {FilteringService} from '@app/services/filtering.service';
 
 import {ComponentGeneratorService} from './component-generator.service';
 
@@ -70,7 +69,6 @@ describe('ComponentGeneratorService', () => {
           provide: HttpClientService,
           useValue: httpClient
         },
-        FilteringService,
         HostsService,
         AuditLogsService,
         ServiceLogsService,


[35/51] [abbrv] ambari git commit: AMBARI-22389. Exclude test scope jars from Log Search / Log Feeder rpm/deb packages (oleewere)

Posted by nc...@apache.org.
AMBARI-22389. Exclude test scope jars from Log Search / Log Feeder rpm/deb packages (oleewere)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 444718a10479c02dc6251ab8dc56eae70723f7bb
Parents: 38476f7
Author: Oliver Szabo <ol...@gmail.com>
Authored: Thu Nov 9 14:18:46 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Thu Nov 9 14:19:17 2017 +0100

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


http://git-wip-us.apache.org/repos/asf/ambari/blob/444718a1/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
index 6b7d94f..01710bf 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
@@ -240,12 +240,12 @@
 
             </goals>
             <configuration>
-              <artifactItems>*</artifactItems>
               <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
               <outputDirectory>${basedir}/target/libs</outputDirectory>
               <overWriteReleases>false</overWriteReleases>
               <overWriteSnapshots>false</overWriteSnapshots>
               <overWriteIfNewer>true</overWriteIfNewer>
+              <includeScope>compile</includeScope>
             </configuration>
           </execution>
         </executions>

http://git-wip-us.apache.org/repos/asf/ambari/blob/444718a1/ambari-logsearch/ambari-logsearch-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/pom.xml b/ambari-logsearch/ambari-logsearch-server/pom.xml
index 2ad35f5..5444b00 100755
--- a/ambari-logsearch/ambari-logsearch-server/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-server/pom.xml
@@ -118,13 +118,13 @@
                   <goal>copy-dependencies</goal>
                 </goals>
                 <configuration>
-                  <artifactItems>*</artifactItems>
                   <excludeArtifactIds>ambari-logsearch-web</excludeArtifactIds>
                   <outputAbsoluteArtifactFilename>true</outputAbsoluteArtifactFilename>
                   <outputDirectory>${basedir}/target/libs</outputDirectory>
                   <overWriteReleases>false</overWriteReleases>
                   <overWriteSnapshots>false</overWriteSnapshots>
                   <overWriteIfNewer>true</overWriteIfNewer>
+                  <includeScope>compile</includeScope>
                 </configuration>
               </execution>
             </executions>


[39/51] [abbrv] ambari git commit: AMBARI-22338 : Review Request for new HDP StackFeatures entry(mradhakrishnan on behalf of ydavis)

Posted by nc...@apache.org.
AMBARI-22338 : Review Request for new HDP StackFeatures entry(mradhakrishnan on behalf of ydavis)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: c693de3650d9b115a3da7639dbd97931c6ebb61b
Parents: 430dcbf
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Authored: Thu Nov 9 11:09:32 2017 -0800
Committer: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Committed: Thu Nov 9 11:09:32 2017 -0800

----------------------------------------------------------------------
 .../resources/stacks/HDP/2.0.6/properties/stack_features.json   | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c693de36/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
index 86de20d..702fb13 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
@@ -427,6 +427,11 @@
         "name": "hadoop_custom_extensions",
         "description": "Support hadoop custom extensions",
         "min_version": "2.6.0.0"
+      },
+      {
+        "name": "sam_storage_core_in_registry",
+        "description": "Storage core module moved to registry",
+        "min_version": "2.6.0.0"
       }
     ]
   }


[45/51] [abbrv] ambari git commit: AMBARI-22411. Restart all required services failed when running cluster with several patch upgrades applied (ncole)

Posted by nc...@apache.org.
AMBARI-22411. Restart all required services failed when running cluster with several patch upgrades applied (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 068d82f700432cf5cfa75d20924443e998d8fe87
Parents: ec02a14
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 10 11:23:13 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 10 12:00:14 2017 -0500

----------------------------------------------------------------------
 .../AmbariCustomCommandExecutionHelper.java     | 23 ++++----
 .../AmbariManagementControllerImpl.java         | 60 +++-----------------
 .../internal/UpgradeResourceProvider.java       |  8 +--
 .../HDP/2.0.6/properties/stack_packages.json    |  3 +-
 .../AmbariManagementControllerImplTest.java     |  2 +-
 5 files changed, 25 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
index e8febbb..dc6bbb7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java
@@ -1425,27 +1425,23 @@ public class AmbariCustomCommandExecutionHelper {
    *
    * @param actionExecContext  the context
    * @param cluster            the cluster for the command
+   * @param stackId            the stack id used to load service metainfo.
    *
    * @return a wrapper of the important JSON structures to add to a stage
    */
   public ExecuteCommandJson getCommandJson(ActionExecutionContext actionExecContext,
-      Cluster cluster, RepositoryVersionEntity repositoryVersion, String requestContext) throws AmbariException {
+      Cluster cluster, StackId stackId, String requestContext) throws AmbariException {
 
     Map<String, String> commandParamsStage = StageUtils.getCommandParamsStage(actionExecContext, requestContext);
     Map<String, String> hostParamsStage = new HashMap<>();
     Map<String, Set<String>> clusterHostInfo;
     String clusterHostInfoJson = "{}";
 
-    StackId stackId = null;
-    if (null != repositoryVersion) {
-      stackId = repositoryVersion.getStackId();
-    }
-
     if (null != cluster) {
       clusterHostInfo = StageUtils.getClusterHostInfo(cluster);
 
       // Important, because this runs during Stack Uprade, it needs to use the effective Stack Id.
-      hostParamsStage = createDefaultHostParams(cluster, repositoryVersion);
+      hostParamsStage = createDefaultHostParams(cluster, stackId);
 
       String componentName = null;
       String serviceName = null;
@@ -1454,7 +1450,7 @@ public class AmbariCustomCommandExecutionHelper {
         serviceName = actionExecContext.getOperationLevel().getServiceName();
       }
 
-      if (serviceName != null && componentName != null && null != stackId) {
+      if (serviceName != null && componentName != null) {
         Service service = cluster.getService(serviceName);
         ServiceComponent component = service.getServiceComponent(componentName);
         stackId = component.getDesiredStackId();
@@ -1473,6 +1469,10 @@ public class AmbariCustomCommandExecutionHelper {
 
       clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo);
 
+      if (null == stackId && null != cluster) {
+        stackId = cluster.getDesiredStackVersion();
+      }
+
       //Propogate HCFS service type info to command params
       if (null != stackId) {
         Map<String, ServiceInfo> serviceInfos = ambariMetaInfo.getServices(stackId.getStackName(),
@@ -1497,11 +1497,10 @@ public class AmbariCustomCommandExecutionHelper {
         hostParamsStageJson);
   }
 
-  Map<String, String> createDefaultHostParams(Cluster cluster, RepositoryVersionEntity repositoryVersion) throws AmbariException {
-    return createDefaultHostParams(cluster, repositoryVersion.getStackId());
-  }
-
   Map<String, String> createDefaultHostParams(Cluster cluster, StackId stackId) throws AmbariException {
+    if (null == stackId) {
+      stackId = cluster.getDesiredStackVersion();
+    }
 
     TreeMap<String, String> hostLevelParams = new TreeMap<>();
     StageUtils.useStackJdkIfExists(hostLevelParams, configs);

http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 380e1b4..4c00f1f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -68,6 +68,8 @@ import java.util.concurrent.TimeUnit;
 
 import javax.persistence.RollbackException;
 
+import org.apache.ambari.annotations.Experimental;
+import org.apache.ambari.annotations.ExperimentalFeature;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
@@ -2838,7 +2840,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
             if (StringUtils.isBlank(stage.getHostParamsStage())) {
               RepositoryVersionEntity repositoryVersion = serviceComponent.getDesiredRepositoryVersion();
               stage.setHostParamsStage(StageUtils.getGson().toJson(
-                  customCommandExecutionHelper.createDefaultHostParams(cluster, repositoryVersion)));
+                  customCommandExecutionHelper.createDefaultHostParams(cluster, repositoryVersion.getStackId())));
             }
 
 
@@ -3186,7 +3188,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
 
     Map<String, String> hostParamsCmd = customCommandExecutionHelper.createDefaultHostParams(
-        cluster, scHost.getServiceComponent().getDesiredRepositoryVersion());
+        cluster, scHost.getServiceComponent().getDesiredStackId());
 
     Stage stage = createNewStage(0, cluster, 1, "", clusterHostInfoJson, "{}", "");
 
@@ -4154,56 +4156,10 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         actionManager,
         actionRequest);
 
-    RepositoryVersionEntity desiredRepositoryVersion = null;
-
-    RequestOperationLevel operationLevel = actionExecContext.getOperationLevel();
-    if (null != operationLevel && StringUtils.isNotBlank(operationLevel.getServiceName())) {
-      Service service = cluster.getService(operationLevel.getServiceName());
-      if (null != service) {
-        desiredRepositoryVersion = service.getDesiredRepositoryVersion();
-      }
-    }
-
-    if (null == desiredRepositoryVersion && CollectionUtils.isNotEmpty(actionExecContext.getResourceFilters())) {
-      Set<RepositoryVersionEntity> versions = new HashSet<>();
-
-      for (RequestResourceFilter filter : actionExecContext.getResourceFilters()) {
-        RepositoryVersionEntity repoVersion = null;
-
-        if (StringUtils.isNotBlank(filter.getServiceName())) {
-          Service service = cluster.getService(filter.getServiceName());
-
-          if (StringUtils.isNotBlank(filter.getComponentName())) {
-            ServiceComponent serviceComponent = service.getServiceComponent(filter.getComponentName());
-
-            repoVersion = serviceComponent.getDesiredRepositoryVersion();
-          }
-
-          if (null == repoVersion) {
-            repoVersion = service.getDesiredRepositoryVersion();
-          }
-        }
-
-        if (null != repoVersion) {
-          versions.add(repoVersion);
-        }
-      }
-
-      if (1 == versions.size()) {
-        desiredRepositoryVersion = versions.iterator().next();
-      } else if (versions.size() > 1) {
-        Set<String> errors = new HashSet<>();
-        for (RepositoryVersionEntity version : versions) {
-          errors.add(String.format("%s/%s", version.getStackId(), version.getVersion()));
-        }
-        throw new IllegalArgumentException(String.format("More than one repository is resolved with this Action: %s",
-            StringUtils.join(errors, ';')));
-      }
-    }
-
-
-    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext,
-        cluster, desiredRepositoryVersion, requestContext);
+    @Experimental(feature=ExperimentalFeature.MULTI_SERVICE,
+        comment = "This must change with Multi-Service since the cluster won't have a desired stack version")
+    ExecuteCommandJson jsons = customCommandExecutionHelper.getCommandJson(actionExecContext, cluster,
+        null == cluster ? null : cluster.getDesiredStackVersion(), requestContext);
 
     String commandParamsForStage = jsons.getCommandParamsForStage();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index 14b1b86..d4111d6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -1073,7 +1073,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setAutoSkipFailures(context.isComponentFailureAutoSkipped());
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, effectiveRepositoryVersion, null);
+        cluster, effectiveRepositoryVersion.getStackId(), null);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1155,7 +1155,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, effectiveRepositoryVersion, null);
+        cluster, effectiveRepositoryVersion.getStackId(), null);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1220,7 +1220,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, effectiveRepositoryVersion, null);
+        cluster, effectiveRepositoryVersion.getStackId(), null);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), entity.getText(), jsons.getCommandParamsForStage(),
@@ -1361,7 +1361,7 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     actionContext.setMaintenanceModeHostExcluded(true);
 
     ExecuteCommandJson jsons = s_commandExecutionHelper.get().getCommandJson(actionContext,
-        cluster, context.getRepositoryVersion(), null);
+        cluster, context.getRepositoryVersion().getStackId(), null);
 
     Stage stage = s_stageFactory.get().createNew(request.getId().longValue(), "/tmp/ambari",
         cluster.getClusterName(), cluster.getClusterId(), stageText, jsons.getCommandParamsForStage(),

http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 23c6d32..68e6bf8 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -1277,8 +1277,7 @@
       }
     },
     "upgrade-dependencies" : {
-      "YARN": ["TEZ"],
-      "TEZ": ["YARN"],
+      "HIVE": ["TEZ"],
       "MAHOUT": ["MAPREDUCE2"]
     }    
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/068d82f7/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
index 9547271..94c5ebe 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerImplTest.java
@@ -2138,7 +2138,7 @@ public class AmbariManagementControllerImplTest {
     f.setAccessible(true);
     f.set(helper, gson);
 
-    Map<String, String> defaultHostParams = helper.createDefaultHostParams(cluster, repositoryVersionEntity);
+    Map<String, String> defaultHostParams = helper.createDefaultHostParams(cluster, repositoryVersionEntity.getStackId());
 
     assertEquals(15, defaultHostParams.size());
     assertEquals(MYSQL_JAR, defaultHostParams.get(DB_DRIVER_FILENAME));


[31/51] [abbrv] ambari git commit: AMBARI-22383. Remove Auto-Installation of LZO Libraries (ncole)

Posted by nc...@apache.org.
AMBARI-22383. Remove Auto-Installation of LZO Libraries (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5adcea78792cf227f15e7c08f5bb3fe2c48883d3
Parents: b04e142
Author: Nate Cole <nc...@hortonworks.com>
Authored: Wed Nov 8 14:28:59 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Nov 8 14:51:48 2017 -0500

----------------------------------------------------------------------
 .../libraries/functions/__init__.py             |  1 -
 .../libraries/functions/get_lzo_packages.py     | 50 --------------------
 .../libraries/functions/package_conditions.py   |  8 +---
 .../DRUID/0.10.1/package/scripts/druid.py       |  3 +-
 .../DRUID/0.10.1/package/scripts/params.py      |  3 +-
 .../common-services/HDFS/2.1.0.2.0/metainfo.xml | 30 ------------
 .../HDFS/2.1.0.2.0/package/scripts/datanode.py  |  1 -
 .../HDFS/2.1.0.2.0/package/scripts/hdfs.py      |  7 ---
 .../2.1.0.2.0/package/scripts/hdfs_client.py    |  1 -
 .../2.1.0.2.0/package/scripts/install_params.py |  1 +
 .../2.1.0.2.0/package/scripts/journalnode.py    |  1 -
 .../HDFS/2.1.0.2.0/package/scripts/namenode.py  |  1 -
 .../common-services/HDFS/3.0.0.3.0/metainfo.xml | 30 ------------
 .../HDFS/3.0.0.3.0/package/scripts/hdfs.py      |  7 ---
 .../OOZIE/4.0.0.2.0/package/scripts/oozie.py    |  6 +--
 .../package/scripts/oozie_server_upgrade.py     |  7 ++-
 .../4.0.0.2.0/package/scripts/params_linux.py   |  1 +
 .../OOZIE/4.2.0.3.0/package/scripts/oozie.py    |  4 --
 .../package/scripts/oozie_server_upgrade.py     |  5 ++
 .../TEZ/0.4.0.2.1/package/scripts/tez_client.py | 32 -------------
 .../TEZ/0.9.0.3.0/package/scripts/tez_client.py | 26 ----------
 .../custom_actions/scripts/remove_bits.py       |  2 +-
 .../BIGTOP/0.8/services/HDFS/metainfo.xml       | 16 -------
 .../0.8/services/HDFS/package/scripts/params.py |  6 +--
 .../stacks/HDP/2.2/services/HDFS/metainfo.xml   | 35 --------------
 .../2.3.GlusterFS/services/HDFS/metainfo.xml    | 10 ----
 .../stacks/HDP/2.3/services/HDFS/metainfo.xml   | 30 ------------
 .../stacks/HDP/3.0/services/HDFS/metainfo.xml   | 30 ------------
 .../python/custom_actions/TestRemoveBits.py     |  5 +-
 29 files changed, 20 insertions(+), 339 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py b/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
index f144b2d..1e388ac 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/__init__.py
@@ -39,7 +39,6 @@ from resource_management.libraries.functions.version import *
 from resource_management.libraries.functions.format_jvm_option import *
 from resource_management.libraries.functions.constants import *
 from resource_management.libraries.functions.get_stack_version import *
-from resource_management.libraries.functions.get_lzo_packages import *
 from resource_management.libraries.functions.setup_ranger_plugin import *
 from resource_management.libraries.functions.curl_krb_request import *
 from resource_management.libraries.functions.get_bare_principal import *

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py b/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
deleted file mode 100644
index cfbb7d8..0000000
--- a/ambari-common/src/main/python/resource_management/libraries/functions/get_lzo_packages.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-"""
-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.
-
-Ambari Agent
-
-"""
-__all__ = ["get_lzo_packages"]
-
-from ambari_commons.os_check import OSCheck
-from resource_management.libraries.functions.stack_features import check_stack_feature
-from resource_management.libraries.functions import StackFeature
-from resource_management.libraries.script.script import Script
-
-# TODO: Make list of lzo packages stack driven
-def get_lzo_packages(stack_version_unformatted):
-  lzo_packages = []
-  script_instance = Script.get_instance()
-  if OSCheck.is_suse_family() and int(OSCheck.get_os_major_version()) >= 12:
-    lzo_packages += ["liblzo2-2", "hadoop-lzo-native"]
-  elif OSCheck.is_redhat_family() or OSCheck.is_suse_family():
-    lzo_packages += ["lzo", "hadoop-lzo-native"]
-  elif OSCheck.is_ubuntu_family():
-    lzo_packages += ["liblzo2-2"]
-
-  if stack_version_unformatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_unformatted):
-    if OSCheck.is_ubuntu_family():
-      lzo_packages += [script_instance.format_package_name("hadooplzo-${stack_version}") ,
-                       script_instance.format_package_name("hadooplzo-${stack_version}-native")]
-    else:
-      lzo_packages += [script_instance.format_package_name("hadooplzo_${stack_version}"),
-                       script_instance.format_package_name("hadooplzo_${stack_version}-native")]
-  else:
-    lzo_packages += ["hadoop-lzo"]
-
-  return lzo_packages

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
index 31e78b9..ded63cf 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/package_conditions.py
@@ -19,7 +19,7 @@ limitations under the License.
 Ambari Agent
 
 """
-__all__ = ["is_lzo_enabled", "should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
+__all__ = ["should_install_phoenix", "should_install_ams_collector", "should_install_ams_grafana",
            "should_install_mysql", "should_install_ranger_tagsync"]
 
 import os
@@ -44,12 +44,6 @@ def _has_local_components(config, components, indicator_function = any):
 def _has_applicable_local_component(config, components):
   return _has_local_components(config, components, any)
 
-def should_install_lzo():
-  config = Script.get_config()
-  io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
-  lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
-  return lzo_enabled
-
 def should_install_phoenix():
   phoenix_hosts = default('/clusterHostInfo/phoenix_query_server_hosts', [])
   phoenix_enabled = default('/configurations/hbase-env/phoenix_sql_enabled', False)

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
index ec98c3c..bb872b9 100644
--- a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
+++ b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/druid.py
@@ -115,8 +115,7 @@ def druid(upgrade_type=None, nodeType=None):
          )
     Logger.info(format("Created druid-{node_type_lowercase} jvm.config"))
     # Handling hadoop Lzo jars if enable and node type is hadoop related eg Overlords and MMs
-    if ['middleManager', 'overlord'].__contains__(node_type_lowercase) and params.lzo_enabled and len(
-            params.lzo_packages) > 0:
+    if ['middleManager', 'overlord'].__contains__(node_type_lowercase) and params.lzo_enabled:
         try:
             Logger.info(
                 format(

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
index fd1cde6..141250d 100644
--- a/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/DRUID/0.10.1/package/scripts/params.py
@@ -18,7 +18,6 @@ limitations under the License.
 
 """
 from ambari_commons import OSCheck
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
 from resource_management.libraries.functions import conf_select
 from resource_management.libraries.functions import stack_select
 from resource_management.libraries.resources.hdfs_resource import HdfsResource
@@ -196,5 +195,5 @@ if has_metric_collector:
 stack_version_unformatted = str(config['hostLevelParams']['stack_version'])
 io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
 lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
-lzo_packages = get_lzo_packages(stack_version_unformatted)
+
 hadoop_lib_home = stack_root + '/' + stack_version + '/hadoop/lib'

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
index 9979de4..6bbb583 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/metainfo.xml
@@ -244,11 +244,6 @@
             <package>
               <name>hadoop</name>
             </package>
-            <package>
-              <name>hadoop-lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
           </packages>
         </osSpecific>
         
@@ -265,16 +260,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadoop-lzo-native</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-libhdfs</name>
             </package>
             <package>
@@ -296,16 +281,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadoop-lzo-native</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-libhdfs</name>
             </package>
           </packages>
@@ -324,11 +299,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-hdfs</name>
             </package>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
index c0abb15..a8b0f48 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/datanode.py
@@ -165,7 +165,6 @@ class DataNodeDefault(DataNode):
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class DataNodeWindows(DataNode):
   def install(self, env):
-    import install_params
     self.install_packages(env)
 
 if __name__ == "__main__":

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
index 4022986..1d7fe53 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs.py
@@ -26,7 +26,6 @@ from resource_management.core.source import Template
 from resource_management.core.resources.service import ServiceConfig
 from resource_management.libraries.resources.xml_config import XmlConfig
 
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
 from resource_management.core.exceptions import Fail
 from resource_management.core.logger import Logger
 from resource_management.libraries.functions.format import format
@@ -143,12 +142,6 @@ def hdfs(name=None):
        content=Template("slaves.j2")
   )
   
-  if params.lzo_enabled:
-    lzo_packages = get_lzo_packages(params.stack_version_unformatted)
-    Package(lzo_packages,
-            retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
-            retry_count=params.agent_stack_retry_count)
-      
 def install_snappy():
   import params
   Directory([params.so_target_dir_x86, params.so_target_dir_x64],

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
index f2e96c3..a802e08 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/hdfs_client.py
@@ -70,7 +70,6 @@ class HdfsClientDefault(HdfsClient):
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class HdfsClientWindows(HdfsClient):
   def install(self, env):
-    import install_params
     self.install_packages(env)
     self.configure(env)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
index 235f231..72850b3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/install_params.py
@@ -18,6 +18,7 @@ limitations under the License.
 """
 from ambari_commons import OSCheck
 
+exclude_packages = []
 # These parameters are supposed to be referenced at installation time, before the Hadoop environment variables have been set
 if OSCheck.is_windows_family():
   exclude_packages = []

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
index 75b2eeb..eaa21e9 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/journalnode.py
@@ -116,7 +116,6 @@ class JournalNodeDefault(JournalNode):
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class JournalNodeWindows(JournalNode):
   def install(self, env):
-    import install_params
     self.install_packages(env)
 
   def start(self, env):

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
index 291da05..5f4152d 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/namenode.py
@@ -327,7 +327,6 @@ class NameNodeDefault(NameNode):
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class NameNodeWindows(NameNode):
   def install(self, env):
-    import install_params
     self.install_packages(env)
     #TODO we need this for HA because of manual steps
     self.configure(env)

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
index e6d1166..0c629f3 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/metainfo.xml
@@ -270,11 +270,6 @@
             <package>
               <name>hadoop</name>
             </package>
-            <package>
-              <name>hadoop-lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
           </packages>
         </osSpecific>
         
@@ -291,16 +286,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadoop-lzo-native</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-libhdfs</name>
             </package>
           </packages>
@@ -319,16 +304,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadoop-lzo-native</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-libhdfs</name>
             </package>
           </packages>
@@ -347,11 +322,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop-hdfs</name>
             </package>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
index 4022986..89f9a1c 100644
--- a/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
+++ b/ambari-server/src/main/resources/common-services/HDFS/3.0.0.3.0/package/scripts/hdfs.py
@@ -26,7 +26,6 @@ from resource_management.core.source import Template
 from resource_management.core.resources.service import ServiceConfig
 from resource_management.libraries.resources.xml_config import XmlConfig
 
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
 from resource_management.core.exceptions import Fail
 from resource_management.core.logger import Logger
 from resource_management.libraries.functions.format import format
@@ -142,12 +141,6 @@ def hdfs(name=None):
        owner=tc_owner,
        content=Template("slaves.j2")
   )
-  
-  if params.lzo_enabled:
-    lzo_packages = get_lzo_packages(params.stack_version_unformatted)
-    Package(lzo_packages,
-            retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
-            retry_count=params.agent_stack_retry_count)
       
 def install_snappy():
   import params

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
index f215a1e..cd94244 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie.py
@@ -37,7 +37,6 @@ from resource_management.libraries.functions.copy_tarball import get_current_ver
 from resource_management.libraries.resources.xml_config import XmlConfig
 from resource_management.libraries.script.script import Script
 from resource_management.libraries.functions.security_commons import update_credential_provider_path
-from resource_management.libraries.functions.get_lzo_packages import get_lzo_packages
 from resource_management.core.resources.packaging import Package
 from resource_management.core.shell import as_user, as_sudo, call, checked_call
 from resource_management.core.exceptions import Fail
@@ -306,11 +305,8 @@ def oozie_server_specific(upgrade_type):
     Execute(format('{sudo} chown {oozie_user}:{user_group} {oozie_libext_dir}/falcon-oozie-el-extension-*.jar'),
       not_if  = no_op_test)
 
+  # just copying files is ok - we're not making assumptions about installing LZO here
   if params.lzo_enabled:
-    all_lzo_packages = get_lzo_packages(params.stack_version_unformatted)
-    Package(all_lzo_packages,
-            retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
-            retry_count=params.agent_stack_retry_count)
     Execute(format('{sudo} cp {hadoop_lib_home}/hadoop-lzo*.jar {oozie_lib_dir}'),
       not_if  = no_op_test,
     )

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
index 23b39ef..c9c07d1 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server_upgrade.py
@@ -61,10 +61,15 @@ class OozieUpgrade(Script):
     # <stack-selector-tool> set hadoop-client has not run yet, therefore we cannot use
     # <stack-root>/current/hadoop-client ; we must use params.version directly
     # however, this only works when upgrading beyond 2.2.0.0; don't do this
-    # for downgrade to 2.2.0.0 since hadoop-lzo will not be present
+    # for downgrade to 2.2.0.0 since hadoop-lzo will not be present.
+    #
     # This can also be called during a Downgrade.
+    #
     # When a version is Installed, it is responsible for downloading the hadoop-lzo packages
     # if lzo is enabled.
+    #
+    # This block is just copying around files - there is no assumption about installation
+    #
     if params.lzo_enabled and (params.upgrade_direction == Direction.UPGRADE or target_version_needs_compression_libraries):
       hadoop_lzo_pattern = 'hadoop-lzo*.jar'
       hadoop_client_new_lib_dir = format("{stack_root}/{version}/hadoop/lib")

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
index a0f0672..40901b6 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params_linux.py
@@ -387,3 +387,4 @@ is_webhdfs_enabled = config['configurations']['hdfs-site']['dfs.webhdfs.enabled'
 # The logic for LZO also exists in HDFS' params.py
 io_compression_codecs = default("/configurations/core-site/io.compression.codecs", None)
 lzo_enabled = io_compression_codecs is not None and "com.hadoop.compression.lzo" in io_compression_codecs.lower()
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
index 0771e93..19912fd 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie.py
@@ -276,10 +276,6 @@ def oozie_server_specific():
       not_if  = no_op_test)
 
   if params.lzo_enabled:
-    all_lzo_packages = get_lzo_packages(params.stack_version_unformatted)
-    Package(all_lzo_packages,
-            retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
-            retry_count=params.agent_stack_retry_count)
     Execute(format('{sudo} cp {hadoop_lib_home}/hadoop-lzo*.jar {oozie_lib_dir}'),
       not_if  = no_op_test,
     )

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
index 402c7cb..4fc1a42 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.2.0.3.0/package/scripts/oozie_server_upgrade.py
@@ -62,9 +62,14 @@ class OozieUpgrade(Script):
     # <stack-root>/current/hadoop-client ; we must use params.version directly
     # however, this only works when upgrading beyond 2.2.0.0; don't do this
     # for downgrade to 2.2.0.0 since hadoop-lzo will not be present
+    #
     # This can also be called during a Downgrade.
+    #
     # When a version is Installed, it is responsible for downloading the hadoop-lzo packages
     # if lzo is enabled.
+    #
+    # This block is just copying around files - there is no assumption about installation
+    #
     if params.lzo_enabled and (params.upgrade_direction == Direction.UPGRADE or target_version_needs_compression_libraries):
       hadoop_lzo_pattern = 'hadoop-lzo*.jar'
       hadoop_client_new_lib_dir = format("{stack_root}/{version}/hadoop/lib")

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
index ed3f5fd..dcf3e24 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/tez_client.py
@@ -19,22 +19,15 @@ Ambari Agent
 
 """
 import os
-import urlparse
 
 from ambari_commons import OSConst
-from ambari_commons.inet_utils import download_file
 from ambari_commons.os_family_impl import OsFamilyImpl
-from ambari_commons.os_utils import copy_file, extract_path_component
 
 from resource_management.core.exceptions import ClientComponentHasNoStatus
-from resource_management.core.source import InlineTemplate
 from resource_management.libraries.functions import stack_select
 from resource_management.libraries.functions import StackFeature
 from resource_management.libraries.functions.stack_features import check_stack_feature
-from resource_management.libraries.functions.get_stack_version import get_stack_version
 from resource_management.libraries.script.script import Script
-from resource_management.libraries.functions.default import default
-from resource_management.core.logger import Logger
 
 from tez import tez
 
@@ -96,33 +89,8 @@ class TezClientWindows(TezClient):
       self.install_packages(env)
       params.refresh_tez_state_dependent_params()
     env.set_params(params)
-    self._install_lzo_support_if_needed(params)
     self.configure(env, config_dir=params.tez_conf_dir)
 
-  def _install_lzo_support_if_needed(self, params):
-    hadoop_classpath_prefix = self._expand_hadoop_classpath_prefix(params.hadoop_classpath_prefix_template, params.config['configurations']['tez-site'])
-
-    hadoop_lzo_dest_path = extract_path_component(hadoop_classpath_prefix, "hadoop-lzo-")
-    if hadoop_lzo_dest_path:
-      hadoop_lzo_file = os.path.split(hadoop_lzo_dest_path)[1]
-
-      config = Script.get_config()
-      file_url = urlparse.urljoin(config['hostLevelParams']['jdk_location'], hadoop_lzo_file)
-      hadoop_lzo_dl_path = os.path.join(config["hostLevelParams"]["agentCacheDir"], hadoop_lzo_file)
-      download_file(file_url, hadoop_lzo_dl_path)
-      #This is for protection against configuration changes. It will infect every new destination with the lzo jar,
-      # but since the classpath points to the jar directly we're getting away with it.
-      if not os.path.exists(hadoop_lzo_dest_path):
-        copy_file(hadoop_lzo_dl_path, hadoop_lzo_dest_path)
-
-  def _expand_hadoop_classpath_prefix(self, hadoop_classpath_prefix_template, configurations):
-    import resource_management
-
-    hadoop_classpath_prefix_obj = InlineTemplate(hadoop_classpath_prefix_template, configurations_dict=configurations,
-                                                 extra_imports=[resource_management, resource_management.core,
-                                                                resource_management.core.source])
-    hadoop_classpath_prefix = hadoop_classpath_prefix_obj.get_content()
-    return hadoop_classpath_prefix
 
 if __name__ == "__main__":
   TezClient().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
index b42d14e..0dfab4f 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/tez_client.py
@@ -98,33 +98,7 @@ class TezClientWindows(TezClient):
       self.install_packages(env)
       params.refresh_tez_state_dependent_params()
     env.set_params(params)
-    self._install_lzo_support_if_needed(params)
     self.configure(env, config_dir=params.tez_conf_dir)
 
-  def _install_lzo_support_if_needed(self, params):
-    hadoop_classpath_prefix = self._expand_hadoop_classpath_prefix(params.hadoop_classpath_prefix_template, params.config['configurations']['tez-site'])
-
-    hadoop_lzo_dest_path = extract_path_component(hadoop_classpath_prefix, "hadoop-lzo-")
-    if hadoop_lzo_dest_path:
-      hadoop_lzo_file = os.path.split(hadoop_lzo_dest_path)[1]
-
-      config = Script.get_config()
-      file_url = urlparse.urljoin(config['hostLevelParams']['jdk_location'], hadoop_lzo_file)
-      hadoop_lzo_dl_path = os.path.join(config["hostLevelParams"]["agentCacheDir"], hadoop_lzo_file)
-      download_file(file_url, hadoop_lzo_dl_path)
-      #This is for protection against configuration changes. It will infect every new destination with the lzo jar,
-      # but since the classpath points to the jar directly we're getting away with it.
-      if not os.path.exists(hadoop_lzo_dest_path):
-        copy_file(hadoop_lzo_dl_path, hadoop_lzo_dest_path)
-
-  def _expand_hadoop_classpath_prefix(self, hadoop_classpath_prefix_template, configurations):
-    import resource_management
-
-    hadoop_classpath_prefix_obj = InlineTemplate(hadoop_classpath_prefix_template, configurations_dict=configurations,
-                                                 extra_imports=[resource_management, resource_management.core,
-                                                                resource_management.core.source])
-    hadoop_classpath_prefix = hadoop_classpath_prefix_obj.get_content()
-    return hadoop_classpath_prefix
-
 if __name__ == "__main__":
   TezClient().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py b/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
index 0be9a34..078cf32 100644
--- a/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
+++ b/ambari-server/src/main/resources/custom_actions/scripts/remove_bits.py
@@ -43,7 +43,7 @@ class RemoveBits(Script):
     Logger.info("Attempting to remove bits for HDP 2.1")
     config = Script.get_config()
 
-    packages_to_remove = ["zookeeper", "hadoop", "hadoop-lzo", "hadoop-hdfs", "hadoop-libhdfs", "hadoop-yarn", "hadoop-client", "hadoop-mapreduce", "hive", "hive-hcatalog", "hive-jdbc", "hive-webhcat", "hcatalog", "webhcat-tar-hive", "webhcat-tar-pig", "oozie", "oozie-client", "pig", "sqoop", "tez" "falcon", "storm", "flume", "hbase", "phoenix"]
+    packages_to_remove = ["zookeeper", "hadoop", "hadoop-hdfs", "hadoop-libhdfs", "hadoop-yarn", "hadoop-client", "hadoop-mapreduce", "hive", "hive-hcatalog", "hive-jdbc", "hive-webhcat", "hcatalog", "webhcat-tar-hive", "webhcat-tar-pig", "oozie", "oozie-client", "pig", "sqoop", "tez" "falcon", "storm", "flume", "hbase", "phoenix"]
     packages_to_remove.reverse()
     Logger.info("Packages to remove: {0}".format(" ".join(packages_to_remove)))
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
index 8500839..f473598 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/metainfo.xml
@@ -180,10 +180,6 @@
             <package>
               <name>hadoop</name>
             </package>
-            <package>
-              <name>hadoop-lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
           </packages>
         </osSpecific>
         
@@ -197,14 +193,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-            <package>
-              <name>hadoop-lzo-native</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-            <package>
               <name>hadoop-libhdfs</name>
             </package>
           </packages>
@@ -220,10 +208,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-            <package>
               <name>hadoop-hdfs</name>
             </package>
             <package>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
index 3a711c7..f16242c 100644
--- a/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/BIGTOP/0.8/services/HDFS/package/scripts/params.py
@@ -209,11 +209,7 @@ HdfsDirectory = functools.partial(
   bin_dir = hadoop_bin_dir
 )
 
-io_compression_codecs = config['configurations']['core-site']['io.compression.codecs']
-if not "com.hadoop.compression.lzo" in io_compression_codecs:
-  exclude_packages = ["lzo", "hadoop-lzo", "hadoop-lzo-native", "liblzo2-2"]
-else:
-  exclude_packages = []
+exclude_packages = []
 name_node_params = default("/commandParams/namenode", None)
 
 #hadoop params

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
index 8c2ec8b..d7221b9 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
@@ -40,19 +40,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
             <package>
@@ -77,19 +64,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
           </packages>
@@ -123,15 +97,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>hadooplzo-${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>libhdfs0-${stack_version}</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
index 15fe931..6a9fab61 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3.GlusterFS/services/HDFS/metainfo.xml
@@ -36,13 +36,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-            </package>
-            <package>
-              <name>hadooplzo_2_3_*</name>
-            </package>
-            <package>
               <name>hadoop_2_3_*-libhdfs</name>
             </package>
           </packages>
@@ -76,9 +69,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>hadooplzo-2-3-.*</name>
-            </package>
-            <package>
               <name>libhdfs0-2-3-.*</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
index ccf9a4e..86531cc 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/HDFS/metainfo.xml
@@ -72,19 +72,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
             <package>
@@ -109,19 +96,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
           </packages>
@@ -155,10 +129,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>hadooplzo-${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>libhdfs0-${stack_version}</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
index 95a5f84..775508e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/services/HDFS/metainfo.xml
@@ -50,19 +50,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>lzo</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
           </packages>
@@ -84,19 +71,6 @@
               <name>snappy-devel</name>
             </package>
             <package>
-              <name>liblzo2-2</name>
-              <skipUpgrade>true</skipUpgrade>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
-              <name>hadooplzo_${stack_version}-native</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>hadoop_${stack_version}-libhdfs</name>
             </package>
           </packages>
@@ -130,10 +104,6 @@
               <name>libsnappy-dev</name>
             </package>
             <package>
-              <name>hadooplzo-${stack_version}</name>
-              <condition>should_install_lzo</condition>
-            </package>
-            <package>
               <name>libhdfs0-${stack_version}</name>
             </package>
           </packages>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5adcea78/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/TestRemoveBits.py b/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
index 6537152..8217ca0 100644
--- a/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
+++ b/ambari-server/src/test/python/custom_actions/TestRemoveBits.py
@@ -105,13 +105,10 @@ class TestRemoveBits(RMFTestCase):
     self.assertResourceCalled('Package', 'hadoop-hdfs',
                               action = ['remove'],
                               )
-    self.assertResourceCalled('Package', 'hadoop-lzo',
-                              action = ['remove'],
-                              )
     self.assertResourceCalled('Package', 'hadoop',
                               action = ['remove'],
                               )
     self.assertResourceCalled('Package', 'zookeeper',
                               action = ['remove'],
                               )
-    self.assertNoMoreResources()
\ No newline at end of file
+    self.assertNoMoreResources()


[13/51] [abbrv] ambari git commit: AMBARI-22362 - Specify the Correct HIVE_BIN In Hive Scripts (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22362  - Specify the Correct HIVE_BIN In Hive Scripts (jonathanhurley)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: afb9a66e24d718a17be87af412a44d4def7273a3
Parents: 65ea560
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Nov 3 10:07:54 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Nov 3 14:25:36 2017 -0400

----------------------------------------------------------------------
 .../0.12.0.2.0/package/files/startMetastore.sh    |  4 ++--
 .../0.12.0.2.0/package/scripts/hive_service.py    | 10 ++--------
 .../0.12.0.2.0/package/scripts/params_linux.py    |  3 +--
 .../0.12.0.2.0/package/scripts/service_check.py   |  6 ++----
 .../2.1.0.3.0/package/files/startMetastore.sh     |  4 ++--
 .../2.1.0.3.0/package/scripts/hive_service.py     |  8 +-------
 .../2.1.0.3.0/package/scripts/params_linux.py     |  3 +--
 .../2.1.0.3.0/package/scripts/service_check.py    |  6 ++----
 .../stacks/2.0.6/HIVE/test_hive_metastore.py      |  8 +++-----
 .../python/stacks/2.0.6/HIVE/test_hive_server.py  | 18 ++++++------------
 .../stacks/2.0.6/HIVE/test_hive_service_check.py  |  2 +-
 .../python/stacks/2.1/HIVE/test_hive_metastore.py |  9 +++------
 12 files changed, 26 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
index 86541f0..5a556b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/files/startMetastore.sh
@@ -19,7 +19,7 @@
 # under the License.
 #
 #
-HIVE_BIN=${HIVE_BIN:-"hive"}
+HIVE_CMD=${HIVE_CMD:-"hive"}
 
-HIVE_CONF_DIR=$4 $HIVE_BIN --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
+HIVE_CONF_DIR=$4 $HIVE_CMD --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
 echo $!|cat>$3

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
index 2412bf9..05aedc1 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
@@ -76,8 +76,6 @@ def hive_service(name, action='start', upgrade_type=None):
       check_fs_root(params.hive_server_conf_dir, params.execute_path)
 
     daemon_cmd = cmd
-    hadoop_home = params.hadoop_home
-    hive_bin = "hive"
 
     # upgrading hiveserver2 (rolling_restart) means that there is an existing,
     # de-registering hiveserver2; the pid will still exist, but the new
@@ -85,13 +83,9 @@ def hive_service(name, action='start', upgrade_type=None):
     if upgrade_type == UPGRADE_TYPE_ROLLING:
       process_id_exists_command = None
 
-      if params.version and params.stack_root:
-        hadoop_home = format("{stack_root}/{version}/hadoop")
-        hive_bin = os.path.join(params.hive_bin, hive_bin)
-      
-    Execute(daemon_cmd, 
+    Execute(daemon_cmd,
       user = params.hive_user,
-      environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_bin },
+      environment = { 'JAVA_HOME': params.java64_home, 'HIVE_CMD': params.hive_cmd },
       path = params.execute_path,
       not_if = process_id_exists_command)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
index 16e1a71..ea8beaf 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
@@ -112,6 +112,7 @@ component_directory_interactive = status_params.component_directory_interactive
 hadoop_home = stack_select.get_hadoop_dir("home")
 
 hive_bin = format('{stack_root}/current/{component_directory}/bin')
+hive_cmd = os.path.join(hive_bin, "hive")
 hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')
 hive_schematool_bin = format('{stack_root}/current/{component_directory}/bin')
 hive_lib = format('{stack_root}/current/{component_directory}/lib')
@@ -186,8 +187,6 @@ hive_server_conf_dir = status_params.hive_server_conf_dir
 
 hcat_conf_dir = '/etc/hive-hcatalog/conf'
 config_dir = '/etc/hive-webhcat/conf'
-hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
-webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
 
 # there are no client versions of these, use server versions directly
 hcat_lib = format('{stack_root}/current/hive-webhcat/share/hcatalog')

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
index 271fff9..852d7bf 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/service_check.py
@@ -171,10 +171,8 @@ class HiveServiceCheckDefault(HiveServiceCheck):
     if kinit_cmd:
       beeline_url.append('principal={key}')
 
-    exec_path = params.execute_path
-    if params.version:
-      upgrade_hive_bin = format("{stack_root}/{version}/hive2/bin")
-      exec_path =  os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + upgrade_hive_bin
+    hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin")
+    exec_path =  os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + hive_interactive_bin
 
     # beeline path
     llap_cmd = "! beeline -u '%s'" % format(";".join(beeline_url))

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
index 86541f0..5a556b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/files/startMetastore.sh
@@ -19,7 +19,7 @@
 # under the License.
 #
 #
-HIVE_BIN=${HIVE_BIN:-"hive"}
+HIVE_CMD=${HIVE_CMD:-"hive"}
 
-HIVE_CONF_DIR=$4 $HIVE_BIN --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
+HIVE_CONF_DIR=$4 $HIVE_CMD --service metastore -hiveconf hive.log.file=hivemetastore.log -hiveconf hive.log.dir=$5 > $1 2> $2 &
 echo $!|cat>$3

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
index 1f2b644..80471ea 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service.py
@@ -76,8 +76,6 @@ def hive_service(name, action='start', upgrade_type=None):
       check_fs_root(params.hive_server_conf_dir, params.execute_path)
 
     daemon_cmd = cmd
-    hadoop_home = params.hadoop_home
-    hive_bin = "hive"
 
     # upgrading hiveserver2 (rolling_restart) means that there is an existing,
     # de-registering hiveserver2; the pid will still exist, but the new
@@ -85,13 +83,9 @@ def hive_service(name, action='start', upgrade_type=None):
     if upgrade_type == UPGRADE_TYPE_ROLLING:
       process_id_exists_command = None
 
-      if params.version and params.stack_root:
-        hadoop_home = format("{stack_root}/{version}/hadoop")
-        hive_bin = os.path.join(params.hive_bin, hive_bin)
-      
     Execute(daemon_cmd, 
       user = params.hive_user,
-      environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_bin },
+      environment = { 'JAVA_HOME': params.java64_home, 'HIVE_CMD': params.hive_cmd },
       path = params.execute_path,
       not_if = process_id_exists_command)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
index fb2c84a..1bd6a1a 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
@@ -109,6 +109,7 @@ component_directory_interactive = status_params.component_directory_interactive
 
 hadoop_home = format('{stack_root}/current/hadoop-client')
 hive_bin = format('{stack_root}/current/{component_directory}/bin')
+hive_cmd = os.path.join(hive_bin, "hive")
 hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')
 hive_schematool_bin = format('{stack_root}/current/{component_directory}/bin')
 hive_lib = format('{stack_root}/current/{component_directory}/lib')
@@ -183,8 +184,6 @@ hive_server_conf_dir = status_params.hive_server_conf_dir
 
 hcat_conf_dir = '/etc/hive-hcatalog/conf'
 config_dir = '/etc/hive-webhcat/conf'
-hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
-webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
 
 # there are no client versions of these, use server versions directly
 hcat_lib = format('{stack_root}/current/hive-webhcat/share/hcatalog')

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
index d144c34..ce434b6 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/service_check.py
@@ -170,10 +170,8 @@ class HiveServiceCheckDefault(HiveServiceCheck):
     if kinit_cmd:
       beeline_url.append('principal={key}')
 
-    exec_path = params.execute_path
-    if params.version:
-      upgrade_hive_bin = format("{stack_root}/{version}/hive2/bin")
-      exec_path =  os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + upgrade_hive_bin
+    hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin")
+    exec_path =  os.environ['PATH'] + os.pathsep + params.hadoop_bin_dir + os.pathsep + hive_interactive_bin
 
     # beeline path
     llap_cmd = "! beeline -u '%s'" % format(";".join(beeline_url))

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
index 1baed03..bacfe3c 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_metastore.py
@@ -62,8 +62,7 @@ class TestHiveMetastore(RMFTestCase):
     self.assert_configure_default()
     self.assert_init_schema()
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -123,8 +122,7 @@ class TestHiveMetastore(RMFTestCase):
     self.assert_configure_secured()
     self.assert_init_schema()
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -552,7 +550,7 @@ class TestHiveMetastore(RMFTestCase):
         user = 'hive')
 
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.3.0.0-1234/hadoop', 'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45', 'HIVE_BIN': '/usr/hdp/current/hive-server2/bin/hive'},
+        environment = {'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45', 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive'},
         not_if = None,
         user = 'hive',
         path = ['/bin:/usr/hdp/current/hive-server2/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin'])

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
index c1fb5a2..87467ac 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_server.py
@@ -93,8 +93,7 @@ class TestHiveServer(RMFTestCase):
                               user='hive'
     )
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -124,8 +123,7 @@ class TestHiveServer(RMFTestCase):
     self.assert_configure_default(default_fs_default='hcfs://c6401.ambari.apache.org:8020')
 
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-                              environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-                                             'HIVE_BIN': 'hive',
+                              environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
                                              'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user = 'hive',
@@ -155,8 +153,7 @@ class TestHiveServer(RMFTestCase):
                               user = 'hive',
                               )
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -186,8 +183,7 @@ class TestHiveServer(RMFTestCase):
                               user = 'hive',
                               )
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -217,8 +213,7 @@ class TestHiveServer(RMFTestCase):
                               user = 'hive',
                               )
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -290,8 +285,7 @@ class TestHiveServer(RMFTestCase):
 
     self.assert_configure_secured()
     self.assertResourceCalled('Execute', '/tmp/start_hiveserver2_script /var/log/hive/hive-server2.out /var/log/hive/hive-server2.err /var/run/hive/hive-server.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': 'mock_hadoop_dir',
-           'HIVE_BIN': 'hive',
+        environment = { 'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive-server.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
index 7efb5fd..157b25c 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_hive_service_check.py
@@ -340,7 +340,7 @@ class TestServiceCheck(RMFTestCase):
     # LLAP call
     self.assertResourceCalled('Execute',
       "! beeline -u 'jdbc:hive2://c6402.ambari.apache.org:10500/;transportMode=binary' --hiveconf \"hiveLlapServiceCheck=\" -f /usr/hdp/current/hive-server2-hive2/scripts/llap/sql/serviceCheckScript.sql -e '' 2>&1| awk '{print}'|grep -i -e 'Invalid status\|Invalid URL\|command not found\|Connection refused'",
-      path = ['/usr/sbin', '/usr/local/bin', '/bin', '/usr/bin', '/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin:/usr/hdp/2.3.0.0-1234/hive2/bin'],
+      path = ['/usr/sbin', '/usr/local/bin', '/bin', '/usr/bin', '/bin:/usr/hdp/2.3.0.0-1234/hadoop/bin:/usr/hdp/current/hive-server2-hive2/bin'],
       tries = 1,
       stderr = -1,
       wait_for_finish = True,

http://git-wip-us.apache.org/repos/asf/ambari/blob/afb9a66e/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py b/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
index db4e2a1..d91bcf4 100644
--- a/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
+++ b/ambari-server/src/test/python/stacks/2.1/HIVE/test_hive_metastore.py
@@ -70,8 +70,7 @@ class TestHiveMetastore(RMFTestCase):
     self.assert_init_schema('aaa')
 
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
-           'HIVE_BIN': 'hive',
+        environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -101,8 +100,7 @@ class TestHiveMetastore(RMFTestCase):
     self.assert_init_schema('aaa')
 
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
-           'HIVE_BIN': 'hive',
+        environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',
@@ -164,8 +162,7 @@ class TestHiveMetastore(RMFTestCase):
     self.assert_configure_secured()
     self.assert_init_schema('asd')
     self.assertResourceCalled('Execute', '/tmp/start_metastore_script /var/log/hive/hive.out /var/log/hive/hive.err /var/run/hive/hive.pid /usr/hdp/current/hive-server2/conf/conf.server /var/log/hive',
-        environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-           'HIVE_BIN': 'hive',
+        environment = {'HIVE_CMD': '/usr/hdp/current/hive-server2/bin/hive',
            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
         not_if = "ls /var/run/hive/hive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
         user = 'hive',


[08/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
new file mode 100644
index 0000000..06824bf
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/assets/fonts/Roboto-Regular-webfont.svg
@@ -0,0 +1,7606 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="robotoregular" horiz-adv-x="1164" >
+<font-face units-per-em="2048" ascent="1638" descent="-410" />
+<missing-glyph horiz-adv-x="509" />
+<glyph unicode="fi" horiz-adv-x="1140" d="M28 936v146h170v117q0 182 106.5 282t295.5 100q67 0 132 -15.5t153 -45.5l-34 -160q-53 21 -113 36t-123 15q-117 0 -168.5 -52t-51.5 -160v-117h215v-146h-215v-936h-197v936h-170zM783 0v1082h198v-1082h-198z" />
+<glyph unicode=" "  horiz-adv-x="509" />
+<glyph unicode="&#x09;" horiz-adv-x="509" />
+<glyph unicode="&#xa0;" horiz-adv-x="509" />
+<glyph unicode="!" horiz-adv-x="539" d="M171 0v204h198v-204h-198zM171 478v978h197v-978h-197z" />
+<glyph unicode="&#x22;" horiz-adv-x="668" d="M80 1040l1 240v280h197v-270l-101 -250h-97zM389 1040l1 248v272h197v-270l-101 -250h-97z" />
+<glyph unicode="#" horiz-adv-x="1276" d="M70 410v140h264l68 348h-256v142h284l82 416h151l-82 -416h255l82 416h151l-82 -416h199v-142h-226l-68 -348h219v-140h-247l-80 -410h-152l80 410h-255l-80 -410h-151l80 410h-236zM485 550h255l68 348h-255z" />
+<glyph unicode="$" horiz-adv-x="1153" d="M114 424l2 5h190q0 -154 77.5 -219.5t190.5 -65.5q129 0 201.5 61.5t72.5 170.5q0 89 -64 153t-210 114q-202 61 -305 163t-103 272q0 165 94.5 269t260.5 125v221h158v-222q168 -24 260.5 -143.5t92.5 -320.5h-196q0 136 -63 220t-175 84q-118 0 -176.5 -61.5 t-58.5 -168.5q0 -97 60.5 -157t218.5 -114q205 -66 304 -164.5t99 -267.5q0 -172 -103 -273.5t-283 -120.5v-192h-157v191q-172 18 -282 125.5t-106 315.5z" />
+<glyph unicode="%" horiz-adv-x="1498" d="M104 1099v77q0 127 82 214t219 87t219 -86.5t82 -214.5v-77q0 -127 -81.5 -213t-217.5 -86q-138 0 -220.5 86t-82.5 213zM250 1099q0 -74 40.5 -125.5t116.5 -51.5q73 0 113 51t40 126v77q0 74 -40.5 126.5t-114.5 52.5q-75 0 -115 -52.5t-40 -126.5v-77zM349 177 l711 1138l109 -67l-711 -1138zM809 279v78q0 127 82 213.5t219 86.5q136 0 218.5 -86.5t82.5 -213.5v-78q0 -128 -82 -214t-217 -86q-138 0 -220.5 86t-82.5 214zM955 279q0 -75 40.5 -126.5t116.5 -51.5q73 0 113 51.5t40 126.5v78q0 74 -41 126t-114 52q-74 0 -114.5 -52 t-40.5 -126v-78z" />
+<glyph unicode="&#x26;" horiz-adv-x="1276" d="M64 392q0 122 70.5 213.5t210.5 183.5q-78 99 -116 176.5t-38 159.5q0 169 97.5 260.5t268.5 91.5q158 0 257 -91t99 -219q0 -98 -52.5 -169.5t-155.5 -146.5l-109 -80l340 -409q41 65 64 144t23 167h176q0 -132 -39 -244t-113 -201l185 -223l-2 -5h-229l-85 102 q-80 -60 -177 -91.5t-201 -31.5q-217 0 -345.5 115t-128.5 298zM261 392q0 -113 71 -186t206 -73q72 0 142 24.5t132 70.5l-361 435l-40 -29q-91 -68 -120.5 -130t-29.5 -112zM388 1127q0 -53 27 -110.5t81 -125.5l138 95q57 38 77.5 82.5t20.5 98.5q0 61 -48.5 108 t-126.5 47q-81 0 -125 -56.5t-44 -138.5z" />
+<glyph unicode="'" horiz-adv-x="359" d="M80 1055l1 265v240h197v-223l-101 -282h-97z" />
+<glyph unicode="(" horiz-adv-x="679" d="M132 582v9q0 394 159 673t334 372l6 -1l38 -116q-137 -107 -238.5 -343t-101.5 -583v-13q0 -347 101 -583t239 -352l-38 -108h-6q-175 93 -334 371.5t-159 673.5z" />
+<glyph unicode=")" horiz-adv-x="687" d="M6 -355q135 105 237.5 345.5t102.5 589.5v13q0 342 -105.5 583.5t-234.5 351.5l38 108h6q174 -93 333.5 -372t159.5 -673v-9q0 -395 -159.5 -673.5t-333.5 -371.5h-6z" />
+<glyph unicode="*" horiz-adv-x="884" d="M28 1071l49 154l296 -111l-10 342h161l-10 -348l293 110l48 -156l-302 -89l193 -270l-131 -96l-181 287l-176 -279l-132 93l198 274z" />
+<glyph unicode="+" horiz-adv-x="1162" d="M78 605v178h402v423h197v-423h399v-178h-399v-459h-197v459h-402z" />
+<glyph unicode="," horiz-adv-x="404" d="M48 -258l70 316v163h197v-173l-150 -306h-117z" />
+<glyph unicode="-" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="." horiz-adv-x="548" d="M161 0v202h197v-202h-197z" />
+<glyph unicode="/" horiz-adv-x="850" d="M16 -125l608 1581h167l-607 -1581h-168z" />
+<glyph unicode="0" horiz-adv-x="1154" d="M113 555v345q0 278 124.5 427.5t338.5 149.5q215 0 339.5 -149.5t124.5 -427.5v-345q0 -279 -123.5 -427.5t-338.5 -148.5t-340 149t-125 427zM310 515q0 -189 69 -285.5t199 -96.5t197.5 96t67.5 286v427q0 189 -68.5 284.5t-198.5 95.5t-198 -95.5t-68 -284.5v-427z " />
+<glyph unicode="1" horiz-adv-x="1153" d="M186 1260v142l495 54v-1456h-197v1264z" />
+<glyph unicode="2" horiz-adv-x="1153" d="M97 1033q-5 188 125 316t360 128q196 0 312.5 -114.5t116.5 -291.5q0 -119 -70.5 -238.5t-197.5 -256.5l-383 -417l2 -5h700v-154h-944v135l477 530q128 143 173.5 227t45.5 172q0 109 -63.5 183.5t-168.5 74.5q-151 0 -222.5 -77.5t-71.5 -217.5h-189z" />
+<glyph unicode="3" horiz-adv-x="1153" d="M100 378l3 6h188q0 -115 70.5 -183t193.5 -68q125 0 196 68t71 201q0 135 -63 199t-199 64h-172v154h172q131 0 185.5 65.5t54.5 182.5q0 125 -62 190t-183 65q-115 0 -184.5 -67.5t-69.5 -179.5h-189l-2 6q-5 165 119.5 280.5t325.5 115.5q202 0 322 -107.5t120 -306.5 q0 -90 -54.5 -179.5t-163.5 -136.5q131 -43 185.5 -135t54.5 -206q0 -199 -130.5 -313t-333.5 -114q-199 0 -329.5 107.5t-125.5 291.5z" />
+<glyph unicode="4" horiz-adv-x="1153" d="M55 336v111l642 1009h208v-966h201v-154h-201v-336h-196v336h-654zM265 490h444v683l-6 1l-19 -50z" />
+<glyph unicode="5" horiz-adv-x="1153" d="M157 377l2 6h178q0 -119 68.5 -184.5t177.5 -65.5q125 0 194 88t69 241q0 140 -70 230t-193 90q-116 0 -168 -35t-76 -107l-164 17l84 799h729v-175h-562l-48 -409q46 34 102.5 56.5t130.5 24.5q201 2 316.5 -131t115.5 -358q0 -219 -117.5 -352t-342.5 -133 q-185 0 -308 101t-118 297z" />
+<glyph unicode="6" horiz-adv-x="1153" d="M132 571v278q0 280 156 454t387 174q75 0 148.5 -17t121.5 -43l-42 -151q-49 25 -102.5 40.5t-125.5 15.5q-156 0 -251.5 -125t-95.5 -326v-23q64 56 146.5 87.5t177.5 31.5q195 0 311 -135t116 -342q0 -226 -123.5 -368.5t-329.5 -142.5q-214 0 -354 155t-140 437z M328 552q0 -201 85 -310t213 -109q121 0 188.5 102.5t67.5 254.5q0 144 -72.5 237t-201.5 93q-101 0 -172 -41t-108 -109v-118z" />
+<glyph unicode="7" horiz-adv-x="1153" d="M77 1301v155h985v-155q-264 -314 -356.5 -556.5t-133.5 -587.5l-16 -157h-197l16 157q42 344 163 615t331 529h-792z" />
+<glyph unicode="8" horiz-adv-x="1153" d="M102 394q0 123 74 217t200 138q-109 42 -171 127.5t-62 199.5q0 192 118.5 296.5t313.5 104.5q192 0 313.5 -104.5t121.5 -296.5q0 -114 -64 -199.5t-173 -127.5q126 -44 201.5 -138t75.5 -217q0 -202 -131.5 -308.5t-341.5 -106.5q-214 0 -344.5 106.5t-130.5 308.5z M299 398q0 -124 76 -194.5t202 -70.5q123 0 200 71t77 194q0 120 -79 197t-200 77q-123 0 -199.5 -77t-76.5 -197zM340 1072q0 -111 65.5 -178t171.5 -67q104 0 170 67t66 178q0 108 -67.5 179t-170.5 71q-105 0 -170 -68.5t-65 -181.5z" />
+<glyph unicode="9" horiz-adv-x="1153" d="M83 978q0 219 131.5 359t319.5 140q228 0 359.5 -142.5t131.5 -419.5v-347q0 -285 -142.5 -437t-371.5 -152q-77 0 -156.5 14.5t-142.5 44.5l30 151q59 -31 122.5 -43.5t146.5 -12.5q144 0 230.5 109t86.5 324v66q-49 -71 -122.5 -107.5t-163.5 -36.5q-211 0 -335 130.5 t-124 359.5zM280 978q0 -150 70.5 -243t191.5 -93q109 0 181.5 47t104.5 120v126q0 191 -73.5 289t-214.5 98q-108 0 -184 -96.5t-76 -247.5z" />
+<glyph unicode=":" horiz-adv-x="517" d="M161 0v202h197v-202h-197zM161 876v202h197v-202h-197z" />
+<glyph unicode=";" horiz-adv-x="525" d="M99 -258l70 316v163h197v-173l-150 -306h-117zM162 876v202h197v-202h-197z" />
+<glyph unicode="&#x3c;" horiz-adv-x="1040" d="M71 466v149l816 378v-201l-559 -233l-85 -18v-6l85 -19l559 -228v-201z" />
+<glyph unicode="=" horiz-adv-x="1153" d="M152 407v164h834v-164h-834zM152 823v164h834v-164h-834z" />
+<glyph unicode="&#x3e;" horiz-adv-x="1072" d="M136 87v196l598 238l85 17v6l-85 20l-598 234v195l856 -378v-149z" />
+<glyph unicode="?" horiz-adv-x="974" d="M61 1122q-3 161 113.5 258t296.5 97q197 0 306 -100.5t109 -280.5q0 -129 -70.5 -236t-186.5 -219q-54 -54 -65.5 -97t-11.5 -134h-197q1 145 25 201t126 148q99 117 141 180t42 152q0 106 -56.5 163t-161.5 57q-91 0 -155 -49.5t-64 -145.5h-188zM353 0v208h206v-208 h-206z" />
+<glyph unicode="@" horiz-adv-x="1833" d="M114 478q19 423 249 688t602 265q379 0 581.5 -250t185.5 -679q-9 -214 -120 -368.5t-332 -154.5q-73 0 -126 41.5t-76 117.5q-50 -80 -122 -119.5t-168 -39.5q-125 0 -194 120.5t-51 316.5q23 259 137.5 415.5t279.5 156.5q105 0 169 -26t139 -80l-4 -4h6l-51 -585 q-9 -110 21.5 -151.5t81.5 -41.5q123 0 197 113.5t82 288.5q16 382 -144 595.5t-496 213.5q-308 0 -495.5 -231t-202.5 -602q-18 -376 150 -594.5t482 -218.5q88 0 178.5 21.5t152.5 56.5l38 -107q-67 -42 -170.5 -65.5t-202.5 -23.5q-380 0 -587.5 249.5t-189.5 681.5z M720 416q-11 -142 21.5 -216t106.5 -74q64 0 117 24.5t97 87.5q-1 12 -0.5 25.5t2.5 29.5l47 538q-26 12 -54.5 19t-59.5 7q-125 0 -191 -109.5t-86 -331.5z" />
+<glyph unicode="A" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6z" />
+<glyph unicode="B" horiz-adv-x="1309" d="M180 0v1456h475q228 0 357 -98.5t129 -295.5q0 -97 -62 -173.5t-163 -113.5q132 -28 207.5 -129t75.5 -235q0 -200 -129.5 -305.5t-351.5 -105.5h-538zM377 154h341q134 0 209 66.5t75 188.5q0 128 -62.5 201t-192.5 73h-370v-529zM377 837h319q110 0 179 60.5t69 168.5 q0 118 -74.5 176.5t-214.5 58.5h-278v-464z" />
+<glyph unicode="C" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5q247 1 393 -131q142 -128 142 -337v-12l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6v-11q0 -198 -144 -332q-148 -138 -391 -138 q-247 0 -402.5 175t-155.5 444z" />
+<glyph unicode="D" horiz-adv-x="1349" d="M180 0v1456h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447zM377 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-1147z" />
+<glyph unicode="E" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966z" />
+<glyph unicode="F" horiz-adv-x="1193" d="M180 0v1456h963v-155h-766v-502h664v-155h-664v-644h-197z" />
+<glyph unicode="G" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432z" />
+<glyph unicode="H" horiz-adv-x="1461" d="M180 0v1456h197v-658h707v658h197v-1456h-197v643h-707v-643h-197z" />
+<glyph unicode="I" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198z" />
+<glyph unicode="J" horiz-adv-x="1130" d="M66 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 107q-119 102 -119 293v16z" />
+<glyph unicode="K" horiz-adv-x="1317" d="M180 0v1456h197v-644h152l521 644h218l3 -5l-565 -699l606 -747l-3 -5h-235l-527 657h-170v-657h-197z" />
+<glyph unicode="L" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886z" />
+<glyph unicode="M" horiz-adv-x="1799" d="M180 0v1456h252l464 -1183h6l464 1183h252v-1456h-197v576l20 592l-5 1l-472 -1169h-131l-470 1166l-5 -1l19 -589v-576h-197z" />
+<glyph unicode="N" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197z" />
+<glyph unicode="O" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261z" />
+<glyph unicode="P" horiz-adv-x="1312" d="M180 0v1456h557q233 0 362 -120t129 -316q0 -199 -129 -317.5t-362 -118.5h-360v-584h-197zM377 738h360q148 0 221 79.5t73 200.5t-73.5 202t-220.5 81h-360v-563z" />
+<glyph unicode="Q" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -142 -50 -263t-140 -205l247 -233l-135 -129l-276 257q-56 -23 -116.5 -34.5t-124.5 -11.5q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5 t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128t-102.5 -328v-261z" />
+<glyph unicode="R" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515z" />
+<glyph unicode="S" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 381 -131q137 -127 136 -292v-12l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -386 118q-163 115 -162 305v11z" />
+<glyph unicode="T" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467z" />
+<glyph unicode="U" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5z" />
+<glyph unicode="V" horiz-adv-x="1295" d="M22 1456h214l376 -1094l33 -115h6l33 115l376 1094h213l-541 -1456h-169z" />
+<glyph unicode="W" horiz-adv-x="1809" d="M54 1456h196l222 -952l27 -182l6 -1l39 183l267 952h174l269 -952l40 -187h6l29 187l217 952h197l-351 -1456h-176l-287 1010l-26 131h-6l-25 -131l-292 -1010h-176z" />
+<glyph unicode="X" horiz-adv-x="1295" d="M66 0l472 734l-462 722h236l338 -568l340 568h238l-462 -722l472 -734h-235l-349 578l-350 -578h-238z" />
+<glyph unicode="Y" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525z" />
+<glyph unicode="Z" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036z" />
+<glyph unicode="[" horiz-adv-x="552" d="M143 -312v1976h385v-155h-188v-1666h188v-155h-385z" />
+<glyph unicode="\" horiz-adv-x="846" d="M39 1456h186l608 -1581h-186z" />
+<glyph unicode="]" horiz-adv-x="552" d="M11 -157h189v1666h-189v155h386v-1976h-386v155z" />
+<glyph unicode="^" horiz-adv-x="856" d="M61 729l299 727h134l298 -727h-181l-166 419l-16 70h-6l-16 -70l-163 -419h-183z" />
+<glyph unicode="_" horiz-adv-x="931" d="M4 0h923v-154h-923v154z" />
+<glyph unicode="`" horiz-adv-x="641" d="M82 1471l3 6h230l175 -266h-158z" />
+<glyph unicode="a" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6v11q0 111 112 205q118 98 303 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="b" d="M143 0v1560h197v-606q51 72 126.5 110t176.5 38q200 0 312 -160t112 -421v-21q0 -234 -112.5 -377.5t-309.5 -143.5q-107 0 -186 41.5t-131 122.5l-24 -143h-161zM340 309q38 -80 99.5 -125t155.5 -45q139 0 207 99t68 262v21q0 186 -68.5 303.5t-208.5 117.5 q-91 0 -153.5 -44.5t-99.5 -119.5v-469z" />
+<glyph unicode="c" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q191 0 311 -112q117 -108 116 -265v-10l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6v-10q-1 -134 -125 -238 q-130 -108 -301 -109q-236 0 -361 154t-125 387z" />
+<glyph unicode="d" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v595h197v-1560h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505q-38 67 -98.5 106.5t-145.5 39.5 q-142 0 -209.5 -117t-67.5 -304v-21z" />
+<glyph unicode="e" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="f" horiz-adv-x="707" d="M56 936v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-53.5 3q-86 0 -128 -51.5t-42 -149.5v-137h225v-146h-225v-936h-197v936h-169z" />
+<glyph unicode="g" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="h" d="M143 0v1560h197v-623q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197z" />
+<glyph unicode="i" horiz-adv-x="516" d="M159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197z" />
+<glyph unicode="j" horiz-adv-x="530" d="M-66 -419l14 155q14 -5 40 -8.5t43 -3.5q65 0 103.5 44t38.5 143v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM167 1363v197h197v-197h-197z" />
+<glyph unicode="k" horiz-adv-x="1050" d="M144 0v1560h197v-904h126l296 426h236l-370 -492l423 -590h-232l-351 499h-128v-499h-197z" />
+<glyph unicode="l" horiz-adv-x="516" d="M159 0v1560h197v-1560h-197z" />
+<glyph unicode="m" horiz-adv-x="1790" d="M143 0v1082h176l14 -142q53 77 134.5 119.5t189.5 42.5t185.5 -50t116.5 -150q51 92 135 146t196 54q165 0 261 -113.5t96 -341.5v-647h-197v649q0 160 -55 226.5t-164 66.5q-101 0 -163.5 -70t-73.5 -177v-8v-687h-198v649q0 152 -56.5 222.5t-162.5 70.5 q-90 0 -148 -37t-89 -104v-801h-197z" />
+<glyph unicode="n" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197z" />
+<glyph unicode="o" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="p" d="M143 -416v1498h151l31 -140q53 78 132 119t184 41q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM340 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="q" d="M98 500v21q0 261 111.5 421t312.5 160q99 0 174 -37.5t127 -109.5l29 127h150v-1498h-197v518q-52 -61 -123 -92t-162 -31q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67.5 -265.5t207.5 -101.5q81 0 138.5 36t96.5 101v546q-39 61 -96.5 96t-136.5 35 q-141 0 -209 -119.5t-68 -306.5v-21z" />
+<glyph unicode="r" horiz-adv-x="702" d="M143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="s" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 301 -97q107 -93 106 -224v-12l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105q-113 100 -113 232v13z" />
+<glyph unicode="t" horiz-adv-x="708" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172z" />
+<glyph unicode="u" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352z" />
+<glyph unicode="v" horiz-adv-x="1030" d="M46 1082h202l256 -763l17 -76h6l19 76l249 763h201l-398 -1082h-149z" />
+<glyph unicode="w" horiz-adv-x="1550" d="M45 1082h196l179 -688l23 -131h6l28 131l216 688h158l217 -688l31 -146h6l29 146l170 688h196l-314 -1082h-159l-209 659l-45 184l-6 -1l-43 -183l-206 -659h-159z" />
+<glyph unicode="x" horiz-adv-x="1030" d="M46 0l361 547l-351 535h227l227 -399l230 399h230l-351 -535l361 -547h-226l-240 409l-240 -409h-228z" />
+<glyph unicode="y" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113z" />
+<glyph unicode="z" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860z" />
+<glyph unicode="{" horiz-adv-x="696" d="M63 543v147q106 0 157.5 61.5t51.5 174.5v206q0 171 82 290.5t277 174.5l40 -117q-110 -35 -156 -125.5t-46 -222.5v-206q0 -105 -42.5 -185t-127.5 -125q85 -46 127.5 -126.5t42.5 -183.5v-205q0 -132 46 -221.5t156 -125.5l-40 -118q-195 55 -277 175t-82 290v205 q0 112 -51.5 174.5t-157.5 62.5z" />
+<glyph unicode="|" horiz-adv-x="507" d="M175 -270v1726h158v-1726h-158z" />
+<glyph unicode="}" horiz-adv-x="696" d="M21 -246q109 36 156 125.5t47 221.5v205q0 107 45 187t139 123q-94 41 -139 121t-45 189v206q0 132 -47 222.5t-156 125.5l41 117q194 -55 276.5 -174.5t82.5 -290.5v-206q0 -113 50.5 -174.5t158.5 -61.5v-147q-108 0 -158.5 -62.5t-50.5 -174.5v-205q0 -170 -82.5 -290 t-276.5 -175z" />
+<glyph unicode="~" horiz-adv-x="1391" d="M128 474q0 136 85.5 232.5t217.5 96.5q88 0 163 -34.5t160 -104.5q58 -51 106 -74t100 -23q66 0 114.5 57t48.5 134l141 -18q0 -137 -87 -238t-217 -101q-90 0 -163.5 33t-158.5 107q-59 48 -108 72t-99 24q-67 0 -114.5 -53t-47.5 -128z" />
+<glyph unicode="&#xa1;" horiz-adv-x="507" d="M144 -374v978h197v-978h-197zM144 876v206h197v-206h-197z" />
+<glyph unicode="&#xa2;" horiz-adv-x="1122" d="M107 520v42q0 199 95 344.5t276 183.5v228h198v-223q157 -24 252.5 -130.5t92.5 -250.5l-2 -5h-179q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h178l3 -6q3 -122 -98 -223t-247 -126v-232 h-198v236q-182 36 -276.5 182t-94.5 347z" />
+<glyph unicode="&#xa3;" horiz-adv-x="1194" d="M70 615v155h158l-10 270q0 204 112 320.5t300 116.5q200 0 310 -104.5t106 -276.5l-2 -6h-190q0 118 -63 175t-161 57q-99 0 -157 -74.5t-58 -207.5l10 -270h418v-155h-413l6 -149q0 -90 -15.5 -171.5t-44.5 -140.5h735l-1 -154h-976v154h10q48 13 72 111t24 201l-6 149 h-164z" />
+<glyph unicode="&#xa4;" horiz-adv-x="1456" d="M104 112l138 140q-50 76 -76.5 166.5t-26.5 189.5q0 102 28.5 196t82.5 172l-146 149l139 139l143 -146q74 55 163 85.5t185 30.5q97 0 186 -31t164 -87l146 149l140 -140l-150 -153q52 -78 80.5 -170.5t28.5 -193.5q0 -98 -26.5 -187.5t-74.5 -165.5l142 -143l-140 -139 l-133 135q-77 -62 -169.5 -95t-193.5 -33t-193.5 32.5t-167.5 93.5l-130 -132zM321 608q0 -188 120.5 -320.5t292.5 -132.5q170 0 290.5 132.5t120.5 320.5q0 186 -120.5 318t-290.5 132q-172 0 -292.5 -132t-120.5 -318z" />
+<glyph unicode="&#xa5;" horiz-adv-x="1243" d="M30 1456h226l359 -663l360 663h224l-418 -718h312v-155h-383v-135h383v-155h-383v-293h-197v293h-375v155h375v135h-375v155h311z" />
+<glyph unicode="&#xa6;" horiz-adv-x="499" d="M145 -270v792h197v-792h-197zM145 698v758h197v-758h-197z" />
+<glyph unicode="&#xa7;" horiz-adv-x="1259" d="M94 551q0 91 47 161.5t134 111.5q-68 50 -102 119.5t-34 166.5q0 166 134 266.5t358 100.5q233 0 363 -111.5t126 -313.5l-3 -6h-188q0 118 -79 197t-219 79q-145 0 -220 -59.5t-75 -150.5q0 -99 67 -148.5t278 -107.5q244 -69 355.5 -159.5t111.5 -265.5q0 -94 -48 -164 t-135 -110q69 -51 104 -119t35 -166q0 -172 -133 -269.5t-358 -97.5q-221 0 -372 102.5t-146 322.5l2 6l188 2q0 -143 96.5 -210.5t231.5 -67.5q137 0 215.5 59.5t78.5 150.5t-72 141.5t-276 113.5q-239 63 -352 156t-113 270zM291 553q0 -100 68 -151.5t278 -110.5 q56 -17 93 -28t70 -23q72 20 112 69.5t40 118.5q0 91 -73.5 144.5t-275.5 116.5q-47 12 -88.5 24.5t-77.5 27.5q-73 -19 -109.5 -69t-36.5 -119z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1021" d="M170 1256v200h219v-200h-219zM640 1256v200h219v-200h-219z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -265 171.5 -447t417.5 -182q245 0 417 182t172 447q0 263 -172 444t-417 181q-246 0 -417.5 -181t-171.5 -444zM436 669v119q0 173 94 280 t254 107q157 0 245.5 -79t84.5 -228l-2 -6h-146q0 95 -45.5 138.5t-136.5 43.5q-94 0 -145 -70.5t-51 -184.5v-120q0 -117 51 -187t145 -70q91 0 136 43t45 141h146l2 -6q4 -151 -84 -229.5t-245 -78.5q-160 0 -254 106.5t-94 280.5z" />
+<glyph unicode="&#xaa;" horiz-adv-x="917" d="M120 920q0 110 84.5 170t245.5 60h139v52q0 63 -30 97t-88 34q-67 0 -103.5 -27t-36.5 -76l-162 13l-1 6q-6 98 78.5 163t224.5 65q134 0 212 -71t78 -205v-314q0 -50 6 -94t20 -87h-174q-8 21 -13 45t-8 50q-33 -47 -89.5 -78t-133.5 -31q-119 0 -184 61t-65 167z M293 924q0 -45 29 -69t89 -24q51 0 105.5 30t72.5 65v110h-138q-75 0 -116.5 -33t-41.5 -79z" />
+<glyph unicode="&#xab;" horiz-adv-x="966" d="M98 507v19l295 389h148l-255 -399l255 -398h-148zM432 507v19l295 389h148l-255 -399l255 -398h-148z" />
+<glyph unicode="&#xac;" horiz-adv-x="1137" d="M127 637v165h835v-427h-198v262h-637z" />
+<glyph unicode="&#xad;" horiz-adv-x="561" d="M35 538v154h490v-154h-490z" />
+<glyph unicode="&#xae;" horiz-adv-x="1604" d="M88 729q0 315 207 531t503 216q295 0 502 -216t207 -531q0 -316 -207.5 -533t-501.5 -217q-296 0 -503 217t-207 533zM209 729q0 -266 171.5 -447.5t417.5 -181.5q244 0 416 182t172 447q0 264 -171.5 444.5t-416.5 180.5q-246 0 -417.5 -180.5t-171.5 -444.5zM504 316 v850h280q152 0 238.5 -65.5t86.5 -191.5q0 -62 -33 -109t-96 -78q66 -26 95.5 -79t29.5 -128v-56q0 -41 3.5 -73.5t13.5 -53.5v-16h-153q-9 21 -11 61.5t-2 82.5v54q0 72 -33.5 106t-110.5 34h-159v-338h-149zM653 784h152q65 1 110.5 32.5t45.5 87.5q0 73 -39.5 102.5 t-137.5 29.5h-131v-252z" />
+<glyph unicode="&#xaf;" horiz-adv-x="950" d="M123 1310v146h721v-146h-721z" />
+<glyph unicode="&#xb0;" horiz-adv-x="763" d="M128 1216q0 106 76 183.5t181 77.5q103 0 177.5 -77.5t74.5 -183.5q0 -108 -74 -182.5t-178 -74.5q-106 0 -181.5 74.5t-75.5 182.5zM259 1216q0 -55 36.5 -91t89.5 -36q52 0 87.5 36t35.5 91t-36 92.5t-87 37.5q-53 0 -89.5 -37.5t-36.5 -92.5z" />
+<glyph unicode="&#xb1;" horiz-adv-x="1097" d="M99 702v154h381v411h177v-411h358v-154h-358v-413h-177v413h-381zM136 4v155h835v-155h-835z" />
+<glyph unicode="&#xb2;" horiz-adv-x="868" d="M119 1240q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="&#xb3;" horiz-adv-x="876" d="M112 882l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169z" />
+<glyph unicode="&#xb4;" horiz-adv-x="654" d="M131 1211l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xb5;" d="M153 -416v1498h196v-642q2 -178 57.5 -242.5t155.5 -64.5q98 0 158.5 36t92.5 106v807h197v-1082h-177l-9 108q-44 -63 -107.5 -96t-146.5 -33q-72 0 -126.5 16.5t-94.5 51.5v-463h-196z" />
+<glyph unicode="&#xb6;" horiz-adv-x="1006" d="M63 988q0 207 129.5 337.5t362.5 130.5h281v-1456h-197v520h-84q-233 0 -362.5 129.5t-129.5 338.5z" />
+<glyph unicode="&#xb7;" horiz-adv-x="540" d="M161 624v212h198v-212h-198z" />
+<glyph unicode="&#xb8;" horiz-adv-x="509" d="M119 -326q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xb9;" horiz-adv-x="557" d="M95 1320v134l301 23v-812h-174v655h-127z" />
+<glyph unicode="&#xba;" horiz-adv-x="933" d="M120 1025v117q0 148 94 241.5t251 93.5q158 0 252 -93.5t94 -241.5v-117q0 -149 -93.5 -241.5t-250.5 -92.5q-158 0 -252.5 92.5t-94.5 241.5zM293 1025q0 -88 44 -140.5t130 -52.5q83 0 127.5 53t44.5 140v117q0 84 -45 137.5t-129 53.5t-128 -53.5t-44 -137.5v-117z " />
+<glyph unicode="&#xbb;" horiz-adv-x="966" d="M110 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148zM456 152l255 398l-255 399h148l295 -389v-19l-295 -389h-148z" />
+<glyph unicode="&#xbc;" horiz-adv-x="1595" d="M184 1319v134l301 23v-812h-174v655h-127zM339 185l711 1138l109 -67l-711 -1138zM785 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM967 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="&#xbd;" horiz-adv-x="1708" d="M184 1319v134l301 23v-812h-174v655h-127zM352 185l711 1138l109 -67l-711 -1138zM930 573q-6 99 78 169t225 70q135 0 211 -64t76 -180q0 -80 -44.5 -136t-160.5 -161l-153 -135l2 -6h361v-130h-592v130l302 262q69 60 91 97.5t22 79.5q0 50 -28.5 81t-86.5 31 q-67 0 -103.5 -32t-36.5 -82h-161z" />
+<glyph unicode="&#xbe;" horiz-adv-x="1781" d="M128 883l1 6h163q0 -46 37.5 -74.5t100.5 -28.5q72 0 114 29.5t42 77.5q0 62 -36.5 90.5t-109.5 28.5h-132v126h132q67 0 99.5 28.5t32.5 80.5q0 43 -36.5 72t-105.5 29q-56 0 -90.5 -24t-34.5 -64h-162l-2 6q-6 94 78.5 153.5t210.5 59.5q145 0 229 -59.5t84 -169.5 q0 -55 -35.5 -100.5t-97.5 -71.5q70 -23 108 -71t38 -116q0 -111 -90 -173t-236 -62q-127 0 -217.5 58t-84.5 169zM522 185l711 1138l109 -67l-711 -1138zM974 254l422 547h173v-519h126v-130h-126v-152h-170v152h-417zM1156 282h243v310l-6 1l-13 -22z" />
+<glyph unicode="&#xbf;" horiz-adv-x="1013" d="M114 -13q0 127 70 233.5t187 220.5q53 53 65 96t12 135h197q-2 -146 -26 -202t-125 -147q-100 -118 -141.5 -181t-41.5 -150q0 -106 56 -163t162 -57q90 0 154.5 49.5t64.5 145.5h188l3 -6q2 -161 -114.5 -258t-295.5 -97q-198 0 -306.5 100.5t-108.5 280.5zM441 874v209 h206v-209h-206z" />
+<glyph unicode="&#xc0;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM378 1820l3 6h230l175 -266h-158zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#xc1;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM613 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xc2;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM356 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#xc3;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM316 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM420 540h490l-240 663h-6z " />
+<glyph unicode="&#xc4;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM319 1605v200h219v-200h-219zM420 540h490l-240 663h-6zM789 1605v200h219v-200h-219z" />
+<glyph unicode="&#xc5;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM457 1734q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140zM560 1734q0 -43 31 -73.5t74 -30.5q42 0 72 29.5 t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1922" d="M-20 0l880 1456h967v-155h-691l20 -466h590v-155h-584l22 -526h705v-154h-895l-15 350h-557l-202 -350h-240zM525 529h447l-31 710l-5 2z" />
+<glyph unicode="&#xc7;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM581 -334 q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xc8;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM303 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xc9;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM538 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xca;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM322 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xcb;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM284 1605v200h219v-200h-219zM754 1605v200h219v-200h-219z" />
+<glyph unicode="&#xcc;" horiz-adv-x="579" d="M-34 1820l3 6h230l175 -266h-158zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#xcd;" horiz-adv-x="579" d="M190 0v1456h198v-1456h-198zM199 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xce;" horiz-adv-x="579" d="M-15 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#xcf;" horiz-adv-x="579" d="M-53 1605v200h219v-200h-219zM190 0v1456h198v-1456h-198zM417 1605v200h219v-200h-219z" />
+<glyph unicode="&#xd0;" horiz-adv-x="1379" d="M42 663v155h168v638h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447v663h-168zM407 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-483h276v-155h-276v-509z" />
+<glyph unicode="&#xd1;" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM381 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xd2;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM373 1841l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xd3;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM608 1577l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xd4;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM392 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xd5;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM351 1649q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xd6;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM354 1626v200h219v-200h-219zM824 1626v200h219v-200h-219z" />
+<glyph unicode="&#xd7;" horiz-adv-x="1096" d="M88 351l327 334l-327 334l126 126l326 -333l327 333l126 -126l-328 -334l328 -334l-126 -126l-327 332l-326 -332z" />
+<glyph unicode="&#xd8;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q94 0 178.5 -25.5t156.5 -71.5l81 137h149l-132 -221q77 -84 119.5 -197t42.5 -242v-259q0 -267 -165.5 -443t-429.5 -176q-85 0 -160.5 20.5t-139.5 60.5l-91 -154h-149l139 234q-84 84 -128.5 202t-44.5 256zM310 598 q0 -85 19 -158t54 -125l6 -1l544 916q-50 41 -112 63t-134 22q-172 0 -274.5 -128t-102.5 -328v-261zM475 208q44 -34 97 -51t115 -17q183 0 290.5 127.5t107.5 330.5v261q0 75 -16.5 142t-46.5 117l-6 1z" />
+<glyph unicode="&#xd9;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM372 1820l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xda;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM607 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xdb;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM391 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xdc;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM353 1605v200h219v-200h-219zM823 1605v200h219v-200h-219z" />
+<glyph unicode="&#xdd;" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM535 1555l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xde;" horiz-adv-x="1209" d="M163 0v1456h197v-293h269q232 0 362 -118t130 -307q0 -190 -130 -307.5t-362 -117.5h-269v-313h-197zM360 467h269q147 0 220.5 78t73.5 191q0 114 -73.5 193.5t-220.5 79.5h-269v-542z" />
+<glyph unicode="&#xdf;" horiz-adv-x="1221" d="M137 0v1082q0 223 117.5 348t300.5 125q161 0 262 -86t101 -253q0 -118 -64.5 -228t-64.5 -167q0 -82 173.5 -224t173.5 -281q0 -167 -104.5 -252t-282.5 -85q-84 0 -172.5 20.5t-125.5 50.5l44 159q43 -28 108 -52t126 -24q108 0 159 47.5t51 125.5q0 84 -173.5 227.5 t-173.5 289.5q0 80 70.5 190.5t70.5 186.5q0 93 -51 147t-117 54q-104 0 -168 -83.5t-64 -235.5v-1082h-196z" />
+<glyph unicode="&#xe0;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM230 1498l3 6h230l175 -266h-158zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe1;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM465 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xe2;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM249 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe3;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM208 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55 t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#xe4;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM211 1283v200h219v-200h-219zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM681 1283v200h219v-200h-219z" />
+<glyph unicode="&#xe5;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM346 1412q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54q-87 0 -147.5 54t-60.5 140z M449 1412q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#xe6;" horiz-adv-x="1729" d="M58 304q0 158 115 244.5t335 86.5h229v85q0 106 -51.5 166.5t-149.5 60.5q-103 0 -164 -55t-61 -133l-188 18l-2 6q-5 138 109.5 228.5t305.5 90.5q114 0 201.5 -40.5t137.5 -117.5q64 75 151.5 116.5t188.5 41.5q214 0 329.5 -130t115.5 -358v-119h-709l-2 -5 q1 -159 79.5 -258t233.5 -99q103 0 169.5 27.5t144.5 78.5l67 -138q-53 -44 -147 -83t-234 -39q-136 0 -240 48.5t-170 138.5q-56 -79 -167.5 -133t-271.5 -54q-170 0 -262.5 87t-92.5 238zM255 300q0 -74 50 -120.5t147 -46.5q76 0 159 43.5t126 100.5v216h-227 q-120 0 -187.5 -56t-67.5 -137zM953 645l2 -5h508v31q0 122 -60 199t-188 77q-113 0 -182 -84.5t-80 -217.5z" />
+<glyph unicode="&#xe7;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM440 -334q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#xe8;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM233 1499l3 6h230l175 -266h-158zM307 654l2 -5 h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#xe9;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM468 1235l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xea;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM252 1280v26l246 237h120l248 -238v-25h-161 l-147 148l-146 -148h-160zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#xeb;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM214 1284v200h219v-200h-219zM307 654l2 -5h499 v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5zM684 1284v200h219v-200h-219z" />
+<glyph unicode="&#xec;" horiz-adv-x="515" d="M-71 1477l3 6h230l175 -266h-158zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#xed;" horiz-adv-x="515" d="M153 0v1082h197v-1082h-197zM162 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xee;" horiz-adv-x="515" d="M-52 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#xef;" horiz-adv-x="515" d="M-90 1262v200h219v-200h-219zM153 0v1082h197v-1082h-197zM380 1262v200h219v-200h-219z" />
+<glyph unicode="&#xf0;" horiz-adv-x="1202" d="M72 466q0 228 138 370t351 142q90 0 169.5 -37t131.5 -97l4 5q-9 109 -51.5 197t-110.5 154l-290 -165l-77 102l256 146q-39 22 -80.5 39t-85.5 31l60 164q79 -19 151 -52t135 -79l218 125l77 -102l-195 -112q95 -104 147 -241.5t52 -300.5v-220q0 -245 -144 -400.5 t-359 -155.5q-218 0 -357.5 140t-139.5 347zM269 466q0 -132 82 -232.5t222 -100.5q133 0 217.5 114t84.5 288v148q-35 59 -115.5 99.5t-198.5 40.5q-131 0 -211.5 -104t-80.5 -253z" />
+<glyph unicode="&#xf1;" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM231 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32 q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#xf2;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM257 1498l3 6h230l175 -266h-158zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf3;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z M492 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xf4;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM276 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22 q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf5;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM235 1306q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5 t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#xf6;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM238 1283v200h219v-200h-219zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22zM708 1283v200h219v-200h-219z" />
+<glyph unicode="&#xf7;" horiz-adv-x="1170" d="M71 597v188h998v-188h-998zM472 180v203h198v-203h-198zM472 999v203h198v-203h-198z" />
+<glyph unicode="&#xf8;" d="M97 529v22q0 240 130 395.5t353 155.5q56 0 107.5 -11t97.5 -31l74 149h129l-104 -211q88 -74 135 -190t47 -257v-22q0 -242 -130 -396t-354 -154q-51 0 -97 8.5t-88 24.5l-72 -147h-129l100 204q-96 71 -147.5 191t-51.5 269zM294 529q0 -91 20 -166.5t61 -123.5h6 l332 674q-29 16 -62.5 25t-70.5 9q-141 0 -213.5 -113t-72.5 -283v-22zM469 156q24 -12 52 -17.5t61 -5.5q141 0 214 112t73 284v22q0 80 -17.5 150.5t-49.5 117.5h-6z" />
+<glyph unicode="&#xf9;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM255 1477l3 6h230l175 -266h-158z" />
+<glyph unicode="&#xfa;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM490 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xfb;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM274 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#xfc;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM236 1262v200h219v-200h-219zM706 1262v200h219v-200h-219z" />
+<glyph unicode="&#xfd;" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM424 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#xfe;" horiz-adv-x="1186" d="M153 -416v1976h197v-598q53 68 128 104t173 36q201 0 312.5 -159.5t111.5 -421.5v-21q0 -234 -112 -377.5t-309 -143.5q-100 0 -175.5 33.5t-128.5 100.5v-529h-197zM350 275q37 -67 97 -104.5t147 -37.5q140 0 212 102.5t72 264.5v21q0 184 -72.5 302.5t-213.5 118.5 q-85 0 -145 -38.5t-97 -105.5v-523z" />
+<glyph unicode="&#xff;" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM170 1262v200h219v-200h-219zM640 1262v200h219v-200h-219z" />
+<glyph unicode="&#x100;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM303 1640v146h721v-146h-721zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#x101;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM200 1318v146h721v-146h-721zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141z" />
+<glyph unicode="&#x102;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM369 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM420 540h490l-240 663h-6z" />
+<glyph unicode="&#x103;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM261 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141 z" />
+<glyph unicode="&#x104;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM962 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5 q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="&#x105;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM667 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5 l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="&#x106;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM588 1577 l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x107;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM447 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x108;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM372 1622 v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x109;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM231 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x10a;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM569 1625 v201h218v-201h-218z" />
+<glyph unicode="&#x10b;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM428 1282v201h218v-201h-218z" />
+<glyph unicode="&#x10c;" horiz-adv-x="1297" d="M118 598v259q0 269 155.5 444.5t402.5 175.5t393 -131.5t142 -348.5l-2 -6h-189q0 153 -90 242t-254 89q-165 0 -263 -133t-98 -330v-261q0 -199 98 -332t263 -133q164 0 254 88.5t90 244.5h189l2 -6q4 -205 -144 -343t-391 -138q-247 0 -402.5 175t-155.5 444zM364 1866 v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x10d;" horiz-adv-x="1087" d="M97 520v42q0 231 125.5 385.5t360.5 154.5q190 0 310.5 -112t116.5 -275l-2 -6h-178q0 99 -70 168.5t-177 69.5q-155 0 -221.5 -111.5t-66.5 -273.5v-42q0 -166 66 -276.5t222 -110.5q98 0 172.5 60.5t74.5 148.5h177l2 -6q5 -140 -124.5 -248.5t-301.5 -108.5 q-236 0 -361 154t-125 387zM223 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x10e;" horiz-adv-x="1349" d="M180 0v1456h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447zM306 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119zM377 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-1147z" />
+<glyph unicode="&#x10f;" horiz-adv-x="1314" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v595h197v-1560h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505q-38 67 -98.5 106.5t-145.5 39.5 q-142 0 -209.5 -117t-67.5 -304v-21zM1090 1183l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x110;" horiz-adv-x="1379" d="M42 663v155h168v638h447q286 0 459 -175.5t173 -453.5v-199q0 -279 -173 -453.5t-459 -174.5h-447v663h-168zM407 154h250q202 0 318.5 133t116.5 341v201q0 206 -116.5 339t-318.5 133h-250v-483h276v-155h-276v-509z" />
+<glyph unicode="&#x111;" horiz-adv-x="1194" d="M98 500v21q0 261 111.5 421t312.5 160q95 0 168.5 -35t125.5 -102v266h-247v155h247v174h197v-174h197v-155h-197v-1231h-161l-23 133q-53 -76 -130 -115t-179 -39q-198 0 -310 143.5t-112 377.5zM295 500q0 -164 67 -262.5t208 -98.5q88 0 148 40t98 112v505 q-38 67 -98.5 106.5t-145.5 39.5q-142 0 -209.5 -117t-67.5 -304v-21z" />
+<glyph unicode="&#x112;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM273 1640v146h721v-146h-721z" />
+<glyph unicode="&#x113;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM203 1319v146h721v-146h-721zM307 654l2 -5h499 v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#x114;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM334 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="&#x115;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM264 1543l2 6h151q0 -66 34 -107t108 -41 q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#x116;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM519 1604v201h218v-201h-218z" />
+<glyph unicode="&#x117;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM449 1283v201h218v-201h-218z" />
+<glyph unicode="&#x118;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM399 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z " />
+<glyph unicode="&#x119;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM307 654l2 -5h499v26q0 116 -62 194t-184 78 q-99 0 -169 -83.5t-86 -209.5zM560 -161q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="&#x11a;" horiz-adv-x="1197" d="M180 0v1456h955v-155h-758v-471h667v-155h-667v-521h769v-154h-966zM314 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x11b;" horiz-adv-x="1083" d="M99 520v44q0 231 137.5 384.5t325.5 153.5q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-226 0 -359.5 150.5t-133.5 390.5zM244 1524v20h166l147 -148l147 148h170v-18 l-257 -245h-119zM307 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5t-86 -209.5z" />
+<glyph unicode="&#x11c;" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM362 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x11d;" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM258 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="&#x11e;" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM374 1885l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="&#x11f;" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM270 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21z" />
+<glyph unicode="&#x120;" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM559 1625v201h218v-201h-218z" />
+<glyph unicode="&#x121;" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21zM455 1282v201h218v-201h-218z" />
+<glyph unicode="&#x122;" horiz-adv-x="1396" d="M120 578v300q0 265 159 432t410 167q250 0 393 -123t146 -317l-2 -6h-188q-9 127 -96.5 209t-252.5 82q-167 0 -269 -125t-102 -317v-302q0 -194 114 -319.5t290 -125.5q124 0 203 33t113 75v331h-319v155h516v-534q-52 -80 -180.5 -147t-332.5 -67q-261 0 -431.5 167 t-170.5 432zM521 -494l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x123;" d="M100 500v21q0 261 114 421t315 160q103 0 181 -41.5t130 -119.5l24 141h157v-1088q0 -208 -121 -319.5t-349 -111.5q-78 0 -168.5 21.5t-159.5 58.5l50 153q53 -30 128 -48.5t148 -18.5q144 0 209.5 65.5t65.5 199.5v122q-53 -68 -127 -102.5t-170 -34.5q-199 0 -313 144 t-114 377zM297 500q0 -163 69 -262t210 -99q89 0 149 40.5t99 114.5v498q-38 69 -99 109.5t-147 40.5q-141 0 -211 -118t-70 -303v-21zM459 1253v148l121 247h97l-21 -257v-138h-197z" />
+<glyph unicode="&#x124;" horiz-adv-x="1461" d="M180 0v1456h197v-658h707v658h197v-1456h-197v643h-707v-643h-197zM415 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x125;" d="M143 0v1560h197v-623q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197zM203 1600v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x126;" horiz-adv-x="1439" d="M31 1024v145h147v287h197v-287h707v287h197v-287h144v-145h-144v-1024h-197v643h-707v-643h-197v1024h-147zM375 798h707v226h-707v-226z" />
+<glyph unicode="&#x127;" horiz-adv-x="1194" d="M1 1231v155h172v174h197v-174h272v-155h-272v-294q56 78 137.5 121.5t180.5 43.5q173 0 269.5 -104t96.5 -320v-678h-197v680q0 134 -57.5 198t-171.5 64q-82 0 -148.5 -38.5t-109.5 -104.5v-799h-197v1231h-172z" />
+<glyph unicode="&#x128;" horiz-adv-x="579" d="M-56 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#x129;" horiz-adv-x="515" d="M-93 1285q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#x12a;" horiz-adv-x="579" d="M-64 1640v146h721v-146h-721zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#x12b;" horiz-adv-x="515" d="M-101 1299v146h721v-146h-721zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#x12c;" horiz-adv-x="579" d="M-3 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#x12d;" horiz-adv-x="515" d="M-40 1521l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#x12e;" horiz-adv-x="579" d="M46 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#x12f;" horiz-adv-x="516" d="M14 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154zM159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197z" />
+<glyph unicode="&#x130;" horiz-adv-x="579" d="M180 1604v201h218v-201h-218zM190 0v1456h198v-1456h-198z" />
+<glyph unicode="&#x131;" horiz-adv-x="515" d="M153 0v1082h197v-1082h-197z" />
+<glyph unicode="&#x132;" horiz-adv-x="1709" d="M190 0v1456h198v-1456h-198zM645 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 106.5t-119 309.5z" />
+<glyph unicode="&#x133;" horiz-adv-x="1046" d="M159 0v1082h197v-1082h-197zM159 1359v201h197v-201h-197zM450 -419l14 155q14 -5 40 -8.5t43 -3.5q65 0 103.5 44t38.5 143v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM683 1363v197h197v-197h-197z" />
+<glyph unicode="&#x134;" horiz-adv-x="1130" d="M66 395l2 6h189q0 -135 68.5 -201.5t193.5 -66.5q109 0 178 73.5t69 196.5v1053h197v-1053q0 -195 -123.5 -309.5t-320.5 -114.5q-210 0 -334 106.5t-119 309.5zM550 1589v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x135;" horiz-adv-x="523" d="M-68 -419l14 150q14 -5 46.5 -9t50.5 -4q59 0 93.5 51.5t34.5 141.5v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM-34 1240v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x136;" horiz-adv-x="1317" d="M180 0v1456h197v-644h152l521 644h218l3 -5l-565 -699l606 -747l-3 -5h-235l-527 657h-170v-657h-197zM487 -477l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x137;" horiz-adv-x="1050" d="M144 0v1560h197v-904h126l296 426h236l-370 -492l423 -590h-232l-351 499h-128v-499h-197zM388 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x138;" horiz-adv-x="1144" d="M153 0v1082h197v-457h84l388 457h231l2 -5l-450 -514l483 -558l-2 -5h-241l-394 459h-101v-459h-197z" />
+<glyph unicode="&#x139;" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM186 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x13a;" horiz-adv-x="516" d="M159 0v1560h197v-1560h-197zM168 1594l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x13b;" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM480 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x13c;" horiz-adv-x="516" d="M110 -475l61 246v131h158v-140l-122 -237h-97zM159 0v1560h197v-1560h-197z" />
+<glyph unicode="&#x13d;" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM583 1080l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x13e;" horiz-adv-x="666" d="M159 0v1560h197v-1560h-197zM453 1183l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x13f;" horiz-adv-x="1106" d="M180 0v1456h197v-1302h689v-154h-886zM613 688v201h218v-201h-218z" />
+<glyph unicode="&#x140;" horiz-adv-x="736" d="M159 0v1560h197v-1560h-197zM485 671v201h218v-201h-218z" />
+<glyph unicode="&#x141;" horiz-adv-x="1077" d="M40 576v166l123 39v675h197v-613l269 86v-166l-269 -86v-523h689v-154h-886v615z" />
+<glyph unicode="&#x142;" horiz-adv-x="558" d="M37 578v165l142 54v763h197v-688l150 58v-165l-150 -58v-707h-197v632z" />
+<glyph unicode="&#x143;" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM638 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x144;" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM488 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x145;" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM580 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x146;" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM430 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x147;" horiz-adv-x="1461" d="M180 0v1456h197l701 -1124l6 2v1122h197v-1456h-197l-701 1126l-6 -2v-1124h-197zM414 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x148;" d="M143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197zM264 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x149;" d="M-32 1183l61 246v131h158v-140l-122 -237h-97zM143 0v1082h176l14 -161q54 86 135.5 133.5t185.5 47.5q175 0 271 -102.5t96 -316.5v-683h-197v679q0 143 -56.5 203t-172.5 60q-85 0 -150.5 -41t-104.5 -112v-789h-197z" />
+<glyph unicode="&#x14a;" horiz-adv-x="1416" d="M161 0v1456h197l701 -1112l6 2v1110h197v-1545q0 -167 -86 -257.5t-240 -90.5q-31 0 -57 4.5t-55 13.5l14 150q13 -5 47 -9t51 -4q60 0 94.5 51.5t34.5 141.5v89l-701 1112l-6 -2v-1110h-197z" />
+<glyph unicode="&#x14b;" d="M143 0v1082h176l13 -150q54 81 134 125.5t181 44.5q174 0 270 -102.5t96 -316.5v-772q0 -167 -86 -257.5t-240 -90.5q-31 0 -57.5 4.5t-54.5 13.5l14 160q13 -5 46.5 -8.5t51.5 -3.5q61 0 95 47t34 135v768q0 143 -57 203t-173 60q-85 0 -146.5 -33t-99.5 -92v-817h-197z " />
+<glyph unicode="&#x14c;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM343 1661v146h721v-146h-721z" />
+<glyph unicode="&#x14d;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM227 1318v146h721v-146h-721zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113 q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#x14e;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM404 1885l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189z" />
+<glyph unicode="&#x14f;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM288 1542l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73q-138 0 -219 73t-76 189zM294 529 q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#x150;" horiz-adv-x="1396" d="M113 598v259q0 266 159.5 443t414.5 177q264 0 429.5 -176.5t165.5 -443.5v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM310 598q0 -202 102.5 -330t274.5 -128q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128 t-102.5 -328v-261zM462 1622l184 266h211l2 -5l-240 -261h-157zM731 1627l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="&#x151;" d="M97 529v22q0 240 130 395.5t353 155.5q225 0 355.5 -155t130.5 -396v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z M346 1279l184 266h211l2 -5l-240 -261h-157zM615 1284l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="&#x152;" horiz-adv-x="1960" d="M104 576v304q0 265 154.5 431t403.5 166q69 0 140.5 -6t150.5 -15h907v-155h-758v-471h667v-155h-667v-521h769v-154h-918q-92 -10 -157 -15.5t-132 -5.5q-249 0 -404.5 166t-155.5 431zM301 576q0 -214 97 -328t266 -114q61 0 122 4.5t119 13.5v1151q-61 8 -122 13.5 t-121 5.5q-169 0 -265 -113.5t-96 -326.5v-306z" />
+<glyph unicode="&#x153;" horiz-adv-x="1854" d="M97 529v22q0 240 130 395.5t353 155.5q130 0 230 -54.5t164 -152.5q65 97 161.5 152t204.5 55q219 0 331 -132t112 -352v-123h-702l-3 -5q3 -156 79 -256.5t213 -100.5q100 0 175.5 28.5t130.5 78.5l77 -128q-58 -57 -153 -95t-230 -38q-131 0 -232.5 52.5t-166.5 148.5 q-64 -96 -163 -148.5t-226 -52.5q-224 0 -354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22zM1085 654l2 -5h499v26q0 116 -62 194t-184 78q-99 0 -169 -83.5 t-86 -209.5z" />
+<glyph unicode="&#x154;" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515zM530 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x155;" horiz-adv-x="702" d="M143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197zM323 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x156;" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM377 786h310q167 0 240.5 63.5t73.5 193.5 q0 123 -71.5 190.5t-222.5 67.5h-330v-515zM472 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x157;" horiz-adv-x="702" d="M107 -475l61 246v131h158v-140l-122 -237h-97zM143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="&#x158;" horiz-adv-x="1357" d="M180 0v1455h527q239 0 365 -106t126 -308q0 -112 -58.5 -195t-170.5 -132q120 -39 172.5 -126.5t52.5 -216.5v-137q0 -68 15 -122t52 -88v-24h-203q-39 34 -50 100t-11 136v133q0 118 -69 190t-185 72h-366v-631h-197zM306 1845v20h166l147 -148l147 148h170v-18 l-257 -245h-119zM377 786h310q167 0 240.5 63.5t73.5 193.5q0 123 -71.5 190.5t-222.5 67.5h-330v-515z" />
+<glyph unicode="&#x159;" horiz-adv-x="702" d="M101 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119zM143 0v1082h176l19 -158q46 84 113.5 131t155.5 47q22 0 42 -3.5t33 -7.5l-27 -183l-101 6q-78 0 -131.5 -37t-82.5 -104v-773h-197z" />
+<glyph unicode="&#x15a;" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM523 1577l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x15b;" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM445 1234l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x15c;" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM307 1622v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x15d;" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM229 1279v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x15e;" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM516 -334q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#x15f;" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM438 -333q72 0 116 24.5t44 73.5q0 48 -36 67t-123 26l32 135h140l-12 -52q65 -11 108 -52t43 -121q0 -96 -79 -153t-226 -57z" />
+<glyph unicode="&#x160;" horiz-adv-x="1277" d="M102 413l2 6h188q0 -140 103 -213t255 -73q149 0 236 63t87 171q0 100 -75 167.5t-266 113.5q-231 55 -360.5 162t-129.5 269q0 170 139.5 284t361.5 114q239 0 380.5 -131t136.5 -304l-2 -6h-188q0 128 -84.5 207t-242.5 79q-147 0 -225.5 -66.5t-78.5 -173.5 q0 -95 85 -158.5t276 -111.5q230 -57 350 -168t120 -275q0 -176 -144 -283t-376 -107q-218 0 -385.5 118t-162.5 316zM299 1866v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x161;" horiz-adv-x="1071" d="M109 329l2 6h188q5 -105 78 -153.5t171 -48.5q105 0 164.5 42.5t59.5 111.5q0 65 -49.5 107t-187.5 73q-197 43 -296.5 116.5t-99.5 200.5q0 132 112 225t292 93q189 0 300.5 -97t106.5 -236l-2 -6h-188q0 71 -59.5 127.5t-157.5 56.5q-105 0 -156 -46t-51 -111 q0 -64 45 -101t183 -66q205 -44 305 -119.5t100 -202.5q0 -144 -116.5 -233t-304.5 -89q-207 0 -326 105t-113 245zM221 1523v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x162;" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467zM455 -475l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x163;" horiz-adv-x="708" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172zM308 -485l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x164;" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-1301h-197v1301h-467zM289 1844v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x165;" horiz-adv-x="748" d="M34 936v146h172v261h197v-261h205v-146h-205v-657q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v657h-172zM545 1210l61 246v131h158v-140l-122 -237h-97z" />
+<glyph unicode="&#x166;" horiz-adv-x="1200" d="M34 1301v155h1132v-155h-468v-326h220v-155h-220v-820h-197v820h-224v155h224v326h-467z" />
+<glyph unicode="&#x167;" horiz-adv-x="708" d="M-8 600v155h214v181h-172v146h172v261h197v-261h205v-146h-205v-181h230v-155h-230v-321q0 -76 31.5 -107t83.5 -31q17 0 37.5 4t36.5 10l26 -135q-22 -18 -64.5 -29.5t-85.5 -11.5q-120 0 -191 72.5t-71 227.5v321h-214z" />
+<glyph unicode="&#x168;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM350 1628q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32 q0 -94 -59.5 -159t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#x169;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM233 1285q0 93 59 161.5t150 68.5q56 0 140 -47t136 -47q41 0 71 32.5t30 79.5l108 -32q0 -94 -59.5 -159 t-149.5 -65q-71 0 -148 46.5t-128 46.5q-43 0 -72 -32.5t-29 -78.5z" />
+<glyph unicode="&#x16a;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM342 1640v146h721v-146h-721z" />
+<glyph unicode="&#x16b;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM225 1299v146h721v-146h-721z" />
+<glyph unicode="&#x16c;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM403 1864l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73 q-138 0 -219 73t-76 189z" />
+<glyph unicode="&#x16d;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM286 1521l2 6h151q0 -66 34 -107t108 -41q72 0 107 41.5t35 106.5h151l2 -6q4 -116 -77 -189t-218 -73 q-138 0 -219 73t-76 189z" />
+<glyph unicode="&#x16e;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM488 1734q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54 q-87 0 -147.5 54t-60.5 140zM591 1734q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#x16f;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM371 1391q0 84 60.5 141t147.5 57q85 0 145 -56.5t60 -141.5q0 -86 -59.5 -140t-145.5 -54 q-87 0 -147.5 54t-60.5 140zM474 1391q0 -43 31 -73.5t74 -30.5q42 0 72 29.5t30 74.5t-30 76t-72 31q-43 0 -74 -31t-31 -76z" />
+<glyph unicode="&#x170;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM461 1601l184 266h211l2 -5l-240 -261h-157zM730 1606l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="&#x171;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM344 1258l184 266h211l2 -5l-240 -261h-157zM613 1263l241 261h229l3 -6l-300 -260h-171z" />
+<glyph unicode="&#x172;" horiz-adv-x="1386" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-987q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5zM493 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66 t73.5 -24q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="&#x173;" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-1082h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352zM675 -223q0 80 60.5 152t187.5 128l72 -57q-70 -52 -109.5 -99.5t-39.5 -101.5q0 -42 22.5 -66t73.5 -24 q27 0 50 7.5t49 18.5l33 -123q-36 -19 -79.5 -31.5t-103.5 -12.5q-95 0 -155.5 55t-60.5 154z" />
+<glyph unicode="&#x174;" horiz-adv-x="1809" d="M54 1456h196l222 -952l27 -182l6 -1l39 183l267 952h174l269 -952l40 -187h6l29 187l217 952h197l-351 -1456h-176l-287 1010l-26 131h-6l-25 -131l-292 -1010h-176zM592 1601v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x175;" horiz-adv-x="1550" d="M45 1082h196l179 -688l23 -131h6l28 131l216 688h158l217 -688l31 -146h6l29 146l170 688h196l-314 -1082h-159l-209 659l-45 184l-6 -1l-43 -183l-206 -659h-159zM467 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x176;" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM319 1600v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x177;" horiz-adv-x="1030" d="M26 1082h220l228 -681l35 -136h6l266 817h219l-455 -1248q-41 -109 -117.5 -190t-206.5 -81q-24 0 -61 5.5t-57 10.5l20 155q-6 1 35.5 -2t52.5 -3q63 0 103 56t67 124l47 113zM208 1258v26l246 237h120l248 -238v-25h-161l-147 148l-146 -148h-160z" />
+<glyph unicode="&#x178;" horiz-adv-x="1250" d="M20 1456h225l380 -740l380 740h225l-511 -944v-512h-196v525zM281 1604v200h219v-200h-219zM751 1604v200h219v-200h-219z" />
+<glyph unicode="&#x179;" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM519 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x17a;" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM434 1213l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x17b;" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM500 1604v201h218v-201h-218z" />
+<glyph unicode="&#x17c;" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM415 1261v201h218v-201h-218z" />
+<glyph unicode="&#x17d;" horiz-adv-x="1225" d="M97 0v146l778 1155h-767v155h992v-141l-781 -1161h814v-154h-1036zM295 1845v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x17e;" horiz-adv-x="1030" d="M94 0v138l585 788h-578v156h819v-134l-591 -794h625v-154h-860zM210 1502v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x17f;" horiz-adv-x="516" d="M159 0v1219q0 173 91 267.5t253 94.5q33 0 67.5 -5.5t76.5 -15.5l-24 -145q-20 5 -42 8t-47 3q-87 0 -132.5 -54.5t-45.5 -152.5v-1219h-197z" />
+<glyph unicode="&#x192;" horiz-adv-x="702" d="M-23 -419l14 150q12 -5 45.5 -9t51.5 -4q60 0 94 51.5t34 141.5v1025h-169v146h169v137q0 173 90.5 267.5t252.5 94.5q34 0 68.5 -5.5t76.5 -15.5l-24 -150q-18 4 -43.5 7t-52.5 3q-87 0 -129 -51.5t-42 -149.5v-137h196v-146h-196v-1025q0 -167 -85.5 -257.5 t-239.5 -90.5q-32 0 -58 4.5t-53 13.5z" />
+<glyph unicode="&#x1a0;" horiz-adv-x="1403" d="M108 598v259q0 266 159.5 443t414.5 177q120 0 223 -40t182 -113q123 11 187 96.5t64 232.5h197q0 -192 -88 -313.5t-250 -157.5q38 -71 59 -154t21 -171v-259q0 -267 -165.5 -443t-429.5 -176q-255 0 -414.5 176t-159.5 443zM305 598q0 -202 102.5 -330t274.5 -128 q183 0 290.5 127.5t107.5 330.5v261q0 200 -108 328t-290 128q-172 0 -274.5 -128t-102.5 -328v-261z" />
+<glyph unicode="&#x1a1;" horiz-adv-x="1175" d="M97 529v22q0 240 130 395.5t353 155.5q102 0 187 -35t149 -98q82 18 122 84t40 170h178q0 -143 -66.5 -237t-195.5 -126q35 -66 53.5 -144.5t18.5 -164.5v-22q0 -242 -130 -396t-354 -154t-354.5 154.5t-130.5 395.5zM294 529q0 -172 72.5 -284t215.5 -112q141 0 214 112 t73 284v22q0 170 -73.5 283t-215.5 113q-141 0 -213.5 -113t-72.5 -283v-22z" />
+<glyph unicode="&#x1af;" horiz-adv-x="1430" d="M147 469v987h197v-987q0 -165 94 -250.5t248 -85.5q162 0 261.5 85.5t99.5 250.5v987h197v-178l6 -2q86 27 132 108.5t46 206.5h190l3 -5q2 -193 -96 -314.5t-281 -155.5v-647q0 -238 -154.5 -364t-403.5 -126q-240 0 -389.5 126.5t-149.5 363.5z" />
+<glyph unicode="&#x1b0;" horiz-adv-x="1204" d="M139 444v638h197v-640q0 -173 51 -238t159 -65q105 0 173.5 42.5t103.5 120.5v780h197v-114l6 -2q100 7 142.5 71t42.5 190h169l3 -6q3 -177 -85.5 -273t-277.5 -110v-838h-177l-13 160q-51 -87 -131 -134t-185 -47q-177 0 -276 113t-99 352z" />
+<glyph unicode="&#x1f0;" horiz-adv-x="523" d="M-68 -419l14 150q14 -5 46.5 -9t50.5 -4q59 0 93.5 51.5t34.5 141.5v1171h197v-1171q0 -167 -86 -257.5t-239 -90.5q-31 0 -56.5 4.5t-54.5 13.5zM-42 1484v20h166l147 -148l147 148h170v-18l-257 -245h-119z" />
+<glyph unicode="&#x1fa;" horiz-adv-x="1326" d="M20 0l563 1456h169l554 -1456h-201l-136 375h-610l-138 -375h-201zM420 540h490l-240 663h-6zM487 1684q0 72 51 119.5t124 47.5q70 0 120 -47.5t50 -119.5t-49.5 -118t-120.5 -46q-73 0 -124 46t-51 118zM575 1684q0 -35 25.5 -59.5t61.5 -24.5q34 0 58.5 24t24.5 60 q0 37 -24.5 62.5t-58.5 25.5q-36 0 -61.5 -25.5t-25.5 -62.5zM615 1900l144 185h199l2 -6l-216 -179h-129z" />
+<glyph unicode="&#x1fb;" horiz-adv-x="1126" d="M106 304q0 155 125.5 242.5t340.5 87.5h214v107q0 95 -58 150.5t-164 55.5q-95 0 -154.5 -48.5t-59.5 -116.5h-188l-2 6q-6 118 111.5 216t303.5 98q184 0 296 -93.5t112 -269.5v-521q0 -58 6 -112t22 -106h-203q-10 49 -15.5 86.5t-6.5 75.5q-55 -78 -143.5 -130.5 t-190.5 -52.5q-169 0 -257.5 86.5t-88.5 238.5zM303 300q0 -72 45 -114t133 -42q107 0 193 55t112 126v176h-221q-119 0 -190.5 -60t-71.5 -141zM383 1362q0 72 51 119.5t124 47.5q70 0 120 -47.5t50 -119.5t-49.5 -118t-120.5 -46q-73 0 -124 46t-51 118zM471 1362 q0 -35 25.5 -59.5t61.5 -24.5q34 0 58.5 24t24.5 60q0 37 -24.5 62.5t-58.5 25.5q-36 0 -61.5 -25.5t-25.5 -62.5zM511 1578l144 185h199l2 -6l-216 -179h-129z" />
+<glyph unicode="&#x1fc;" horiz-adv-x="1922" d="M-20 0l880 1456h967v-155h-691l20 -466h590v-155h-584l22 -526h705v-154h-895l-15 350h-557l-202 -350h-240zM525 529h447l-31 710l-5 2zM845 1556l185 266h230l2 -6l-270 -260h-147z" />
+<glyph unicode="&#x1fd;" horiz-adv-x="1729" d="M58 304q0 158 115 244.5t335 86.5h229v85q0 106 -51.5 166.5t-149.5 60.5q-103 0 -164 -55t-61 -133l-188 18l-2 6q-5 138 109.5 228.5t305.5 90.5q114 0 201.5 -40.5t137.5 -117.5q64 75 151.5 116.5t188.5 41.5q214 0 329.5 -130t115.5 -358v-119h-709l-2 -5 q1 -159 79.5 -258t233.5 -99q103 0 169.5 27.5t144.5 78.5l67 -138q-53 -44 -147 -83t-234 -39q-136 0 -240 48.5t-170 138.5q-56 -79 -167.5 -133t-271.5 -54q-170 0 -262.5 8

<TRUNCATED>

[32/51] [abbrv] ambari git commit: AMBARI-22384. Disable HDP 2.3 stack. (swagle)

Posted by nc...@apache.org.
AMBARI-22384. Disable HDP 2.3 stack. (swagle)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 7074e6e8a736fbdc1bb3afb86480c6cd349611b0
Parents: 5adcea7
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Wed Nov 8 13:07:11 2017 -0800
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Wed Nov 8 13:07:11 2017 -0800

----------------------------------------------------------------------
 ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7074e6e8/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
index f98b24b..9fa9b90 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/metainfo.xml
@@ -17,7 +17,7 @@
 -->
 <metainfo>
     <versions>
-	  <active>true</active>
+	  <active>false</active>
     </versions>
     <extends>2.2</extends>
     <minJdk>1.7</minJdk>


[22/51] [abbrv] ambari git commit: AMBARI-22337 each service should be able to implement server actions, package them add a jar to be loaded during EU (dili)

Posted by nc...@apache.org.
AMBARI-22337 each service should be able to implement server actions, package them add a jar to be loaded during EU (dili)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 063ba36ef5d2ae2f407b46aae3f993ab81eae310
Parents: 38f6740
Author: Di Li <di...@apache.org>
Authored: Tue Nov 7 10:51:48 2017 -0500
Committer: Di Li <di...@apache.org>
Committed: Tue Nov 7 10:51:48 2017 -0500

----------------------------------------------------------------------
 ambari-server/pom.xml                           |  12 ++
 .../serveraction/ServerActionExecutor.java      | 147 +++++++++++++++++--
 .../ambari/server/stack/ServiceDirectory.java   |  29 ++++
 .../ambari/server/stack/ServiceModule.java      |   8 +
 .../apache/ambari/server/state/ServiceInfo.java |  14 ++
 .../ambari/server/stack/ServiceModuleTest.java  |  30 ++++
 .../server/stack/StackManagerExtensionTest.java |   6 +
 7 files changed, 232 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index a86acf5..2ecf435 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -198,6 +198,18 @@
               </target>
             </configuration>
           </execution>
+          <execution>
+            <id>generate-test-oozie2-server-actions-dir</id>
+            <phase>process-test-classes</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <mkdir dir="target/test-classes/extensions/EXT/0.1/services/OOZIE2/server_actions/tmp"/>
+              </target>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
index 50e3cfe..e219dc3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/ServerActionExecutor.java
@@ -18,10 +18,17 @@
 
 package org.apache.ambari.server.serveraction;
 
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.ConcurrentHashMap;
@@ -38,11 +45,17 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.security.authorization.internal.InternalAuthenticationToken;
+import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.UpgradeContext.UpgradeServiceSummary;
+import org.apache.ambari.server.state.UpgradeContext.UpgradeSummary;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.ClassUtils;
 
 import com.google.inject.Inject;
 import com.google.inject.Injector;
@@ -495,7 +508,6 @@ public class ServerActionExecutor {
         throw new AmbariException("Missing ExecutionCommand data");
       } else {
         Map<String, String> roleParams = executionCommand.getRoleParams();
-
         if (roleParams == null) {
           throw new AmbariException("Missing RoleParams data");
         } else {
@@ -504,8 +516,30 @@ public class ServerActionExecutor {
           if (actionClassname == null) {
             throw new AmbariException("Missing action classname for server action");
           } else {
-            ServerAction action = createServerAction(actionClassname);
-
+            Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+            UpgradeSummary upgradeSummary = executionCommand.getUpgradeSummary();
+            if (upgradeSummary != null) {
+              Map<String, UpgradeServiceSummary> upgradeServiceSummaries = upgradeSummary.services;
+              LOG.debug("UpgradeServiceSummary: " + upgradeServiceSummaries);
+              AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+              AmbariMetaInfo ambariMetaInfo = ambariManagementController.getAmbariMetaInfo();
+              String serviceName = executionCommand.getServiceName();
+              if (serviceName != null && !serviceName.isEmpty()){
+                LOG.info(String.format("Server action %s is associated with service %s", actionClassname, serviceName));
+                //Execution stage of a given service, only need to examine stack information for this one service
+                UpgradeServiceSummary serviceSummary = upgradeServiceSummaries.get(serviceName);
+                addServiceInfo(services, ambariMetaInfo, serviceSummary.sourceStackId, serviceName);
+              } else {
+                LOG.info(String.format("Server action %s is not associated with a service", actionClassname));
+                //Load all Jars
+                for(String key: upgradeServiceSummaries.keySet()){
+                  UpgradeServiceSummary serviceSummary = upgradeServiceSummaries.get(key);
+                  addServiceInfo(services, ambariMetaInfo, serviceSummary.sourceStackId, key);
+                }
+              }
+              LOG.info(String.format("Attempt to load server action classes from %s", services.keySet().toString()));
+            }
+            ServerAction action = createServerAction(actionClassname, services);
             if (action == null) {
               throw new AmbariException("Failed to create server action: " + actionClassname);
             } else {
@@ -520,6 +554,30 @@ public class ServerActionExecutor {
       }
     }
 
+    private void addServiceInfo(Map<String, ServiceInfo> services, AmbariMetaInfo ambariMetaInfo, String stackId, String serviceName) {
+      List<String> stackInfo = getStackInfo(stackId);
+      LOG.debug(String.format("Stack info list: %s", stackInfo));
+      if (stackInfo.size() > 1) {
+        try {
+          ServiceInfo service = ambariMetaInfo.getService(stackInfo.get(0), stackInfo.get(1), serviceName);
+          LOG.debug(String.format("Adding %s to the list of services for loading external Jars...", service.getName()));
+          services.put(serviceName, service);
+        } catch (AmbariException e) {
+          LOG.error(String.format("Failed to obtain service info for stack %s, service name %s", stackId, serviceName), e);
+        }
+      }
+    }
+
+    private List<String> getStackInfo(String stackId) {
+      LOG.debug(String.format("Stack id: %s", stackId));
+      StringTokenizer tokens = new StringTokenizer(stackId, "-");
+      List<String> info = new ArrayList<String>();
+      while (tokens.hasMoreElements()) {
+        info.add((String)tokens.nextElement());
+      }
+      return info;
+    }
+
     /**
      * Attempts to create an instance of the ServerAction class implementation specified in
      * classname.
@@ -528,24 +586,85 @@ public class ServerActionExecutor {
      * @return the instantiated ServerAction implementation
      * @throws AmbariException
      */
-    private ServerAction createServerAction(String classname) throws AmbariException {
-      try {
-        Class<?> actionClass = Class.forName(classname);
+    private ServerAction createServerAction(String classname, Map<String, ServiceInfo> services) throws AmbariException {
+      Class<?> actionClass = null;
+      actionClass = getServerActionClass(classname);
+      if (actionClass == null) {
+        LOG.debug(String.format("Did not find %s in Ambari, try to load it from external directories", classname));
+        actionClass = getServiceLevelServerActionClass(classname, services);
+      }
 
-        if (actionClass == null) {
-          throw new AmbariException("Unable to load server action class: " + classname);
+      if (actionClass == null) {
+        throw new AmbariException("Unable to load server action class: " + classname);
+      } else {
+        LOG.debug(String.format("Ready to init server action %s", classname));
+        Class<? extends ServerAction> serverActionClass = actionClass.asSubclass(ServerAction.class);
+        if (serverActionClass == null) {
+          throw new AmbariException("Unable to execute server action class, invalid type: " + classname);
         } else {
-          Class<? extends ServerAction> serverActionClass = actionClass.asSubclass(ServerAction.class);
+          return injector.getInstance(serverActionClass);
+        }
+      }
+    }
 
-          if (serverActionClass == null) {
-            throw new AmbariException("Unable to execute server action class, invalid type: " + classname);
-          } else {
-            return injector.getInstance(serverActionClass);
+    /**
+     * Load server action classes defined in the service level Jar files
+     * */
+    private Class<?> getServiceLevelServerActionClass(String classname, Map<String, ServiceInfo> services) {
+      List<URL> urls = new ArrayList<>();
+      for (ServiceInfo service : services.values()) {
+        LOG.debug(String.format("Checking service %s", service));
+        File dir = service.getServerActionsFolder();
+        if ( dir != null) {
+          LOG.debug(String.format("Service %s, external dir %s",service.getName(), dir.getAbsolutePath()));
+          File[] jars = dir.listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+              LOG.debug(String.format("Checking folder %s", name));
+              return name.endsWith(".jar");
+            }
+          });
+          for (File jar : jars) {
+            try {
+              URL url = jar.toURI().toURL();
+              urls.add(url);
+              LOG.info("Adding server action jar to classpath: {}", url);
+            }
+            catch (Exception e) {
+              LOG.error("Failed to add server action jar to classpath: {}", jar.getAbsolutePath(), e);
+            }
           }
+        } else {
+          LOG.error(String.format("%s service server actions folder returned null", service));
+        }
+      }
+
+      ClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), ClassUtils.getDefaultClassLoader());
+      Class<?> actionClass = null;
+      try {
+        actionClass = ClassUtils.resolveClassName(classname, classLoader);
+        LOG.debug(String.format("Found external server action %s", classname));
+      } catch(IllegalArgumentException illegalArgumentException) {
+        LOG.error(String.format("Unable to find server action %s in external server action directories", classname), illegalArgumentException);
+      }
+
+      return actionClass;
+    }
+
+    /**
+     * Load server action classes defined in Ambari source code
+     * */
+    private Class<?> getServerActionClass(String classname) throws AmbariException{
+      Class<?> actionClass = null;
+      try {
+        actionClass = Class.forName(classname);
+        if (actionClass == null) {
+          LOG.warn(String.format("Unable to load server action class: %s from Ambari", classname));
         }
       } catch (ClassNotFoundException e) {
-        throw new AmbariException("Unable to load server action class: " + classname, e);
+        LOG.error(String.format("Unable to load server action class: %s", classname), e);
       }
+      return actionClass;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
index 119163e..7464e61 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
@@ -93,6 +93,11 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
   protected File checksDir;
 
   /**
+   * server side action directory path
+   */
+  protected File serverActionsDir;
+
+  /**
    * service metainfo file object representation
    */
   private ServiceMetainfoXml metaInfoXml;
@@ -118,6 +123,11 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
   protected static final String CHECKS_FOLDER_NAME = "checks";
 
   /**
+   * Server actions directory name
+   */
+  protected static final String SERVER_ACTIONS_FOLDER_NAME = "server_actions";
+
+  /**
    * service metainfo file name
    */
   private static final String SERVICE_METAINFO_FILE_NAME = "metainfo.xml";
@@ -172,6 +182,15 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
   }
 
   /**
+   * Obtain the server side actions directory path.
+   *
+   * @return server side actions directory path
+   */
+  public File getServerActionsDir() {
+    return serverActionsDir;
+  }
+
+  /**
    * Obtain the metrics file.
    *
    * @return metrics file
@@ -303,6 +322,7 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
 	  calculatePackageDirectory(stack, service);
 	  calculateUpgradesDirectory(stack, service);
 	  calculateChecksDirectory(stack, service);
+	  calculateServerActionsDirectory(stack, service);
   }
 
   /**
@@ -378,6 +398,15 @@ public abstract class ServiceDirectory extends StackDefinitionDirectory {
   }
 
   /**
+   * Sets the serverActionsDir if the dir exists and is not empty
+   * @param stack
+   * @param service
+   */
+  protected void calculateServerActionsDirectory(String stack, String service) {
+    serverActionsDir = resolveDirectory(SERVER_ACTIONS_FOLDER_NAME, stack, service);
+  }
+
+  /**
    * Unmarshal the metainfo file into its object representation.
    *
    * @throws AmbariException if the metainfo file doesn't exist or

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
index 3b3d52c..4eb3858 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
@@ -150,6 +150,7 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
     serviceInfo.setServicePackageFolder(serviceDirectory.getPackageDir());
     serviceInfo.setServiceUpgradesFolder(serviceDirectory.getUpgradesDir());
     serviceInfo.setChecksFolder(serviceDirectory.getChecksDir());
+    serviceInfo.setServerActionsFolder(serviceDirectory.getServerActionsDir());
     serviceInfo.setAdvisorFile(serviceDirectory.getAdvisorFile());
     serviceInfo.setAdvisorName(serviceDirectory.getAdvisorName(serviceInfo.getName()));
 
@@ -270,6 +271,13 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem
     }
 
     /*
+     * Use parent's server actions if the current one does not have any.
+     */
+    if (serviceInfo.getServerActionsFolder() == null) {
+      serviceInfo.setServerActionsFolder(parent.getServerActionsFolder());
+    }
+
+    /*
      * If current stack version does not specify the credential store information
      * for the service, then use parent definition.
      */

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 8fe6583..f1c63bf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -305,6 +305,12 @@ public class ServiceInfo implements Validable{
   @XmlTransient
   private File checksFolder;
 
+  /**
+   * Stores the path to the server actions folder which contains server actions jars for the given service.
+   */
+  @XmlTransient
+  private File serverActionsFolder;
+
   public boolean isDeleted() {
     return isDeleted;
   }
@@ -796,6 +802,14 @@ public class ServiceInfo implements Validable{
     this.checksFolder = checksFolder;
   }
 
+  public File getServerActionsFolder() {
+    return serverActionsFolder;
+  }
+
+  public void setServerActionsFolder(File serverActionsFolder) {
+    this.serverActionsFolder = serverActionsFolder;
+  }
+
   /**
    * Exposes (and initializes on first use) map of os-specific details.
    * @return  map of OS specific details keyed by family

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
index dbdd043..13c32cf 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java
@@ -499,6 +499,36 @@ public class ServiceModuleTest {
   }
 
   @Test
+  public void testResolve_ServerActionDirectory() throws Exception {
+    File serverActions = new File("server_actions");
+
+    // check directory specified in child only
+    ServiceInfo info = new ServiceInfo();
+    ServiceInfo parentInfo = new ServiceInfo();
+    ServiceModule child = createServiceModule(info);
+    ServiceModule parent = createServiceModule(parentInfo);
+    child.getModuleInfo().setServerActionsFolder(serverActions);
+    resolveService(child, parent);
+    assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+
+    // check directory specified in parent only
+    child = createServiceModule(info);
+    parent = createServiceModule(parentInfo);
+    parent.getModuleInfo().setServerActionsFolder(serverActions);
+    resolveService(child, parent);
+    assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+
+    // check directory set in both
+    info.setServerActionsFolder(serverActions);
+    child = createServiceModule(info);
+    child.getModuleInfo().setServerActionsFolder(serverActions);
+    parent = createServiceModule(parentInfo);
+    parent.getModuleInfo().setServerActionsFolder(new File("other"));
+    resolveService(child, parent);
+    assertEquals(serverActions.getPath(), child.getModuleInfo().getServerActionsFolder().getPath());
+  }
+
+  @Test
   public void testResolve_CustomCommands() throws Exception {
     List<CustomCommandDefinition> customCommands = new ArrayList<>();
     CustomCommandDefinition cmd1 = new CustomCommandDefinition();

http://git-wip-us.apache.org/repos/asf/ambari/blob/063ba36e/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
index 6617b33..bf55e6f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/StackManagerExtensionTest.java
@@ -140,6 +140,9 @@ public class StackManagerExtensionTest  {
     File checks = oozie.getChecksFolder();
     assertNotNull(checks);
     assertTrue("Checks dir is " + checks.getPath(), checks.getPath().contains("extensions/EXT/0.1/services/OOZIE2/checks"));
+    File serverActions = oozie.getServerActionsFolder();
+    assertNotNull(serverActions);
+    assertTrue("Server actions dir is " + serverActions.getPath(), serverActions.getPath().contains("extensions/EXT/0.1/services/OOZIE2/server_actions"));
     List<ThemeInfo> themes = oozie.getThemes();
     assertNotNull(themes);
     assertTrue("Number of themes is " + themes.size(), themes.size() == 1);
@@ -158,6 +161,9 @@ public class StackManagerExtensionTest  {
     checks = oozie.getChecksFolder();
     assertNotNull(checks);
     assertTrue("Checks dir is " + checks.getPath(), checks.getPath().contains("extensions/EXT/0.1/services/OOZIE2/checks"));
+    serverActions = oozie.getServerActionsFolder();
+    assertNotNull(serverActions);
+    assertTrue("Server actions dir is " + serverActions.getPath(), serverActions.getPath().contains("extensions/EXT/0.1/services/OOZIE2/server_actions"));
     themes = oozie.getThemes();
     assertNotNull(themes);
     assertTrue("Number of themes is " + themes.size(), themes.size() == 0);


[38/51] [abbrv] ambari git commit: AMBARI-22400 Ambari 3.0: Implement new design for Admin View: Cluster Information page. (atkach)

Posted by nc...@apache.org.
AMBARI-22400 Ambari 3.0: Implement new design for Admin View: Cluster Information page. (atkach)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 430dcbf1224996c76276a8c40fb58eb54addd10a
Parents: e968b12
Author: Andrii Tkach <at...@apache.org>
Authored: Thu Nov 9 16:13:29 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Thu Nov 9 16:53:02 2017 +0200

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   3 +-
 .../app/scripts/controllers/AppCtrl.js          |   2 +-
 .../controllers/ClusterInformationCtrl.js       |  65 +++++++++++
 .../controllers/clusters/ExportBlueprintCtrl.js |  58 ----------
 .../app/scripts/controllers/mainCtrl.js         |  27 -----
 .../ui/admin-web/app/scripts/i18n.config.js     |  13 +--
 .../ui/admin-web/app/scripts/routes.js          |  59 +++++-----
 .../app/styles/cluster-information.css          |  59 ++++++++++
 .../resources/ui/admin-web/app/styles/main.css  |  98 -----------------
 .../admin-web/app/views/clusterInformation.html |  66 ++++++++++++
 .../app/views/clusters/exportBlueprint.html     |  40 -------
 .../ui/admin-web/app/views/groups/list.html     |   3 +-
 .../resources/ui/admin-web/app/views/main.html  | 107 -------------------
 .../app/views/remoteClusters/list.html          |   3 +-
 .../ui/admin-web/app/views/sideNav.html         |  19 ++--
 .../admin-web/app/views/stackVersions/list.html |   3 +-
 .../ui/admin-web/app/views/users/list.html      |   3 +-
 .../test/unit/services/Utility_test.js          |   2 +-
 18 files changed, 240 insertions(+), 390 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index 41cc60f..2b350f0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -121,7 +121,7 @@
 <script src="scripts/app.js"></script>
 <script src="scripts/routes.js"></script>
 <script src="scripts/i18n.config.js"></script>
-<script src="scripts/controllers/mainCtrl.js"></script>
+<script src="scripts/controllers/ClusterInformationCtrl.js"></script>
 <script src="scripts/controllers/AppCtrl.js"></script>
 <script src="scripts/controllers/SideNavCtrl.js"></script>
 <script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script>
@@ -142,7 +142,6 @@
 <script src="scripts/controllers/ambariViews/CloneViewInstanceCtrl.js"></script>
 <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
 <script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
-<script src="scripts/controllers/clusters/ExportBlueprintCtrl.js"></script>
 <script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script>
 <script src="scripts/controllers/stackVersions/StackVersionsListCtrl.js"></script>
 <script src="scripts/controllers/stackVersions/StackVersionsEditCtrl.js"></script>

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
index 4ac5b38..eb9a9b0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/AppCtrl.js
@@ -31,7 +31,7 @@ angular.module('ambariAdminConsole')
     return $route.current;
   }, function (value) {
     var breadcrumbs = [$t('common.admin')];
-    if (value && value.$$route.label) {
+    if (value && value.$$route && value.$$route.label) {
       breadcrumbs.push(value.$$route.label);
     }
     $scope.breadcrumbs = breadcrumbs;

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
new file mode 100644
index 0000000..60a610c
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ClusterInformationCtrl.js
@@ -0,0 +1,65 @@
+/**
+ * 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('ClusterInformationCtrl', ['$scope', '$http', '$location', 'Cluster', '$routeParams', '$translate', '$rootScope',
+function($scope, $http, $location, Cluster, $routeParams, $translate, $rootScope) {
+  var $t = $translate.instant;
+  $scope.isDataLoaded = false;
+
+  $scope.$watch(function() {
+    return $rootScope.cluster;
+  }, function() {
+    $scope.cluster = $rootScope.cluster;
+    if ($scope.cluster) {
+      $scope.getBlueprint();
+    }
+  }, true);
+
+  $scope.getBlueprint = function () {
+    Cluster.getBlueprint({
+      clusterName: $scope.cluster.Clusters.cluster_name
+    }).then(function (data) {
+      console.debug($t('exportBlueprint.dataLoaded'), data);
+      $scope.isDataLoaded = true;
+      var response = JSON.stringify(data, null, 4),
+        lt = /&lt;/g,
+        gt = /&gt;/g,
+        ap = /&#39;/g,
+        ic = /&#34;/g;
+      $scope.blueprint = response ? response.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, '"') : "";
+    });
+  };
+
+  $scope.downloadBlueprint = function () {
+    if (window.navigator.msSaveOrOpenBlob) {
+      var blob = new Blob([decodeURIComponent(encodeURI($scope.blueprint))], {
+        type: "text/csv;charset=utf-8;"
+      });
+      navigator.msSaveBlob(blob, 'blueprint.json');
+    } else {
+      var a = document.createElement('a');
+      a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI($scope.blueprint);
+      a.target = '_blank';
+      a.download = 'blueprint.json';
+      document.body.appendChild(a);
+      a.click();
+    }
+  };
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
deleted file mode 100644
index 6b74b40..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/clusters/ExportBlueprintCtrl.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('ExportBlueprintCtrl', ['$scope', '$http', '$location', 'Cluster', '$routeParams', '$translate', function($scope, $http, $location, Cluster, $routeParams, $translate) {
-  var $t = $translate.instant;
-  $scope.identity = angular.identity;
-
-  $scope.isDataLoaded = false;
-  $scope.clusterName = $routeParams.id;
-
-  $scope.getBlueprint = function() {
-    Cluster.getBlueprint({
-      clusterName: $scope.clusterName
-    }).then(function(data) {
-      console.debug($t('exportBlueprint.dataLoaded'), data);
-      $scope.isDataLoaded = true;
-      var response = JSON.stringify(data, null, 4),
-        lt = /&lt;/g,
-        gt = /&gt;/g,
-        ap = /&#39;/g,
-        ic = /&#34;/g;
-      $scope.blueprint = response ? response.toString().replace(lt, "<").replace(gt, ">").replace(ap, "'").replace(ic, '"') : "";
-    });
-  };
-
-  $scope.downloadBlueprint = function() {
-    if (window.navigator.msSaveOrOpenBlob) {
-      var blob = new Blob([decodeURIComponent(encodeURI($scope.blueprint))], {
-        type: "text/csv;charset=utf-8;"
-      });
-      navigator.msSaveBlob(blob, 'blueprint.json');
-    } else {
-      var a = document.createElement('a');
-      a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI($scope.blueprint);
-      a.target = '_blank';
-      a.download = 'blueprint.json';
-      document.body.appendChild(a);
-      a.click();
-    }
-  };
-}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
deleted file mode 100644
index 30f7568..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.
- */
-'use strict';
-
-angular.module('ambariAdminConsole')
-.controller('MainCtrl',['$scope','$rootScope', function($scope, $rootScope) {
-  $scope.$watch(function() {
-    return $rootScope.cluster;
-  }, function() {
-    $scope.cluster = $rootScope.cluster;
-  }, true);
-}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index 73ab064..4ef3ee9 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -41,7 +41,6 @@ angular.module('ambariAdminConsole')
     'common.dashboard': 'Dashboard',
     'common.goToDashboard': 'Go to Dashboard',
     'common.exportBlueprint': 'Export Blueprint',
-    'common.blueprint': 'Blueprint',
     'common.download': 'Download',
     'common.noClusters': 'No Clusters',
     'common.noViews': 'No Views',
@@ -168,23 +167,12 @@ angular.module('ambariAdminConsole')
 
     'main.title': 'Welcome to Apache Ambari',
     'main.noClusterDescription': 'Provision a cluster, manage who can access the cluster, and customize views for Ambari users.',
-    'main.hasClusterDescription': 'Monitor your cluster resources, manage who can access the cluster, and customize views for Ambari users.',
     'main.autoLogOut': 'Automatic Logout',
 
-    'main.operateCluster.title': 'Operate Your Cluster',
-    'main.operateCluster.description': 'Manage the configuration of your cluster and monitor the health of your services',
-    'main.operateCluster.manageRoles': 'Manage Roles',
-
     'main.createCluster.title': 'Create a Cluster',
     'main.createCluster.description': 'Use the Install Wizard to select services and configure your cluster',
     'main.createCluster.launchInstallWizard': 'Launch Install Wizard',
 
-    'main.manageUsersAndGroups.title': 'Manage Users + Groups',
-    'main.manageUsersAndGroups.description': 'Manage the users and groups that can access Ambari',
-
-    'main.deployViews.title': 'Deploy Views',
-    'main.deployViews.description': 'Create view instances and grant permissions',
-
     'main.controls.remainLoggedIn': 'Remain Logged In',
     'main.controls.logOut': 'Log Out Now',
 
@@ -284,6 +272,7 @@ angular.module('ambariAdminConsole')
     'clusters.assignRoles': 'Assign roles to these {{term}}',
 
     'clusters.alerts.cannotLoadClusterData': 'Cannot load cluster data',
+    'clusters.devBlueprint': 'Dev Blueprint',
 
     'groups.createLocal': 'Add Groups',
     'groups.name': 'Group name',

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index 2cb077a..486e598 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -19,12 +19,6 @@
 
 angular.module('ambariAdminConsole')
 .constant('ROUTES', {
-  root: {
-    url: '/',
-    templateUrl: 'views/main.html',
-    controller: 'MainCtrl',
-    label: 'Welcome'
-  },
   authentication: {
     main: {
       url: '/authentication',
@@ -33,7 +27,7 @@ angular.module('ambariAdminConsole')
     }
   },
   loginActivities: {
-    loginMessage:{
+    loginMessage: {
       url: '/loginMessage',
       templateUrl: 'views/loginActivities/main.html',
       controller: 'LoginActivitiesMainCtrl'
@@ -109,19 +103,19 @@ angular.module('ambariAdminConsole')
       controller: 'ViewsEditCtrl',
       label: 'Views'
     },
-    createViewUrl:{
+    createViewUrl: {
       url: '/urls/new',
       templateUrl: 'views/urls/create.html',
       controller: 'ViewUrlCtrl',
       label: 'Views'
     },
-    linkViewUrl:{
+    linkViewUrl: {
       url: '/urls/link/:viewName/:viewVersion/:viewInstanceName',
       templateUrl: 'views/urls/create.html',
       controller: 'ViewUrlCtrl',
       label: 'Views'
     },
-    editViewUrl:{
+    editViewUrl: {
       url: '/urls/edit/:urlName',
       templateUrl: 'views/urls/edit.html',
       controller: 'ViewUrlEditCtrl',
@@ -133,19 +127,19 @@ angular.module('ambariAdminConsole')
       url: '/stackVersions',
       templateUrl: 'views/stackVersions/list.html',
       controller: 'StackVersionsListCtrl',
-      label: 'Cluster Information'
+      label: 'Versions'
     },
     create: {
       url: '/stackVersions/create',
       templateUrl: 'views/stackVersions/stackVersionPage.html',
       controller: 'StackVersionsCreateCtrl',
-      label: 'Cluster Information'
+      label: 'Versions'
     },
     edit: {
       url: '/stackVersions/:stackName/:versionId/edit',
       templateUrl: 'views/stackVersions/stackVersionPage.html',
       controller: 'StackVersionsEditCtrl',
-      label: 'Cluster Information'
+      label: 'Versions'
     }
   },
   remoteClusters: {
@@ -161,12 +155,12 @@ angular.module('ambariAdminConsole')
       controller: 'RemoteClustersCreateCtrl',
       label: 'Remote Clusters'
     },
-     edit: {
-     url: '/remoteClusters/:clusterName/edit',
-     templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
-     controller: 'RemoteClustersEditCtrl',
-       label: 'Remote Clusters'
-     }
+    edit: {
+      url: '/remoteClusters/:clusterName/edit',
+      templateUrl: 'views/remoteClusters/editRemoteClusterPage.html',
+      controller: 'RemoteClustersEditCtrl',
+      label: 'Remote Clusters'
+    }
   },
   clusters: {
     manageAccess: {
@@ -180,31 +174,36 @@ angular.module('ambariAdminConsole')
       templateUrl: 'views/clusters/userAccessList.html',
       controller: 'UserAccessListCtrl'
     },
-    exportBlueprint: {
-      url: '/clusters/:id/exportBlueprint',
-      templateUrl: 'views/clusters/exportBlueprint.html',
-      controller: 'ExportBlueprintCtrl'
+    clusterInformation: {
+      url: '/clusterInformation',
+      templateUrl: 'views/clusterInformation.html',
+      controller: 'ClusterInformationCtrl',
+      label: 'Cluster Information'
     }
   },
-  dashboard:{
+  dashboard: {
     url: '/dashboard',
-    controller: ['$window', function($window) {
+    controller: ['$window', function ($window) {
       $window.location.replace('/#/main/dashboard');
     }],
     template: ''
   }
 })
-.config(['$routeProvider', '$locationProvider', 'ROUTES', function($routeProvider, $locationProvider, ROUTES) {
-  var createRoute = function(routeObj) {
-    if(routeObj.url){
+.config(['$routeProvider', '$locationProvider', 'ROUTES', function ($routeProvider, $locationProvider, ROUTES) {
+  var createRoute = function (routeObj) {
+    if (routeObj.url) {
       $routeProvider.when(routeObj.url, routeObj);
     } else {
       angular.forEach(routeObj, createRoute);
     }
   };
+  var rootUrl = ROUTES['clusters']['clusterInformation'].url;
   angular.forEach(ROUTES, createRoute);
+  $routeProvider.otherwise({
+    redirectTo: rootUrl
+  });
 }])
-.run(['$rootScope', 'ROUTES', 'Settings', function($rootScope, ROUTES, Settings) {
+.run(['$rootScope', 'ROUTES', 'Settings', function ($rootScope, ROUTES, Settings) {
   // Make routes available in every template and controller
   $rootScope.ROUTES = ROUTES;
   $rootScope.$on('$locationChangeStart', function (e, nextUrl) {
@@ -226,7 +225,7 @@ angular.module('ambariAdminConsole')
    * @param {string} url
    * @returns {string}
    */
-  $rootScope.fromSiteRoot = function(url) {
+  $rootScope.fromSiteRoot = function (url) {
     var path = url[0] === '/' ? url.substring(1) : url;
     return Settings.siteRoot + path;
   };

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
new file mode 100644
index 0000000..63f4150
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/cluster-information.css
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+#cluster-information .cluster-name label {
+  font-weight: normal;
+}
+
+#cluster-information .dev-blueprint {
+  line-height: 35px;
+}
+
+#cluster-information .dev-blueprint span {
+  vertical-align: text-top;
+}
+
+#cluster-information .cluster-name label {
+  font-weight: normal;
+}
+
+#cluster-information .dev-blueprint {
+  line-height: 35px;
+}
+
+#cluster-information .dev-blueprint span {
+  vertical-align: text-top;
+}
+
+
+#cluster-information .welcome-header {
+  margin: -15px;
+  padding: 15px 15px 40px 15px;
+  background-color: #f0f0f0;
+  text-align: center;
+}
+
+#cluster-information .create-cluster-section {
+  text-align: center;
+  padding: 30px;
+}
+
+#cluster-information .fa-cloud {
+  font-size: 150px;
+  color: #f0f0f0;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index bd06bc0..4224f62 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -123,14 +123,6 @@
   transition: none;
 }
 
-.cluster-installation-progress-label{
-  display: block;
-  color: #888;
-  text-align: center;
-  padding: 10px 0;
-  cursor: default;
-}
-
 .add-item-input span{
   display: block;
   outline: none;
@@ -236,96 +228,6 @@
 .paginator{
   margin: 0;
 }
-.mainpage .panel-body{
-  padding: 20px;
-  height: 620px;
-}
-.mainpage h1{
-  font-size: 24px;
-  margin-top: 10px;
-}
-.mainpage .panel-body #main-operations-boxes {
-  padding: 10px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail{
-  display: block;
-  height: 230px;
-  padding: 8px;
-  background-color: #eeeeee;
-  margin-bottom: 20px;
-  margin-left: 20px;
-  margin-right: 10px;
-  border: none;
-  border-radius: 0;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .title,
-.mainpage .panel-body #main-operations-boxes .thumbnail .description,
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons {
-  text-align: center;
-  line-height: 1.5;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn{
-  width: 200px;
-  margin: 5px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.userslist-button,
-.mainpage .panel-body #main-operations-boxes .thumbnail .buttons .btn.groupslist-button {
-  width: 100px;
-}
-.mainpage .panel-body #main-operations-boxes .thumbnail .glyphicon {
-  font-size: 50px;
-  text-align: center;
-  display: block;
-  line-height: 1.5;
-}
-.mainpage .panel-body #main-operations-boxes .col-sm-5 {
-  width: 43.5%;
-}
-
-.views-list-table .panel{
-  border-radius: 0;
-  border: none;
-  margin-top: 0;
-}
-.views-list-table h4{
-  font-size: 14px;
-}
-.views-list-table .panel-group .panel + .panel{
-  margin-top: 0;
-}
-.views-list-table .panel-group .panel .panel-heading{
-  border-radius: 0;
-  border-top: 1px solid #ddd;
-}
-.views-list-table .panel-group .panel .panel-heading{
-  background: #f9f9f9;
-}
-.views-list-table .panel-group .panel:nth-child(even) .panel-heading{
-  background: none;
-}
-.views-list-table .panel-group .panel .panel-heading .panel-title{
-  font-size: 14px;
-  font-weight: normal;
-  cursor: pointer;
-}
-.views-list-table .panel-group .panel .panel-body{
-  padding-top: 0;
-  padding-bottom: 0;
-}
-.views-list-table .panel-group .panel .panel-body table tr:first-child td{
-  border-top: none;
-}
-.views-list-table .glyphicon.glyphicon-chevron-right{
-  -webkit-transition: all 0.3s;
-  -o-transition: all 0.3s;
-  transition: all 0.3s;
-}
-.views-list-table .glyphicon.glyphicon-chevron-right.opened{
-  -webkit-transform: rotateZ(90deg);
-  -ms-transform: rotateZ(90deg);
-  -o-transform: rotateZ(90deg);
-  transform: rotateZ(90deg);
-}
 
 a.gotoinstance{
   font-size: 12px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
new file mode 100644
index 0000000..6334d06
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusterInformation.html
@@ -0,0 +1,66 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div id="cluster-information">
+  <div ng-show="cluster.Clusters.provisioning_state !== 'INSTALLED'">
+    <div class="welcome-header">
+      <h1>{{'main.title' | translate}}</h1>
+      <span>{{'main.noClusterDescription' | translate}}</span>
+    </div>
+    <div class="create-cluster-section">
+      <h2>{{'main.createCluster.title' | translate}}</h2>
+      <div>
+        <span>
+          {{'main.createCluster.description' | translate}}
+        </span>
+      </div>
+      <div><i class="fa fa-cloud" aria-hidden="true"></i></div>
+      <div>
+        <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary">
+          {{'main.createCluster.launchInstallWizard' | translate}}
+        </a>
+      </div>
+    </div>
+  </div>
+
+  <div ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
+    <div class="row">
+      <div class="form-group col-xs-3 cluster-name">
+        <label for="clusterName">{{'views.clusterName' | translate}}*</label>
+        <input type="text" class="form-control" id="clusterName" ng-model="cluster.Clusters.cluster_name">
+      </div>
+    </div>
+    <div>
+      <div class="row dev-blueprint">
+        <div class="col-sm-11"><span>{{'clusters.devBlueprint' | translate}}</span></div>
+        <div class="col-sm-1">
+          <div class="btn btn-default pull-right" ng-click="downloadBlueprint()">{{"common.download" | translate}}
+          </div>
+        </div>
+      </div>
+      <textarea type="text"
+                rows="20"
+                class="form-control"
+                name="blueprint_text"
+                ng-model="blueprint"
+                ng-disabled="true"
+                ng-readonly="true">
+      </textarea>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
deleted file mode 100644
index 6ccbffe..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/exportBlueprint.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<div class="cluster-manage-access-pane" data-ng-init="getBlueprint()" ng-controller="ExportBlueprintCtrl">
-  <div class="clearfix">
-    <ol class="breadcrumb pull-left">
-      <li class="active">{{clusterName}} {{'common.blueprint' | translate}}</li>
-    </ol>
-    <div class="pull-right top-margin-4">
-      <div class="pull-right top-margin-4">
-        <div class="btn btn-default" ng-click="downloadBlueprint()">{{"common.download" | translate}}</div>
-      </div>
-    </div>
-  </div>
-  <hr>
-  <div>
-    <textarea type="text"
-               rows="20"
-               class="form-control"
-               name="blueprint_text"
-               ng-model="blueprint"
-               ng-disabled="true"
-               ng-readonly="true">
-    </textarea>
-  </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
index 5271ceb..b39f55d 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/groups/list.html
@@ -26,7 +26,6 @@
       </link-to>
     </div>
   </div>
-  <hr>
   <table class="table table-striped table-hover col-sm-12">
     <thead>
       <tr>
@@ -63,7 +62,7 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert alert-info col-sm-12" ng-show="!groups.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!groups.length && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate: '{term: constants.groups}'}}
   </div>
   <div class="col-sm-12 table-bar">

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
deleted file mode 100644
index 3c382af..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/main.html
+++ /dev/null
@@ -1,107 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-<div class="panel panel-default mainpage">
-  <div class="panel-body">
-    <h1>{{'main.title' | translate}}</h1>
-
-    <div id="main-operations-boxes" class="row thumbnails">
-      <p ng-hide="cluster">{{'main.noClusterDescription' | translate}}</p>
-
-      <p ng-show="cluster">{{'main.hasClusterDescription' | translate}}</p>
-
-      <!--Clusters-->
-      <div ng-show="cluster" class="col-sm-11 thumbnail">
-        <h4 class="title">{{'main.operateCluster.title' | translate}}</h4>
-
-        <div class="description">{{'main.operateCluster.description' | translate}}</div>
-        <div class="glyphicon glyphicon-cloud"></div>
-        <div class="buttons">
-        <span ng-class="{active: isActive('clusters.manageAccess')}">
-          <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
-                  class="btn btn-primary permission-button"
-                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
-            {{'main.operateCluster.manageRoles' | translate}}
-          </a>
-          <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
-                  href="#/clusters/{{cluster.Clusters.cluster_name}}/userAccessList"
-                  class="btn btn-primary permission-button"
-                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
-            {{'main.operateCluster.manageRoles' | translate}}
-          </a>
-        </span>
-        <span>
-          <a ng-show="cluster.Clusters.provisioning_state != 'INSTALLED'" href
-                  class="btn btn-primary go-dashboard-button"
-                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
-            {{'common.goToDashboard' | translate}}
-          </a>
-          <a ng-show="cluster.Clusters.provisioning_state == 'INSTALLED'"
-                  href="{{fromSiteRoot('/#/main/dashboard/metrics')}}" class="btn btn-primary go-dashboard-button"
-                  ng-disabled="cluster.Clusters.provisioning_state != 'INSTALLED' ">
-            {{'common.goToDashboard' | translate}}
-          </a>
-        </span>
-        </div>
-      </div>
-      <div ng-hide="cluster" class="col-sm-11 thumbnail">
-        <h4 class="title">{{'main.createCluster.title' | translate}}</h4>
-
-        <div class="description">{{'main.createCluster.description' | translate}}</div>
-        <div class="glyphicon glyphicon-cloud"></div>
-        <div class="buttons">
-          <a href="{{fromSiteRoot('/#/installer/step0')}}" class="btn btn-primary create-cluster-button">
-            {{'main.createCluster.launchInstallWizard' | translate}}
-          </a>
-        </div>
-      </div>
-
-      <!--Manage Users and groups-->
-      <div class="col-sm-5 thumbnail">
-        <h4 class="title">{{'main.manageUsersAndGroups.title' | translate}}</h4>
-
-        <div class="description">{{'main.manageUsersAndGroups.description' | translate}}</div>
-        <div class="glyphicon glyphicon-user"></div>
-        <div class="buttons">
-          <span ng-class="{active: isActive('users.list')}">
-            <link-to route="users.list" class="btn btn-primary userslist-button">
-            {{'common.users' | translate}}
-            </link-to>
-          </span>
-          <span ng-class="{active: isActive('groups.list')}">
-            <link-to route="groups.list" class="btn btn-primary groupslist-button">
-            {{'common.groups' | translate}}
-            </link-to>
-          </span>
-        </div>
-      </div>
-
-      <!--Deploy Views-->
-      <div class="col-sm-5 thumbnail">
-        <h4 class="title">{{'main.deployViews.title' | translate}}</h4>
-
-        <div class="description">{{'main.deployViews.description' | translate}}</div>
-        <div class="glyphicon glyphicon-th"></div>
-        <div ng-class="{active: isActive('views.list')}" class="buttons">
-          <link-to route="views.list" class="btn btn-primary viewslist-button">
-            {{'common.views' | translate}}
-          </link-to>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
index e3e11d5..8bb6632 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html
@@ -27,7 +27,6 @@
       </a>
     </div>
   </div>
-  <hr>
   <table class="table table-striped table-hover">
     <thead>
       <tr>
@@ -62,7 +61,7 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert alert-info col-sm-12" ng-show="!remoteClusters.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!remoteClusters.length && !isLoading">
     {{'common.alerts.noRemoteClusterDisplay' | translate}}
   </div>
   <div class="col-sm-12 table-bar">

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
index 09b4cd9..97dc5d3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/sideNav.html
@@ -33,36 +33,43 @@
       </li>
     </ul>
     <ul class="nav side-nav-menu nav-pills nav-stacked">
-      <li class="mainmenu-li active">
+      <li class="mainmenu-li active" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
         <a title="{{'common.dashboard' | translate}}" rel="tooltip" data-placement="right" href="{{fromSiteRoot('/#/dashboard')}}" class="gotodashboard">
           <i class="navigation-icon fa fa-tachometer" aria-hidden="true"></i>
           <span class="navigation-menu-item">{{'common.dashboard' | translate}}</span>
         </a>
       </li>
-      <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+      <li class="mainmenu-li dropdown has-sub-menu">
         <a title="{{'common.clusterManagement' | translate}}" data-toggle="collapse-sub-menu" rel="tooltip" data-placement="right">
           <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
           <i class="navigation-icon fa fa-cloud" aria-hidden="true"></i>
           <span class="navigation-menu-item">{{'common.clusterManagement' | translate}}</span>
         </a>
         <ul class="sub-menu nav nav-pills nav-stacked">
+          <li class="submenu-li" ng-class="{active: isActive('clusters.clusterInformation')}">
+            <a href="#/clusterInformation" class="clusterInformation">
+              {{'common.clusterInformation' | translate}}
+            </a>
+          </li>
           <li class="submenu-li"  ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0">
-            <a href="#/stackVersions">{{'common.clusterInformation' | translate}}</a>
+            <a href="#/stackVersions">{{'common.versions' | translate}}</a>
           </li>
           <li class="submenu-li" ng-class="{active: isActive('remoteClusters.list')}">
             <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a>
           </li>
         </ul>
       </li>
-      <li class="mainmenu-li dropdown has-sub-menu" ng-show="cluster.Clusters.provisioning_state === 'INSTALLED' ">
+      <li class="mainmenu-li dropdown has-sub-menu">
         <a title="{{'common.userManagement' | translate}}" rel="tooltip" data-placement="right" data-toggle="collapse-sub-menu">
           <span class="toggle-icon glyphicon glyphicon-menu-down pull-right"></span>
           <i class="navigation-icon fa fa-users" aria-hidden="true"></i>
           <span class="navigation-menu-item">{{'common.userManagement' | translate}}</span>
         </a>
         <ul class="sub-menu nav nav-pills nav-stacked">
-          <li class="submenu-li" ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}">
-            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">Roles</a>
+          <li class="submenu-li"
+              ng-class="{active: isActive('clusters.manageAccess') || isActive('clusters.userAccessList')}"
+              ng-show="cluster.Clusters.provisioning_state === 'INSTALLED'">
+            <a href="#/clusters/{{cluster.Clusters.cluster_name}}/manageAccess" class="roles">{{'common.roles' | translate}}</a>
           </li>
           <li class="submenu-li" ng-class="{active: isActive('users.list')}">
             <link-to route="users.list" class="userslist-link">{{'common.users' | translate}}</link-to>

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
index f6b6ee9..99f9ac0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/list.html
@@ -27,7 +27,6 @@
       </a>
     </div>
   </div>
-  <hr/>
   <table class="table table-striped table-hover">
     <thead>
     <tr>
@@ -119,7 +118,7 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert alert-info col-sm-12" ng-show="!repos.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!repos.length && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate: '{term: getConstant("common.version")}'}}
   </div>
   <div class="col-sm-12 table-bar">

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
index 7b8e12a..12227c3 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html
@@ -27,7 +27,6 @@
       </link-to>
     </div>
   </div>
-  <hr>
   <table class="table table-striped table-hover">
     <thead>
       <tr>
@@ -80,7 +79,7 @@
   <div ng-if="isLoading" class="spinner-container">
     <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
   </div>
-  <div class="alert alert-info col-sm-12" ng-show="!users.length && !isLoading">
+  <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading">
     {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}}
   </div>
   <div class="col-sm-12 table-bar">

http://git-wip-us.apache.org/repos/asf/ambari/blob/430dcbf1/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
index d17747b..1b76dcf 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
@@ -54,7 +54,7 @@ describe('Utility Service', function () {
       httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
         items: []
       });
-      httpBackend.whenGET("views/main.html").respond(200, {});
+      httpBackend.whenGET("views/clusterInformation.html").respond(200, {});
     });
   });
 


[04/51] [abbrv] ambari git commit: AMBARI-22358 : VersionUtils incorrectly compares versions when it has double digits (mradhakrishnan)

Posted by nc...@apache.org.
AMBARI-22358 : VersionUtils incorrectly compares versions when it has double digits (mradhakrishnan)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: fe02abf62b1aaee7d48d5ea36eeadfe782294aa4
Parents: f844e5f
Author: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Authored: Thu Nov 2 14:51:11 2017 -0700
Committer: Madhuvanthi Radhakrishnan <mr...@hortonworks.com>
Committed: Thu Nov 2 14:51:11 2017 -0700

----------------------------------------------------------------------
 .../src/main/java/org/apache/ambari/server/utils/VersionUtils.java | 2 +-
 .../test/java/org/apache/ambari/server/utils/TestVersionUtils.java | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/fe02abf6/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
index 65966ed..08948e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
@@ -81,7 +81,7 @@ public class VersionUtils {
     }
 
     //String pattern = "^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\.([0-9]+).*";
-    String pattern = "([0-9]+).([0-9]+).([0-9]+).([0-9]+)?.*";
+    String pattern = "([0-9]+).([0-9]+).([0-9]+).?([0-9]+)?.*";
     String[] version1Parts = version1.replaceAll(pattern, "$1.$2.$3.$4").split("\\.");
     String[] version2Parts = version2.replaceAll(pattern, "$1.$2.$3.$4").split("\\.");
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/fe02abf6/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 9d20a01..6ad4e26 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -118,6 +118,7 @@ public class TestVersionUtils {
     //Assert.assertEquals(-1, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.4_MYAMBARI_000000"));
     Assert.assertEquals(1, VersionUtils.compareVersions("1.2.4_MYAMBARI_000000", "1.2.3_MYAMBARI_000000"));
     Assert.assertEquals(0, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.3_MYAMBARI_000000"));
+    Assert.assertEquals(0, VersionUtils.compareVersions("2.99.99.0", "2.99.99"));
 
     Assert.assertEquals(-1, VersionUtils.compareVersions("1.2.3_MYAMBARI_000000", "1.2.4_MYAMBARI_000000", 3));
     Assert.assertEquals(1, VersionUtils.compareVersions("1.2.4_MYAMBARI_000000", "1.2.3_MYAMBARI_000000", 3));


[28/51] [abbrv] ambari git commit: AMBARI-22361. Fix bug in base_alert when matching hostnames (stephanesan via dlysnichenko)

Posted by nc...@apache.org.
AMBARI-22361. Fix bug in base_alert when matching hostnames (stephanesan via dlysnichenko)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 0f67d1c690f019ef5289e9bbb4aa93abb607b40b
Parents: 30a43c9
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Wed Nov 8 13:28:03 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Wed Nov 8 13:28:03 2017 +0200

----------------------------------------------------------------------
 ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0f67d1c6/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 05f8023..5c0305e 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -463,7 +463,7 @@ class BaseAlert(object):
       # get the host for dfs.namenode.http-address.c1ha.nn1 and see if it's
       # this host
       value = self._get_configuration_value(key)
-      if value is not None and (self.host_name in value or self.public_host_name in value):
+      if value is not None and (self.host_name.lower() in value.lower() or self.public_host_name.lower() in value.lower()):
         return AlertUri(uri=value, is_ssl_enabled=is_ssl_enabled)
 
     return None


[02/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC integration (rlevas)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
index 0997f65..bbcd6e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
@@ -18,21 +18,17 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
-import java.text.NumberFormat;
-import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Queue;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Set;
 
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.utils.ShellCommandUtil;
-import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,37 +41,24 @@ import com.google.inject.Inject;
  * It is assumed that a MIT Kerberos client is installed and that the kdamin shell command is
  * available
  */
-public class MITKerberosOperationHandler extends KerberosOperationHandler {
+public class MITKerberosOperationHandler extends KDCKerberosOperationHandler {
+
+  private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
 
   @Inject
   private Configuration configuration;
 
   /**
-   * A regular expression pattern to use to parse the key number from the text captured from the
-   * get_principal kadmin command
-   */
-  private final static Pattern PATTERN_GET_KEY_NUMBER = Pattern.compile("^.*?Key: vno (\\d+).*$", Pattern.DOTALL);
-
-  private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
-
-  /**
    * A String containing user-specified attributes used when creating principals
    */
   private String createAttributes = null;
 
-  private String adminServerHost = null;
-
   /**
    * A String containing the resolved path to the kdamin executable
    */
   private String executableKadmin = null;
 
   /**
-   * A String containing the resolved path to the kdamin.local executable
-   */
-  private String executableKadminLocal = null;
-
-  /**
    * Prepares and creates resources to be used by this KerberosOperationHandler
    * <p/>
    * It is expected that this KerberosOperationHandler will not be used before this call.
@@ -92,39 +75,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public void open(PrincipalKeyCredential administratorCredentials, String realm,
-                   Map<String, String> kerberosConfiguration)
+  public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
       throws KerberosOperationException {
 
-    setAdministratorCredential(administratorCredentials);
-    setDefaultRealm(realm);
-
     if (kerberosConfiguration != null) {
-      setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
-      setAdminServerHost(kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST));
-      setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
-      setCreateAttributes(kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES));
-    } else {
-      setKeyEncryptionTypes(null);
-      setAdminServerHost(null);
-      setExecutableSearchPaths((String) null);
-      setCreateAttributes(null);
+      createAttributes = kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES);
     }
 
     // Pre-determine the paths to relevant Kerberos executables
     executableKadmin = getExecutable("kadmin");
-    executableKadminLocal = getExecutable("kadmin.local");
 
-    setOpen(true);
+    super.open(administratorCredentials, realm, kerberosConfiguration);
   }
 
   @Override
   public void close() throws KerberosOperationException {
-    // There is nothing to do here.
-    setOpen(false);
-
+    createAttributes = null;
     executableKadmin = null;
-    executableKadminLocal = null;
+
+    super.close();
   }
 
   /**
@@ -134,6 +103,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * the result from STDOUT to determine if the presence of the specified principal.
    *
    * @param principal a String containing the principal to test
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal exists; false otherwise
    * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
    * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -141,26 +111,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public boolean principalExists(String principal)
+  public boolean principalExists(String principal, boolean service)
       throws KerberosOperationException {
 
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if (principal == null) {
-      return false;
-    } else {
+    if (!StringUtils.isEmpty(principal)) {
       // Create the KAdmin query to execute:
-      ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
+      ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal));
 
       // If there is data from STDOUT, see if the following string exists:
       //    Principal: <principal>
       String stdOut = result.getStdout();
       return (stdOut != null) && stdOut.contains(String.format("Principal: %s", principal));
     }
-  }
 
+    return false;
+  }
 
   /**
    * Creates a new principal in a previously configured MIT KDC
@@ -188,72 +157,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
 
     if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to create new principal - no principal specified");
-    } else if (StringUtils.isEmpty(password)) {
-      throw new KerberosOperationException("Failed to create new principal - no password specified");
-    } else {
-      String createAttributes = getCreateAttributes();
-      // Create the kdamin query:  add_principal <-randkey|-pw <password>> [<options>] <principal>
-      ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal %s %s",
-          (createAttributes == null) ? "" : createAttributes, principal), password);
-
-      // If there is data from STDOUT, see if the following string exists:
-      //    Principal "<principal>" created
-      String stdOut = result.getStdout();
-      String stdErr = result.getStderr();
-      if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
-        return getKeyNumber(principal);
-      } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
-        throw new KerberosPrincipalAlreadyExistsException(principal);
-      } else {
-        LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
-            (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
-        throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
-            principal, stdOut, result.getStderr()));
-      }
-    }
-  }
-
-  /**
-   * Updates the password for an existing principal in a previously configured MIT KDC
-   * <p/>
-   * This implementation creates a query to send to the kadmin shell command and then interrogates
-   * the exit code to determine if the operation executed successfully.
-   *
-   * @param principal a String containing the principal to update
-   * @param password  a String containing the password to set
-   * @return an Integer declaring the new key number
-   * @throws KerberosKDCConnectionException         if a connection to the KDC cannot be made
-   * @throws KerberosAdminAuthenticationException   if the administrator credentials fail to authenticate
-   * @throws KerberosRealmException                 if the realm does not map to a KDC
-   * @throws KerberosPrincipalDoesNotExistException if the principal does not exist
-   * @throws KerberosOperationException             if an unexpected error occurred
-   */
-  @Override
-  public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
-    if (!isOpen()) {
-      throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if (StringUtils.isEmpty(principal)) {
-      throw new KerberosOperationException("Failed to set password - no principal specified");
-    } else if (StringUtils.isEmpty(password)) {
-      throw new KerberosOperationException("Failed to set password - no password specified");
+    // Create the kdamin query:  add_principal <-randkey|-pw <password>> [<options>] <principal>
+    ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal -randkey %s %s",
+        (createAttributes == null) ? "" : createAttributes, principal));
+
+    // If there is data from STDOUT, see if the following string exists:
+    //    Principal "<principal>" created
+    String stdOut = result.getStdout();
+    String stdErr = result.getStderr();
+    if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
+      return 0;
+    } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
+      throw new KerberosPrincipalAlreadyExistsException(principal);
     } else {
-      // Create the kdamin query:  change_password <-randkey|-pw <password>> <principal>
-      ShellCommandUtil.Result result = invokeKAdmin(String.format("change_password %s", principal), password);
-
-      String stdOut = result.getStdout();
-      String stdErr = result.getStderr();
-      if ((stdOut != null) && stdOut.contains(String.format("Password for \"%s\" changed", principal))) {
-        return getKeyNumber(principal);
-      } else if ((stdErr != null) && stdErr.contains("Principal does not exist")) {
-        throw new KerberosPrincipalDoesNotExistException(principal);
-      } else {
-        LOG.error("Failed to execute kadmin query: change_password -pw \"********\" {} \nSTDOUT: {}\nSTDERR: {}",
-            principal, stdOut, result.getStderr());
-        throw new KerberosOperationException(String.format("Failed to update password for %s\nSTDOUT: %s\nSTDERR: %s",
-            principal, stdOut, result.getStderr()));
-      }
+      LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
+          (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
+      throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
+          principal, stdOut, result.getStderr()));
     }
   }
 
@@ -263,6 +185,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to remove
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal was successfully removed; otherwise false
    * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
    * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -270,181 +193,63 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public boolean removePrincipal(String principal) throws KerberosOperationException {
+  public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
     if (StringUtils.isEmpty(principal)) {
-      throw new KerberosOperationException("Failed to remove new principal - no principal specified");
-    } else {
-      ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal), null);
-
-      // If there is data from STDOUT, see if the following string exists:
-      //    Principal "<principal>" created
-      String stdOut = result.getStdout();
-      return (stdOut != null) && !stdOut.contains("Principal does not exist");
+      throw new KerberosOperationException("Failed to remove principal - no principal specified");
     }
-  }
 
-  /**
-   * Sets the KDC administrator server host address
-   *
-   * @param adminServerHost the ip address or FQDN of the KDC administrator server
-   */
-  public void setAdminServerHost(String adminServerHost) {
-    this.adminServerHost = adminServerHost;
-  }
+    ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal));
 
-  /**
-   * Gets the IP address or FQDN of the KDC administrator server
-   *
-   * @return the IP address or FQDN of the KDC administrator server
-   */
-  public String getAdminServerHost() {
-    return this.adminServerHost;
-  }
-
-  /**
-   * Sets the (additional) principal creation attributes
-   *
-   * @param createAttributes the additional principal creations attributes
-   */
-  public void setCreateAttributes(String createAttributes) {
-    this.createAttributes = createAttributes;
-  }
-
-  /**
-   * Gets the (additional) principal creation attributes
-   *
-   * @return the additional principal creations attributes or null
-   */
-  public String getCreateAttributes() {
-    return createAttributes;
-  }
-
-  /**
-   * Retrieves the current key number assigned to the identity identified by the specified principal
-   *
-   * @param principal a String declaring the principal to look up
-   * @return an Integer declaring the current key number
-   * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
-   * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
-   * @throws KerberosRealmException               if the realm does not map to a KDC
-   * @throws KerberosOperationException           if an unexpected error occurred
-   */
-  private Integer getKeyNumber(String principal) throws KerberosOperationException {
-    if (!isOpen()) {
-      throw new KerberosOperationException("This operation handler has not been opened");
-    }
-
-    if (StringUtils.isEmpty(principal)) {
-      throw new KerberosOperationException("Failed to get key number for principal  - no principal specified");
-    } else {
-      // Create the kdamin query:  get_principal <principal>
-      ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
-
-      String stdOut = result.getStdout();
-      if (stdOut == null) {
-        String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-            principal, result.getExitCode(), result.getStderr());
-        LOG.warn(message);
-        throw new KerberosOperationException(message);
-      }
-
-      Matcher matcher = PATTERN_GET_KEY_NUMBER.matcher(stdOut);
-      if (matcher.matches()) {
-        NumberFormat numberFormat = NumberFormat.getIntegerInstance();
-        String keyNumber = matcher.group(1);
-
-        numberFormat.setGroupingUsed(false);
-        try {
-          Number number = numberFormat.parse(keyNumber);
-          return (number == null) ? 0 : number.intValue();
-        } catch (ParseException e) {
-          String message = String.format("Failed to get key number for %s - invalid key number value (%s):\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-              principal, keyNumber, result.getExitCode(), result.getStderr());
-          LOG.warn(message);
-          throw new KerberosOperationException(message);
-        }
-      } else {
-        String message = String.format("Failed to get key number for %s - unexpected STDOUT data:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-            principal, result.getExitCode(), result.getStderr());
-        LOG.warn(message);
-        throw new KerberosOperationException(message);
-      }
-    }
+    // If there is data from STDOUT, see if the following string exists:
+    //    Principal "<principal>" created
+    String stdOut = result.getStdout();
+    return (stdOut != null) && !stdOut.contains("Principal does not exist");
   }
 
   /**
    * Invokes the kadmin shell command to issue queries
    *
-   * @param query        a String containing the query to send to the kdamin command
-   * @param userPassword a String containing the user's password to set or update if necessary,
-   *                     null if not needed
+   * @param query a String containing the query to send to the kdamin command
    * @return a ShellCommandUtil.Result containing the result of the operation
    * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
    * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
    * @throws KerberosRealmException               if the realm does not map to a KDC
    * @throws KerberosOperationException           if an unexpected error occurred
    */
-  protected ShellCommandUtil.Result invokeKAdmin(String query, String userPassword)
+  protected ShellCommandUtil.Result invokeKAdmin(String query)
       throws KerberosOperationException {
     if (StringUtils.isEmpty(query)) {
       throw new KerberosOperationException("Missing kadmin query");
     }
 
-    ShellCommandUtil.Result result = null;
-    PrincipalKeyCredential administratorCredential = getAdministratorCredential();
-    String defaultRealm = getDefaultRealm();
+    if (StringUtils.isEmpty(executableKadmin)) {
+      throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
+    }
 
     List<String> command = new ArrayList<>();
+    command.add(executableKadmin);
 
-    String adminPrincipal = (administratorCredential == null)
-        ? null
-        : administratorCredential.getPrincipal();
-
-    ShellCommandUtil.InteractiveHandler interactiveHandler = null;
-
-    if (StringUtils.isEmpty(adminPrincipal)) {
-      // Set the kdamin interface to be kadmin.local
-      if (StringUtils.isEmpty(executableKadminLocal)) {
-        throw new KerberosOperationException("No path for kadmin.local is available - this KerberosOperationHandler may not have been opened.");
-      }
-
-      command.add(executableKadminLocal);
-
-      if (userPassword != null) {
-        interactiveHandler = new InteractivePasswordHandler(null, userPassword);
-      }
-    } else {
-      if (StringUtils.isEmpty(executableKadmin)) {
-        throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
-      }
-      char[] adminPassword = administratorCredential.getKey();
-
-      // Set the kdamin interface to be kadmin
-      command.add(executableKadmin);
-
-      // Add explicit KDC admin host, if available
-      if (!StringUtils.isEmpty(getAdminServerHost())) {
-        command.add("-s");
-        command.add(getAdminServerHost());
-      }
-
-      // Add the administrative principal
-      command.add("-p");
-      command.add(adminPrincipal);
+    // Add the credential cache, if available
+    String credentialCacheFilePath = getCredentialCacheFilePath();
+    if (!StringUtils.isEmpty(credentialCacheFilePath)) {
+      command.add("-c");
+      command.add(credentialCacheFilePath);
+    }
 
-      if (!ArrayUtils.isEmpty(adminPassword)) {
-        interactiveHandler = new InteractivePasswordHandler(String.valueOf(adminPassword), userPassword);
-      } else if (userPassword != null) {
-        interactiveHandler = new InteractivePasswordHandler(null, userPassword);
-      }
+    // Add explicit KDC admin host, if available
+    String adminSeverHost = getAdminServerHost();
+    if (!StringUtils.isEmpty(adminSeverHost)) {
+      command.add("-s");
+      command.add(adminSeverHost);
     }
 
+    // Add default realm clause, if available
+    String defaultRealm = getDefaultRealm();
     if (!StringUtils.isEmpty(defaultRealm)) {
-      // Add default realm clause
       command.add("-r");
       command.add(defaultRealm);
     }
@@ -457,12 +262,13 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       LOG.debug("Executing: {}", command);
     }
 
+    ShellCommandUtil.Result result = null;
     int retryCount = configuration.getKerberosOperationRetries();
     int tries = 0;
 
     while (tries <= retryCount) {
       try {
-        result = executeCommand(command.toArray(new String[command.size()]), null, interactiveHandler);
+        result = executeCommand(command.toArray(new String[command.size()]));
       } catch (KerberosOperationException exception) {
         if (tries == retryCount) {
           throw exception;
@@ -486,13 +292,16 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
     }
 
 
-    if (!result.isSuccessful()) {
+    if ((result == null) || !result.isSuccessful()) {
+      int exitCode = (result == null) ? -999 : result.getExitCode();
+      String stdOut = (result == null) ? "" : result.getStdout();
+      String stdErr = (result == null) ? "" : result.getStderr();
+
       String message = String.format("Failed to execute kadmin:\n\tCommand: %s\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
-          command, result.getExitCode(), result.getStdout(), result.getStderr());
+          command, exitCode, stdOut, stdErr);
       LOG.warn(message);
 
       // Test STDERR to see of any "expected" error conditions were encountered...
-      String stdErr = result.getStderr();
       // Did admin credentials fail?
       if (stdErr.contains("Client not found in Kerberos database")) {
         throw new KerberosAdminAuthenticationException(stdErr);
@@ -513,57 +322,56 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       } else {
         throw new KerberosOperationException(String.format("Unexpected error condition executing the kadmin command. STDERR: %s", stdErr));
       }
+    } else {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Executed the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+            StringUtils.join(command, " "), result.getStdout(), result.getStderr());
+      }
     }
 
     return result;
   }
 
-  /**
-   * InteractivePasswordHandler is a {@link org.apache.ambari.server.utils.ShellCommandUtil.InteractiveHandler}
-   * implementation that answers queries from kadmin or kdamin.local command for the admin and/or user
-   * passwords.
-   */
-  protected static class InteractivePasswordHandler implements ShellCommandUtil.InteractiveHandler {
-    /**
-     * The queue of responses to return
-     */
-    private LinkedList<String> responses;
-    private Queue<String> currentResponses;
-
-    /**
-     * Constructor.
-     *
-     * @param adminPassword the KDC administrator's password (optional)
-     * @param userPassword  the user's password (optional)
-     */
-    public InteractivePasswordHandler(String adminPassword, String userPassword) {
-      responses = new LinkedList<>();
-
-      if (adminPassword != null) {
-        responses.offer(adminPassword);
-      }
+  @Override
+  protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) {
+    // kinit -c <path> -S kadmin/`hostname -f` <principal>
+    return new String[]{
+        executableKinit,
+        "-c",
+        credentialsCache,
+        "-S",
+        String.format("kadmin/%s", getAdminServerHost()),
+        credentials.getPrincipal()
+    };
+  }
 
-      if (userPassword != null) {
-        responses.offer(userPassword);
-        responses.offer(userPassword);  // Add a 2nd time for the password "confirmation" request
+  @Override
+  protected void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException {
+    String encryptionTypeSpec = null;
+    if (!CollectionUtils.isEmpty(keyEncryptionTypes)) {
+      StringBuilder encryptionTypeSpecBuilder = new StringBuilder();
+      for (EncryptionType encryptionType : keyEncryptionTypes) {
+        if (encryptionTypeSpecBuilder.length() > 0) {
+          encryptionTypeSpecBuilder.append(',');
+        }
+        encryptionTypeSpecBuilder.append(encryptionType.getName());
+        encryptionTypeSpecBuilder.append(":normal");
       }
 
-      currentResponses = new LinkedList<>(responses);
+      encryptionTypeSpec = encryptionTypeSpecBuilder.toString();
     }
 
-    @Override
-    public boolean done() {
-      return currentResponses.size() == 0;
-    }
+    String query = (StringUtils.isEmpty(encryptionTypeSpec))
+        ? String.format("xst -k \"%s\" %s", keytabFileDestinationPath, principal)
+        : String.format("xst -k \"%s\" -e %s %s", keytabFileDestinationPath, encryptionTypeSpec, principal);
 
-    @Override
-    public String getResponse(String query) {
-      return currentResponses.poll();
-    }
+    ShellCommandUtil.Result result = invokeKAdmin(query);
 
-    @Override
-    public void start() {
-      currentResponses = new LinkedList<>(responses);
+    if (!result.isSuccessful()) {
+      String message = String.format("Failed to export the keytab file for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+          principal, result.getExitCode(), result.getStdout(), result.getStderr());
+      LOG.warn(message);
+      throw new KerberosOperationException(message);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index bfe2a13..d3e924e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -45,6 +45,7 @@ import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.Config;
 import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -149,6 +150,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
     showHcatDeletedUserMessage();
     setStatusOfStagesAndRequests();
     updateLogSearchConfigs();
+    updateKerberosConfigurations();
   }
 
   protected void showHcatDeletedUserMessage() {
@@ -265,7 +267,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
                 "logsearch-common-properties", Collections.emptyMap(), "ambari-upgrade",
                 String.format("Updated logsearch-common-properties during Ambari Upgrade from %s to %s",
                     getSourceVersion(), getTargetVersion()));
-            
+
             String defaultLogLevels = logSearchProperties.getProperties().get("logsearch.logfeeder.include.default.level");
 
             Set<String> removeProperties = Sets.newHashSet("logsearch.logfeeder.include.default.level");
@@ -324,7 +326,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
               updateConfigurationPropertiesForCluster(cluster, "logsearch-audit_logs-solrconfig", Collections.singletonMap("content", content), true, true);
             }
           }
-          
+
           Config logFeederOutputConfig = cluster.getDesiredConfigByType("logfeeder-output-config");
           if (logFeederOutputConfig != null) {
             String content = logFeederOutputConfig.getProperties().get("content");
@@ -346,4 +348,28 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
       }
     }
   }
+
+  protected void updateKerberosConfigurations() throws AmbariException {
+    AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+    Clusters clusters = ambariManagementController.getClusters();
+    if (clusters != null) {
+      Map<String, Cluster> clusterMap = clusters.getClusters();
+
+      if (!MapUtils.isEmpty(clusterMap)) {
+        for (Cluster cluster : clusterMap.values()) {
+          Config config = cluster.getDesiredConfigByType("kerberos-env");
+
+          if (config != null) {
+            Map<String, String> properties = config.getProperties();
+            if (properties.containsKey("group")) {
+              // Covert kerberos-env/group to kerberos-env/ipa_user_group
+              updateConfigurationPropertiesForCluster(cluster, "kerberos-env",
+                  Collections.singletonMap("ipa_user_group", properties.get("group")), Collections.singleton("group"),
+                  true, false);
+            }
+          }
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
-    <name>group</name>
-    <display-name>IPA Group</display-name>
+    <name>ipa_user_group</name>
+    <display-name>IPA User Group</display-name>
     <description>
       The group in IPA user principals should be member of
     </description>
@@ -362,38 +362,6 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
-    <name>set_password_expiry</name>
-    <display-name>Set IPA principal password expiry</display-name>
-    <description>
-      Indicates whether Ambari should set the password expiry for the principals it creates. By default
-      IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
-      attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
-      policy is in place for the IPA Group principals are added to.
-    </description>
-    <value>false</value>
-    <value-attributes>
-      <type>boolean</type>
-      <overridable>false</overridable>
-      <visible>false</visible>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
-  <property>
-    <name>password_chat_timeout</name>
-    <display-name>Set IPA kinit password chat timeout</display-name>
-    <description>
-      Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
-      because it can take some time due to lookups before a response is there.
-    </description>
-    <value>5</value>
-    <value-attributes>
-      <visible>false</visible>
-      <type>int</type>
-      <overridable>false</overridable>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
-  <property>
     <name>preconfigure_services</name>
     <display-name>Pre-configure services</display-name>
     <description>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
-    <name>group</name>
-    <display-name>IPA Group</display-name>
+    <name>ipa_user_group</name>
+    <display-name>IPA User Group</display-name>
     <description>
       The group in IPA user principals should be member of
     </description>
@@ -362,38 +362,6 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
-    <name>set_password_expiry</name>
-    <display-name>Set IPA principal password expiry</display-name>
-    <description>
-      Indicates whether Ambari should set the password expiry for the principals it creates. By default
-      IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
-      attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
-      policy is in place for the IPA Group principals are added to.
-    </description>
-    <value>false</value>
-    <value-attributes>
-      <type>boolean</type>
-      <overridable>false</overridable>
-      <visible>false</visible>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
-  <property>
-    <name>password_chat_timeout</name>
-    <display-name>Set IPA kinit password chat timeout</display-name>
-    <description>
-      Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
-      because it can take some time due to lookups before a response is there.
-    </description>
-    <value>5</value>
-    <value-attributes>
-      <visible>false</visible>
-      <type>int</type>
-      <overridable>false</overridable>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
-  <property>
     <name>preconfigure_services</name>
     <display-name>Pre-configure services</display-name>
     <description>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
index 66e81db..a66a7a6 100644
--- a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
@@ -348,8 +348,8 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
-    <name>group</name>
-    <display-name>IPA Group</display-name>
+    <name>ipa_user_group</name>
+    <display-name>IPA User Group</display-name>
     <description>
       The group in IPA user principals should be member of
     </description>
@@ -360,36 +360,4 @@
     </value-attributes>
     <on-ambari-upgrade add="true"/>
   </property>
-  <property>
-    <name>set_password_expiry</name>
-    <display-name>Set IPA principal password expiry</display-name>
-    <description>
-      Indicates whether Ambari should set the password expiry for the principals it creates. By default
-      IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
-      attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
-      policy is in place for the IPA Group principals are added to.
-    </description>
-    <value>false</value>
-    <value-attributes>
-      <type>boolean</type>
-      <overridable>false</overridable>
-      <visible>false</visible>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
-  <property>
-    <name>password_chat_timeout</name>
-    <display-name>Set IPA kinit password chat timeout</display-name>
-    <description>
-      Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
-      because it can take some time due to lookups before a response is there.
-    </description>
-    <value>5</value>
-    <value-attributes>
-      <visible>false</visible>
-      <type>int</type>
-      <overridable>false</overridable>
-    </value-attributes>
-    <on-ambari-upgrade add="true"/>
-  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/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 a3074ae..ee87d24 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
@@ -188,7 +188,7 @@ public class KerberosHelperTest extends EasyMockSupport {
           }
 
           @Override
-          public boolean principalExists(String principal) throws KerberosOperationException {
+          public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
             return "principal".equals(principal);
           }
 
@@ -198,12 +198,12 @@ public class KerberosHelperTest extends EasyMockSupport {
           }
 
           @Override
-          public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+          public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
             return null;
           }
 
           @Override
-          public boolean removePrincipal(String principal) throws KerberosOperationException {
+          public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
             return false;
           }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
index 483cc0a..8b3c19a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
@@ -19,11 +19,15 @@
 package org.apache.ambari.server.serveraction.kerberos;
 
 import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isNull;
 import static org.easymock.EasyMock.newCapture;
 import static org.easymock.EasyMock.replay;
 
+import java.lang.reflect.Method;
 import java.nio.charset.Charset;
 import java.util.HashMap;
 import java.util.List;
@@ -50,6 +54,8 @@ import org.apache.ambari.server.state.stack.OsFamily;
 import org.easymock.Capture;
 import org.easymock.CaptureType;
 import org.easymock.IAnswer;
+import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -65,6 +71,36 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
   private static final String DEFAULT_LDAP_URL = "ldaps://10.0.100.4";
   private static final String DEFAULT_PRINCIPAL_CONTAINER_DN = "ou=HDP,DC=HDP01,DC=LOCAL";
   private static final String DEFAULT_REALM = "HDP01.LOCAL";
+  private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
+    {
+      put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+      put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
+    }
+  };
+
+  private static Method methodCreateInitialLdapContext;
+
+  private Injector injector;
+  private LdapContext ldapContext;
+
+  @BeforeClass
+  public static void beforeMITKerberosOperationHandlerTest() throws Exception {
+    methodCreateInitialLdapContext = ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class);
+  }
+
+  @Before
+  public void setup() {
+    injector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+        bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
+        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+      }
+    });
+
+    ldapContext = createMock(LdapContext.class);
+  }
 
   @Test(expected = KerberosKDCConnectionException.class)
   public void testOpenExceptionLdapUrlNotProvided() throws Exception {
@@ -95,13 +131,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
   @Test(expected = KerberosAdminAuthenticationException.class)
   public void testOpenExceptionAdminCredentialsNotProvided() throws Exception {
     KerberosOperationHandler handler = new ADKerberosOperationHandler();
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
-    handler.open(null, DEFAULT_REALM, kerberosEnvMap);
+
+    handler.open(null, DEFAULT_REALM, getKerberosEnv());
     handler.close();
   }
 
@@ -124,13 +155,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     Injector injector = getInjector();
 
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, "wrong");
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
-
     ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
         .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
         .createNiceMock();
@@ -145,7 +169,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     replayAll();
 
-    handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+    handler.open(kc, DEFAULT_REALM, getKerberosEnv());
     handler.testAdministratorCredentials();
     handler.close();
   }
@@ -155,12 +179,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     Injector injector = getInjector();
 
     PrincipalKeyCredential kc = new PrincipalKeyCredential("wrong", DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
 
     ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
         .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
@@ -176,7 +194,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     replayAll();
 
-    handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+    handler.open(kc, DEFAULT_REALM, getKerberosEnv());
     handler.testAdministratorCredentials();
     handler.close();
   }
@@ -184,17 +202,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
   @Test(expected = KerberosKDCConnectionException.class)
   public void testTestAdministratorCredentialsKDCConnectionException() throws Exception {
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, "invalid");
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
-
-    ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
-        .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
-        .createNiceMock();
 
+    ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
     expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class))).andAnswer(new IAnswer<LdapContext>() {
       @Override
       public LdapContext answer() throws Throwable {
@@ -204,7 +213,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     replayAll();
 
-    handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+    handler.open(kc, DEFAULT_REALM, getKerberosEnv());
     handler.testAdministratorCredentials();
     handler.close();
   }
@@ -212,21 +221,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
   @Test
   public void testTestAdministratorCredentialsSuccess() throws Exception {
-    Injector injector = getInjector();
-
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
-
-    ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
-        .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
-        .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createSearchControls"))
-        .createNiceMock();
-    injector.injectMembers(handler);
+    ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
 
     expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class)))
         .andAnswer(new IAnswer<LdapContext>() {
@@ -245,23 +241,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
                   }
                 })
                 .once();
-            replay(ldapContext);
             return ldapContext;
           }
         })
         .once();
-    expect(handler.createSearchControls()).andAnswer(new IAnswer<SearchControls>() {
-      @Override
-      public SearchControls answer() throws Throwable {
-        SearchControls searchControls = createNiceMock(SearchControls.class);
-        replay(searchControls);
-        return searchControls;
-      }
-    }).once();
 
     replayAll();
 
-    handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+    handler.open(kc, DEFAULT_REALM, getKerberosEnv());
     handler.testAdministratorCredentials();
     handler.close();
   }
@@ -271,12 +258,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     Injector injector = getInjector();
 
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-      }
-    };
 
     Capture<Name> capturedName = newCapture(CaptureType.ALL);
     Capture<Attributes> capturedAttributes = newCapture(CaptureType.ALL);
@@ -315,7 +296,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     replayAll();
 
-    handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+    handler.open(kc, DEFAULT_REALM, getKerberosEnv());
     handler.createPrincipal("nn/c6501.ambari.apache.org", "secret", true);
     handler.createPrincipal("hdfs@" + DEFAULT_REALM, "secret", false);
     handler.close();
@@ -384,31 +365,26 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     Injector injector = getInjector();
 
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
-      {
-        put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-        put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
-            "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
-            "{" +
-            "  \"objectClass\": [" +
-            "    \"top\"," +
-            "    \"person\"," +
-            "    \"organizationalPerson\"," +
-            "    \"user\"" +
-            "  ]," +
-            "  \"cn\": \"$user\"," +
-            "  \"sAMAccountName\": \"$user.substring(0,20)\"," +
-            "  #if( $is_service )" +
-            "  \"servicePrincipalName\": \"$principal_name\"," +
-            "  #end" +
-            "  \"userPrincipalName\": \"$normalized_principal\"," +
-            "  \"unicodePwd\": \"$password\"," +
-            "  \"accountExpires\": \"0\"," +
-            "  \"userAccountControl\": \"66048\"" +
-            "}");
-      }
-    };
+    Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
+    kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
+        "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
+        "{" +
+        "  \"objectClass\": [" +
+        "    \"top\"," +
+        "    \"person\"," +
+        "    \"organizationalPerson\"," +
+        "    \"user\"" +
+        "  ]," +
+        "  \"cn\": \"$user\"," +
+        "  \"sAMAccountName\": \"$user.substring(0,20)\"," +
+        "  #if( $is_service )" +
+        "  \"servicePrincipalName\": \"$principal_name\"," +
+        "  #end" +
+        "  \"userPrincipalName\": \"$normalized_principal\"," +
+        "  \"unicodePwd\": \"$password\"," +
+        "  \"accountExpires\": \"0\"," +
+        "  \"userAccountControl\": \"66048\"" +
+        "}");
 
     Capture<Name> capturedName = newCapture();
     Capture<Attributes> capturedAttributes = newCapture();
@@ -491,9 +467,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     Injector injector = getInjector();
 
     PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
-    Map<String, String> kerberosEnvMap = new HashMap<>();
-    kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-    kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+    Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
     kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
         "{" +
         "\"principal_digest\": \"$principal_digest\"," +
@@ -596,7 +570,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     System.out.println("Test Admin Credentials: " + handler.testAdministratorCredentials());
     // does the principal already exist?
-    System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org"));
+    System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org", true));
 
     handler.close();
 
@@ -605,15 +579,15 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     String evaluatedPrincipal;
 
     evaluatedPrincipal = "nn/c6501.ambari.apache.org@" + DEFAULT_REALM;
-    if (handler.principalExists(evaluatedPrincipal)) {
-      handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+    if (handler.principalExists(evaluatedPrincipal, true)) {
+      handler.setPrincipalPassword(evaluatedPrincipal, "some password", true);
     } else {
       handler.createPrincipal(evaluatedPrincipal, "some password", true);
     }
 
     evaluatedPrincipal = "hdfs@" + DEFAULT_REALM;
-    if (handler.principalExists(evaluatedPrincipal)) {
-      handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+    if (handler.principalExists(evaluatedPrincipal, false)) {
+      handler.setPrincipalPassword(evaluatedPrincipal, "some password", false);
     } else {
       handler.createPrincipal(evaluatedPrincipal, "some password", true);
     }
@@ -644,14 +618,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
     handler.open(credentials, realm, kerberosEnvMap);
 
     // remove the principal
-    handler.removePrincipal("abcdefg");
-    handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM);
+    handler.removePrincipal("abcdefg", false);
+    handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, true);
 
     handler.createPrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
     handler.createPrincipal("abcdefg@" + DEFAULT_REALM, "some password", false);
 
     //update the password
-    handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password");
+    handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
 
     handler.close();
   }
@@ -687,11 +661,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
 
     replayAll();
 
-    Map<String, String> kerberosConfiguration = new HashMap<>();
-    kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
-    kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-
-    handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", kerberosConfiguration);
+    handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", getKerberosEnv());
 
     Properties properties = capturedProperties.getValue();
     Assert.assertNotNull(properties);
@@ -705,13 +675,78 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
   }
 
   private Injector getInjector() {
-    return Guice.createInjector(new AbstractModule() {
-      @Override
-      protected void configure() {
-        bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
-        bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
-        bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
-      }
-    });
+    return injector;
+  }
+
+  @Override
+  protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+    return createMockedHandler(methodCreateInitialLdapContext);
+  }
+
+
+  private ADKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+    ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
+        .addMockedMethods(mockedMethods)
+        .createMock();
+    injector.injectMembers(handler);
+    return handler;
+  }
+
+
+  @Override
+  protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+
+    ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+
+    expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andReturn(ldapContext).anyTimes();
+  }
+
+  @Override
+  protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+    ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+    expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andThrow(new AuthenticationException("Bogus error!")).anyTimes();
+  }
+
+  @Override
+  protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    setupPrincipalExists(handler, service);
+  }
+
+  @Override
+  protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+    NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+    results.close();
+    expectLastCall().once();
+    expect(results.hasMore()).andReturn(false).anyTimes();
+
+    expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+        .andReturn(results)
+        .anyTimes();
+    ldapContext.close();
+    expectLastCall().once();
+  }
+
+  @Override
+  protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    SearchResult result = createMock(SearchResult.class);
+    expect(result.getNameInNamespace()).andReturn("user/service dn").anyTimes();
+
+    NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+    results.close();
+    expectLastCall().anyTimes();
+    expect(results.hasMore()).andReturn(true).once();
+    expect(results.next()).andReturn(result).once();
+    expect(results.hasMore()).andReturn(false).anyTimes();
+
+    expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+        .andReturn(results)
+        .anyTimes();
+    ldapContext.close();
+    expectLastCall().once();
+  }
+
+  @Override
+  protected Map<String, String> getKerberosEnv() {
+    return KERBEROS_ENV_MAP;
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
index f2a09ba..558ca79 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
@@ -18,36 +18,26 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.utils.ShellCommandUtil;
 import org.easymock.EasyMock;
 import org.junit.BeforeClass;
-import org.junit.Test;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
-import junit.framework.Assert;
-
-public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
-  private static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
-  private static final String DEFAULT_ADMIN_PASSWORD = "Hadoop12345";
-
-  private static final String DEFAULT_REALM = "IPA01.LOCAL";
-
-  private static Injector injector;
-
-  private static boolean hasIpa = false;
+public class IPAKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
 
   private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
     {
@@ -58,8 +48,10 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
     }
   };
 
+  private static Injector injector;
+
   @BeforeClass
-  public static void beforeClass() throws AmbariException {
+  public static void beforeIPAKerberosOperationHandlerTest() throws Exception {
     injector = Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
@@ -72,85 +64,74 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
         bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
       }
     });
-    if (System.getenv("HAS_IPA") != null) {
-      hasIpa = true;
-    }
   }
 
-  @Test
-  public void testSetPrincipalPasswordExceptions() throws Exception {
-    if (!hasIpa) {
-      return;
-    }
+  @Override
+  protected IPAKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+    IPAKerberosOperationHandler handler = createMockBuilder(IPAKerberosOperationHandler.class)
+        .addMockedMethods(mockedMethods)
+        .createMock();
+    injector.injectMembers(handler);
+    return handler;
+  }
 
-    IPAKerberosOperationHandler handler = injector.getInstance(IPAKerberosOperationHandler.class);
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
-    try {
-      handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null);
-      Assert.fail("KerberosOperationException not thrown for null password");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+  @Override
+  protected Map<String, String> getKerberosEnv() {
+    return KERBEROS_ENV_MAP;
+  }
 
-    try {
-      handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "");
-      Assert.fail("KerberosOperationException not thrown for empty password");
-      handler.createPrincipal("", "1234", false);
-      Assert.fail("AmbariException not thrown for empty principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
+  @Override
+  protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(1).anyTimes();
+    expect(result.isSuccessful()).andReturn(false).anyTimes();
+    if(service) {
+      expect(result.getStderr()).andReturn("ipa: ERROR: service with name \"service/host@EXAMPLE.COM\" already exists").anyTimes();
     }
-
-    try {
-      handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD);
-      Assert.fail("KerberosOperationException not thrown for null principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
+    else {
+      expect(result.getStderr()).andReturn("ipa: ERROR: user with name \"user\" already exists").anyTimes();
     }
+    expect(result.getStdout()).andReturn("").anyTimes();
 
-    try {
-      handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD);
-      Assert.fail("KerberosOperationException not thrown for empty principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-add" : "user-add"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
   }
 
-  @Test
-  public void testCreateServicePrincipal_Exceptions() throws Exception {
-    if (!hasIpa) {
-      return;
-    }
-
-    IPAKerberosOperationHandler handler = new IPAKerberosOperationHandler();
-    handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+  @Override
+  protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(2).anyTimes();
+    expect(result.isSuccessful()).andReturn(false).anyTimes();
+    expect(result.getStderr()).andReturn(String.format("ipa: ERROR: %s: user not found", (service) ? "service/host" : "user")).anyTimes();
+    expect(result.getStdout()).andReturn("").anyTimes();
 
-    try {
-      handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, null, false);
-      Assert.fail("KerberosOperationException not thrown for null password");
-    } catch (Throwable t) {
-      Assert.fail("KerberosOperationException thrown on null password with IPA");
-    }
 
-    try {
-      handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, "", false);
-    } catch (Throwable t) {
-      Assert.fail("KerberosOperationException thrown for empty password");
-    }
-
-    try {
-      handler.createPrincipal(null, DEFAULT_ADMIN_PASSWORD, false);
-      Assert.fail("KerberosOperationException not thrown for null principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
-
-    try {
-      handler.createPrincipal("", DEFAULT_ADMIN_PASSWORD, false);
-      Assert.fail("KerberosOperationException not thrown for empty principal");
-    } catch (Throwable t) {
-      Assert.assertEquals(KerberosOperationException.class, t.getClass());
-    }
+    expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
   }
 
+  @Override
+  protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.getExitCode()).andReturn(0).anyTimes();
+    expect(result.isSuccessful()).andReturn(true).anyTimes();
+    expect(result.getStderr()).andReturn("").anyTimes();
+    expect(result.getStdout()).andReturn(String.format("  User login: %s\n" +
+        "  Last name: User\n" +
+        "  Home directory: /home/user\n" +
+        "  Login shell: /bin/bash\n" +
+        "  Principal alias: user@EXAMPLE.COM\n" +
+        "  UID: 324200000\n" +
+        "  GID: 324200000\n" +
+        "  Account disabled: False\n" +
+        "  Password: True\n" +
+        "  Member of groups: users\n" +
+        "  Kerberos keys available: True", (service) ? "service/host" : "user")).anyTimes();
+
+    expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
new file mode 100644
index 0000000..271c787
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.serveraction.kerberos;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.lang.StringUtils;
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
+
+  static Method methodExecuteCommand;
+
+  @BeforeClass
+  public static void beforeKDCKerberosOperationHandlerTest() throws Exception {
+    methodExecuteCommand = KDCKerberosOperationHandler.class.getDeclaredMethod("executeCommand", String[].class, Map.class, ShellCommandUtil.InteractiveHandler.class);
+  }
+
+  @Test
+  public void testInteractivePasswordHandler() {
+    KDCKerberosOperationHandler.InteractivePasswordHandler handler = new KDCKerberosOperationHandler.InteractivePasswordHandler("admin_password", "user_password");
+
+    handler.start();
+    Assert.assertEquals("admin_password", handler.getResponse("password"));
+    Assert.assertFalse(handler.done());
+    Assert.assertEquals("user_password", handler.getResponse("password"));
+    Assert.assertFalse(handler.done());
+    Assert.assertEquals("user_password", handler.getResponse("password"));
+    Assert.assertTrue(handler.done());
+
+    // Test restarting
+    handler.start();
+    Assert.assertEquals("admin_password", handler.getResponse("password"));
+    Assert.assertFalse(handler.done());
+    Assert.assertEquals("user_password", handler.getResponse("password"));
+    Assert.assertFalse(handler.done());
+    Assert.assertEquals("user_password", handler.getResponse("password"));
+    Assert.assertTrue(handler.done());
+  }
+
+  @Override
+  protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+    return createMockedHandler(methodExecuteCommand);
+  }
+
+  @Override
+  protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.isSuccessful()).andReturn(true);
+
+    expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
+  }
+
+  @Override
+  protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+    ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+    expect(result.isSuccessful()).andReturn(false).once();
+    expect(result.getExitCode()).andReturn(-1).once();
+    expect(result.getStdout()).andReturn("STDOUT data").once();
+    expect(result.getStderr()).andReturn("STDERR data").once();
+
+    expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+        .andReturn(result)
+        .anyTimes();
+  }
+
+  protected abstract KDCKerberosOperationHandler createMockedHandler(Method... mockedMethods);
+
+  public static class ArrayContains implements IArgumentMatcher {
+
+    private String[] startItems;
+
+    ArrayContains(String startItem) {
+      this.startItems = new String[]{startItem};
+    }
+
+    ArrayContains(String[] startItems) {
+      this.startItems = startItems;
+    }
+
+    @Override
+    public boolean matches(Object o) {
+      if (o instanceof String[]) {
+        String[] array = (String[]) o;
+
+        for (String item : startItems) {
+          boolean valueContains = false;
+          for (String value : array) {
+            if (value.contains(item)) {
+              valueContains = true;
+              break;
+            }
+          }
+
+          if (!valueContains) {
+            return false;
+          }
+        }
+
+        return true;
+      }
+
+      return false;
+    }
+
+    @Override
+    public void appendTo(StringBuffer stringBuffer) {
+      stringBuffer.append("arrayContains(");
+      stringBuffer.append(StringUtils.join(startItems, ", "));
+      stringBuffer.append("\")");
+    }
+  }
+
+  static String[] arrayContains(String in) {
+    EasyMock.reportMatcher(new ArrayContains(in));
+    return null;
+  }
+
+  static String[] arrayContains(String[] in) {
+    EasyMock.reportMatcher(new ArrayContains(in));
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
index 88c841c..9d1e8e0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
@@ -40,10 +40,128 @@ import junit.framework.Assert;
 
 public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
 
+  static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
+  static final String DEFAULT_ADMIN_PASSWORD = "hadoop";
+  static final String DEFAULT_REALM = "EXAMPLE.COM";
+  static final PrincipalKeyCredential DEFAULT_ADMIN_CREDENTIALS = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
+
   @Rule
   public TemporaryFolder folder = new TemporaryFolder();
 
   @Test
+  public void testOpenSucceeded() throws Exception {
+    KerberosOperationHandler handler = createMockedHandler();
+
+    setupOpenSuccess(handler);
+
+    replayAll();
+
+    handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+
+    verifyAll();
+
+    Assert.assertTrue(handler.isOpen());
+  }
+
+  @Test
+  public void testOpenFailed() throws Exception {
+    KerberosOperationHandler handler = createMockedHandler();
+
+    setupOpenFailure(handler);
+
+    replayAll();
+
+    try {
+      handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+      Assert.fail("KerberosAdminAuthenticationException expected");
+    } catch (KerberosAdminAuthenticationException e) {
+      // This is expected
+    }
+
+    verifyAll();
+
+    Assert.assertFalse(handler.isOpen());
+  }
+
+  @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+  public void testCreateUserPrincipalPrincipalAlreadyExists() throws Exception {
+    testCreatePrincipalPrincipalAlreadyExists(false);
+  }
+
+  @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+  public void testCreateServicePrincipalPrincipalAlreadyExists() throws Exception {
+    testCreatePrincipalPrincipalAlreadyExists(true);
+  }
+
+  private void testCreatePrincipalPrincipalAlreadyExists(boolean service) throws Exception {
+    KerberosOperationHandler handler = createMockedHandler();
+
+    setupOpenSuccess(handler);
+    setupPrincipalAlreadyExists(handler, service);
+
+    replayAll();
+
+    handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+    handler.createPrincipal(createPrincipal(service), "password", service);
+    handler.close();
+
+    verifyAll();
+
+  }
+
+
+  @Test
+  public void testUserPrincipalExistsNotFound() throws Exception {
+    testPrincipalExistsNotFound(false);
+  }
+
+  @Test
+  public void testServicePrincipalExistsNotFound() throws Exception {
+    testPrincipalExistsNotFound(true);
+  }
+
+  private void testPrincipalExistsNotFound(boolean service) throws Exception {
+    KerberosOperationHandler handler = createMockedHandler();
+
+    setupOpenSuccess(handler);
+    setupPrincipalDoesNotExist(handler, service);
+
+    replayAll();
+
+    handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+    Assert.assertFalse(handler.principalExists(createPrincipal(service), service));
+    handler.close();
+
+    verifyAll();
+  }
+
+  @Test
+  public void testUserPrincipalExistsFound() throws Exception {
+    testPrincipalExistsFound(false);
+  }
+
+  @Test
+  public void testServicePrincipalExistsFound() throws Exception {
+    testPrincipalExistsFound(true);
+  }
+
+  private void testPrincipalExistsFound(boolean service) throws Exception {
+    KerberosOperationHandler handler = createMockedHandler();
+
+    setupOpenSuccess(handler);
+    setupPrincipalExists(handler, service);
+
+    replayAll();
+
+    handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+    Assert.assertTrue(handler.principalExists(createPrincipal(service), service));
+    handler.close();
+
+    verifyAll();
+
+  }
+
+  @Test
   public void testCreateKeytabFileOneAtATime() throws Exception {
     KerberosOperationHandler handler = createHandler();
     File file = folder.newFile();
@@ -285,7 +403,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
   public void testAdminCredentialsNullCredential() throws KerberosOperationException {
     KerberosOperationHandler handler = createHandler();
 
-    PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[])null);
+    PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[]) null);
     handler.setAdministratorCredential(credentials);
   }
 
@@ -301,10 +419,10 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
   public void testSetExecutableSearchPaths() throws KerberosOperationException {
     KerberosOperationHandler handler = createHandler();
 
-    handler.setExecutableSearchPaths((String)null);
+    handler.setExecutableSearchPaths((String) null);
     Assert.assertNull(handler.getExecutableSearchPaths());
 
-    handler.setExecutableSearchPaths((String[])null);
+    handler.setExecutableSearchPaths((String[]) null);
     Assert.assertNull(handler.getExecutableSearchPaths());
 
     handler.setExecutableSearchPaths("");
@@ -341,6 +459,24 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
     Assert.assertEquals("path3/", handler.getExecutableSearchPaths()[2]);
   }
 
+  protected abstract KerberosOperationHandler createMockedHandler() throws KerberosOperationException;
+
+  protected abstract void setupOpenSuccess(KerberosOperationHandler handler) throws Exception;
+
+  protected abstract void setupOpenFailure(KerberosOperationHandler handler) throws Exception;
+
+  protected abstract void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+  protected abstract void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception;
+
+  protected abstract void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+  protected abstract Map<String, String> getKerberosEnv();
+
+  protected PrincipalKeyCredential getAdminCredentials() {
+    return DEFAULT_ADMIN_CREDENTIALS;
+  }
+
   private KerberosOperationHandler createHandler() throws KerberosOperationException {
     KerberosOperationHandler handler = new KerberosOperationHandler() {
 
@@ -357,7 +493,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
       }
 
       @Override
-      public boolean principalExists(String principal) throws KerberosOperationException {
+      public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
         return false;
       }
 
@@ -367,12 +503,12 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
       }
 
       @Override
-      public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+      public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
         return 0;
       }
 
       @Override
-      public boolean removePrincipal(String principal) throws KerberosOperationException {
+      public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
         return false;
       }
     };
@@ -380,4 +516,8 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
     handler.open(new PrincipalKeyCredential("admin/admin", "hadoop"), "EXAMPLE.COM", null);
     return handler;
   }
+
+  private String createPrincipal(boolean service) {
+    return String.format("%s@%s", (service) ? "service/host" : "user", DEFAULT_REALM);
+  }
 }


[03/51] [abbrv] ambari git commit: AMBARI-22293. Improve KDC integration (rlevas)

Posted by nc...@apache.org.
AMBARI-22293. Improve KDC integration (rlevas)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: f844e5f3f952b57d790a238f0bafaf7d5ba1ddca
Parents: a7f0f45
Author: Robert Levas <rl...@hortonworks.com>
Authored: Thu Nov 2 12:37:36 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Thu Nov 2 12:37:36 2017 -0400

----------------------------------------------------------------------
 .../docs/security/kerberos/kerberos_service.md  |   22 +-
 .../kerberos/ADKerberosOperationHandler.java    |   22 +-
 .../kerberos/CreatePrincipalsServerAction.java  |    4 +-
 .../kerberos/DestroyPrincipalsServerAction.java |    3 +-
 .../kerberos/IPAKerberosOperationHandler.java   | 1067 +++---------------
 .../kerberos/KDCKerberosOperationHandler.java   |  391 +++++++
 .../kerberos/KerberosOperationHandler.java      |   64 +-
 .../kerberos/MITKerberosOperationHandler.java   |  406 ++-----
 .../server/upgrade/UpgradeCatalog300.java       |   30 +-
 .../1.10.3-10/configuration/kerberos-env.xml    |   36 +-
 .../1.10.3-30/configuration/kerberos-env.xml    |   36 +-
 .../KERBEROS/configuration/kerberos-env.xml     |   36 +-
 .../server/controller/KerberosHelperTest.java   |    6 +-
 .../ADKerberosOperationHandlerTest.java         |  261 +++--
 .../IPAKerberosOperationHandlerTest.java        |  147 ++-
 .../KDCKerberosOperationHandlerTest.java        |  152 +++
 .../kerberos/KerberosOperationHandlerTest.java  |  152 ++-
 .../kerberos/KerberosServerActionTest.java      |  133 ++-
 .../MITKerberosOperationHandlerTest.java        |  633 +++--------
 .../server/upgrade/UpgradeCatalog300Test.java   |  152 ++-
 .../2.5/configs/ranger-admin-secured.json       |    2 -
 .../stacks/2.5/configs/ranger-kms-secured.json  |    2 -
 .../2.6/configs/ranger-admin-secured.json       |    2 -
 .../PreconfigureActionTest_cluster_config.json  |    4 +-
 .../main/admin/kerberos/step2_controller.js     |    2 +-
 25 files changed, 1623 insertions(+), 2142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/docs/security/kerberos/kerberos_service.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/security/kerberos/kerberos_service.md b/ambari-server/docs/security/kerberos/kerberos_service.md
index 65e312b..c9cbd49 100644
--- a/ambari-server/docs/security/kerberos/kerberos_service.md
+++ b/ambari-server/docs/security/kerberos/kerberos_service.md
@@ -231,32 +231,12 @@ _Example:_ `-requires_preauth max_renew_life=7d`
 
 This property is optional and only used if the `kdc_type` is `mit-kdc`
 
-##### group
+##### ipa_user_group
 
 The group in IPA user principals should be member of
 
 This property is mandatory and only used if the `kdc_type` is `ipa`
 
-##### set_password_expiry
-
-Indicates whether Ambari should set the password expiry for the principals it creates. By default
-IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
-attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
-policy is in place for the IPA Group principals are added to.
-
-_Possible values:_ `true`, `false`
-
-_Default value:_ `false`
-
-This property is mandatory and only used if the `kdc_type` is `ipa`
-
-##### password_chat_timeout
-
-Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
-because it can take some time due to lookups before a response is there.
-
-This property is mandatory and only used if the `kdc_type` is `ipa`
-
 <a name="krb5-conf"></a>
 #### krb5-conf
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
index f7d6060..d7b91b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
@@ -175,9 +175,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosLDAPContainerException("principalContainerDn is not a valid LDAP name", e);
     }
 
-    setAdministratorCredential(administratorCredential);
-    setDefaultRealm(realm);
-    setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
+    super.open(administratorCredential, realm, kerberosConfiguration);
 
     this.ldapContext = createLdapContext();
     this.searchControls = createSearchControls();
@@ -215,11 +213,12 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to test
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal exists; false otherwise
    * @throws KerberosOperationException
    */
   @Override
-  public boolean principalExists(String principal) throws KerberosOperationException {
+  public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
@@ -260,7 +259,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
     if (password == null) {
       throw new KerberosOperationException("principal password is null");
     }
-    if (principalExists(principal)) {
+    if (principalExists(principal, service)) {
       throw new KerberosPrincipalAlreadyExistsException(principal);
     }
 
@@ -347,12 +346,13 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
    *
    * @param principal a String containing the principal to update
    * @param password  a String containing the password to set
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return an Integer declaring the new key number
    * @throws KerberosPrincipalDoesNotExistException if the principal does not exist
    * @throws KerberosOperationException
    */
   @Override
-  public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+  public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
@@ -362,7 +362,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
     if (password == null) {
       throw new KerberosOperationException("principal password is null");
     }
-    if(!principalExists(principal)) {
+    if (!principalExists(principal, service)) {
       throw new KerberosPrincipalDoesNotExistException(principal);
     }
 
@@ -396,11 +396,12 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to remove
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal was successfully removed; otherwise false
    * @throws KerberosOperationException
    */
   @Override
-  public boolean removePrincipal(String principal) throws KerberosOperationException {
+  public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
@@ -469,10 +470,9 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
       String message = String.format("Failed to communicate with the Active Directory at %s: %s", ldapUrl, e.getMessage());
       LOG.warn(message, e);
 
-      if(rootCause instanceof SSLHandshakeException) {
+      if (rootCause instanceof SSLHandshakeException) {
         throw new KerberosKDCSSLConnectionException(message, e);
-      }
-      else {
+      } else {
         throw new KerberosKDCConnectionException(message, e);
       }
     } catch (AuthenticationException e) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
index 08e03bd..59d5327 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
@@ -253,7 +253,7 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
 
         if (regenerateKeytabs) {
           try {
-            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password);
+            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
             created = false;
           } catch (KerberosPrincipalDoesNotExistException e) {
             message = String.format("Principal, %s, does not exist, creating new principal", principal);
@@ -276,7 +276,7 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
               actionLog.writeStdOut(message);
             }
 
-            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password);
+            keyNumber = kerberosOperationHandler.setPrincipalPassword(principal, password, isServicePrincipal);
             created = false;
           }
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
index 2b3a0ca..4c80bd4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/DestroyPrincipalsServerAction.java
@@ -114,7 +114,8 @@ public class DestroyPrincipalsServerAction extends KerberosServerAction {
 
       try {
         try {
-          operationHandler.removePrincipal(evaluatedPrincipal);
+          boolean servicePrincipal = "service".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL_TYPE));
+          operationHandler.removePrincipal(evaluatedPrincipal, servicePrincipal);
         } catch (KerberosOperationException e) {
           message = String.format("Failed to remove identity for %s from the KDC - %s", evaluatedPrincipal, e.getMessage());
           LOG.warn(message);

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
index 9a6a07e..c411237 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
@@ -18,32 +18,14 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Set;
 
 import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
-import org.apache.ambari.server.utils.Closeables;
 import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
-import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,12 +36,9 @@ import org.slf4j.LoggerFactory;
  * It is assumed that the IPA admin tools are installed and that the ipa shell command is
  * available
  */
-public class IPAKerberosOperationHandler extends KerberosOperationHandler {
+public class IPAKerberosOperationHandler extends KDCKerberosOperationHandler {
   private final static Logger LOG = LoggerFactory.getLogger(IPAKerberosOperationHandler.class);
 
-  private String adminServerHost = null;
-
-  private HashMap<String, Keytab> cachedKeytabs = null;
   /**
    * This is where user principals are members of. Important as the password should not expire
    * and thus a separate password policy should apply to this group
@@ -67,27 +46,6 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
   private String userPrincipalGroup = null;
 
   /**
-   * The format used for krbPasswordExpiry
-   */
-  private final SimpleDateFormat expiryFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
-
-  /**
-   * Time zone for krbPasswordExpiry
-   */
-  private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
-
-  /**
-   * Years to add for password expiry
-   */
-  private static final int PASSWORD_EXPIRY_YEAR = 30;
-
-  /**
-   * A regular expression pattern to use to parse the key number from the text captured from the
-   * kvno command
-   */
-  private final static Pattern PATTERN_GET_KEY_NUMBER = Pattern.compile("^.*?: kvno = (\\d+).*$", Pattern.DOTALL);
-
-  /**
    * A String containing the resolved path to the ipa executable
    */
   private String executableIpaGetKeytab = null;
@@ -98,31 +56,6 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
   private String executableIpa = null;
 
   /**
-   * A String containing the resolved path to the kinit executable
-   */
-  private String executableKinit = null;
-
-  /**
-   * A String containing the resolved path to the ipa-getkeytab executable
-   */
-  private String executableKvno = null;
-
-  /**
-   * A boolean indicating if password expiry should be set
-   */
-  private boolean usePasswordExpiry = false;
-
-  /**
-   * An int indicating the time out in seconds for the password chat;
-   */
-  private int timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
-
-  /**
-   * Credentials context stores a handler to the ccache so it can be reused and removed on request
-   */
-  private CredentialsContext credentialsContext;
-
-  /**
    * Prepares and creates resources to be used by this KerberosOperationHandler
    * <p/>
    * It is expected that this KerberosOperationHandler will not be used before this call.
@@ -139,84 +72,27 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public void open(PrincipalKeyCredential administratorCredentials, String realm,
-                   Map<String, String> kerberosConfiguration)
-          throws KerberosOperationException {
-
-    setAdministratorCredential(administratorCredentials);
-    setDefaultRealm(realm);
+  public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
+      throws KerberosOperationException {
 
     if (kerberosConfiguration != null) {
-      // todo: ignore if ipa managed krb5.conf?
-      setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
-      setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
-      setUserPrincipalGroup(kerberosConfiguration.get(KERBEROS_ENV_USER_PRINCIPAL_GROUP));
-      setAdminServerHost(kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST));
-      setUsePasswordExpiry(kerberosConfiguration.get(KERBEROS_ENV_SET_PASSWORD_EXPIRY));
-      setTimeout(kerberosConfiguration.get(KERBEROS_ENV_PASSWORD_CHAT_TIMEOUT));
-    } else {
-      setKeyEncryptionTypes(null);
-      setAdminServerHost(null);
-      setExecutableSearchPaths((String) null);
-      setUserPrincipalGroup(null);
-      setUsePasswordExpiry(null);
-      setTimeout(null);
+      userPrincipalGroup = kerberosConfiguration.get(KERBEROS_ENV_USER_PRINCIPAL_GROUP);
     }
 
     // Pre-determine the paths to relevant Kerberos executables
     executableIpa = getExecutable("ipa");
-    executableKvno = getExecutable("kvno");
-    executableKinit = getExecutable("kinit");
     executableIpaGetKeytab = getExecutable("ipa-getkeytab");
 
-    credentialsContext = new CredentialsContext(administratorCredentials);
-    cachedKeytabs = new HashMap<>();
-    expiryFormat.setTimeZone(UTC);
-
-    setOpen(true);
-  }
-
-  private void setUsePasswordExpiry(String usePasswordExpiry) {
-    if (usePasswordExpiry == null) {
-      this.usePasswordExpiry = false;
-      return;
-    }
-
-    if (usePasswordExpiry.equalsIgnoreCase("true")) {
-      this.usePasswordExpiry = true;
-    } else {
-      this.usePasswordExpiry = false;
-    }
-  }
-
-  private void setTimeout(String timeout) {
-    if (timeout == null || timeout.isEmpty()) {
-      this.timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
-      return;
-    }
-
-    try {
-      this.timeout = Integer.parseInt(timeout);
-    } catch (NumberFormatException e) {
-      this.timeout = DEFAULT_PASSWORD_CHAT_TIMEOUT;
-    }
+    super.open(administratorCredentials, realm, kerberosConfiguration);
   }
 
   @Override
   public void close() throws KerberosOperationException {
-    if (isOpen()) {
-      credentialsContext.delete();
-    }
-
-    // There is nothing to do here.
-    setOpen(false);
-
+    userPrincipalGroup = null;
     executableIpa = null;
-    executableKvno = null;
     executableIpaGetKeytab = null;
-    executableKinit = null;
-    credentialsContext = null;
-    cachedKeytabs = null;
+
+    super.close();
   }
 
   /**
@@ -226,190 +102,121 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
    * the result from STDOUT to determine if the presence of the specified principal.
    *
    * @param principal a String containing the principal to test
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal exists; false otherwise
    * @throws KerberosOperationException if an unexpected error occurred
    */
   @Override
-  public boolean principalExists(String principal)
-          throws KerberosOperationException {
-
-    LOG.debug("Entering principal exists");
+  public boolean principalExists(String principal, boolean service)
+      throws KerberosOperationException {
 
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if (principal == null) {
-      return false;
-    } else if (isServicePrincipal(principal)) {
-      return true;
-    } else {
-      // TODO: fix exception check to only check for relevant exceptions
-      try {
-        DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-        LOG.debug("Running IPA command user-show");
+    if (!StringUtils.isEmpty(principal)) {
+      DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
+      String principalName = deconstructedPrincipal.getPrincipalName();
 
-        // Create the ipa query to execute:
-        ShellCommandUtil.Result result = invokeIpa(String.format("user-show %s", deconstructedPrincipal.getPrincipalName()));
-        if (result.isSuccessful()) {
-          return true;
-        }
-      } catch (KerberosOperationException e) {
-        LOG.error("Cannot invoke IPA: " + e);
-        throw e;
+      String[] ipaCommand = new String[]{
+          (service) ? "service-show" : "user-show",
+          principalName
+      };
+
+      ShellCommandUtil.Result result = invokeIpa(ipaCommand);
+      if (result.isSuccessful()) {
+        return true;
       }
     }
 
     return false;
   }
 
-
   /**
-   * Creates a new principal in a previously configured IPA Realm
-   * <p/>
-   * This implementation creates a query to send to the kadmin shell command and then interrogates
-   * the result from STDOUT to determine if the operation executed successfully.
+   * Creates a new principal in a previously configured KDC.
+   * <p>
+   * This implementation uses the ipa shell to create either a user or service account.  No password
+   * will be set for either account type.  The password (or key) will be automatically generated by
+   * the IPA server when exporting the keytab entry.  Upon success, this method will always return
+   * <code>0</code> as the key number since the value is not generated until the keytab entry is
+   * exported.
    *
-   * @param principal a String containing the principal add
-   * @param password  a String containing the password to use when creating the principal
+   * @param principal a String containing the principal to add
+   * @param password  a String containing the password to use when creating the principal (ignored)
    * @param service   a boolean value indicating whether the principal is to be created as a service principal or not
-   * @return an Integer declaring the generated key number
-   * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
+   * @return an Integer declaring the generated key number (always 0)
+   * @throws KerberosOperationException
    */
   @Override
   public Integer createPrincipal(String principal, String password, boolean service)
-          throws KerberosOperationException {
+      throws KerberosOperationException {
 
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to create new principal - no principal specified");
-    } else if (((password == null) || password.isEmpty()) && service) {
-      throw new KerberosOperationException("Failed to create new user principal - no password specified");
-    } else {
-      DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-
-      if (service) {
-        // Create the ipa query:  service-add --ok-as-delegate <principal>
-        ShellCommandUtil.Result result = invokeIpa(String.format("service-add %s", principal));
-        if (result.isSuccessful()) {
-          // IPA does not generate encryption types when no keytab has been generated
-          // So getKeyNumber(principal) cannot be used.
-          // createKeytabCredentials(principal, password);
-          // return getKeyNumber(principal);
-          return 0;
-        } else {
-          LOG.error("Failed to execute ipa query: service-add --ok-as-delegate=TRUE {}\nSTDOUT: {}\nSTDERR: {}",
-                  principal, result.getStdout(), result.getStderr());
-          throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
-                  principal, result.getStdout(), result.getStderr()));
-        }
-      } else {
-        if (!StringUtils.isAllLowerCase(deconstructedPrincipal.getPrincipalName())) {
-          LOG.warn(deconstructedPrincipal.getPrincipalName() + " is not in lowercase. FreeIPA does not recognize user " +
-                  "principals that are not entirely in lowercase. This can lead to issues with kinit and keytabs. Make " +
-                  "sure users are in lowercase ");
-        }
-        // Create the ipa query: user-add <username> --principal=<principal_name> --first <primary> --last <primary>
-        // set-attr userPassword="<password>"
-        // first and last are required for IPA so we make it equal to the primary
-        // the --principal arguments makes sure that Kerberos keys are available for use in getKeyNumber
-        ShellCommandUtil.Result result = invokeIpa(String.format("user-add %s --principal=%s --first %s --last %s --setattr userPassword=%s",
-                deconstructedPrincipal.getPrimary(), deconstructedPrincipal.getPrincipalName(),
-                deconstructedPrincipal.getPrimary(), deconstructedPrincipal.getPrimary(), password));
-
-        if (!result.isSuccessful()) {
-          throw new KerberosOperationException(String.format("Failed to create user principal for %s\nSTDOUT: %s\nSTDERR: %s",
-                  principal, result.getStdout(), result.getStderr()));
-        }
-
-        if (getUserPrincipalGroup() != null && !getUserPrincipalGroup().isEmpty()) {
-          result = invokeIpa(String.format("group-add-member %s --users=%s",
-                  getUserPrincipalGroup(), deconstructedPrincipal.getPrimary()));
-          if (!result.isSuccessful()) {
-            throw new KerberosOperationException(String.format("Failed to create user principal for %s\nSTDOUT: %s\nSTDERR: %s",
-                    principal, result.getStdout(), result.getStderr()));
-          }
-        }
-
-        if (!usePasswordExpiry) {
-          updatePassword(deconstructedPrincipal.getPrimary(), password);
-          return getKeyNumber(principal);
-        }
-
-        Calendar calendar = Calendar.getInstance();
-        calendar.add(Calendar.YEAR, PASSWORD_EXPIRY_YEAR);
+    }
 
-        result = invokeIpa(String.format("user-mod %s --setattr krbPasswordExpiration=%s",
-                deconstructedPrincipal.getPrimary(), expiryFormat.format(calendar.getTime())));
+    DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
+    String normalizedPrincipal = deconstructedPrincipal.getNormalizedPrincipal();
 
-        if (result.isSuccessful()) {
-          return getKeyNumber(principal);
-        }
+    String[] ipaCommand;
+    if (service) {
+      ipaCommand = new String[]{
+          "service-add",
+          normalizedPrincipal
+      };
+    } else {
+      String principalName = deconstructedPrincipal.getPrincipalName();
 
-        throw new KerberosOperationException(String.format("Unknown error while creating principal for %s\n" +
-                        "STDOUT: %s\n" +
-                        "STDERR: %s\n",
-                principal, result.getStdout(), result.getStderr()));
+      if (!principalName.equals(principal.toLowerCase())) {
+        LOG.warn("{} is not in lowercase. FreeIPA does not recognize user " +
+            "principals that are not entirely in lowercase. This can lead to issues with kinit and keytabs. Make " +
+            "sure users are in lowercase.", principalName);
       }
-    }
-  }
 
-  /**
-   * Updates the password for an existing user principal in a previously configured IPA KDC
-   * <p/>
-   * This implementation creates a query to send to the ipa shell command and then interrogates
-   * the exit code to determine if the operation executed successfully.
-   *
-   * @param principal a String containing the principal to update
-   * @param password  a String containing the password to set
-   * @return an Integer declaring the new key number
-   * @throws KerberosOperationException if an unexpected error occurred
-   */
-  @Override
-  public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
-    if (!isOpen()) {
-      throw new KerberosOperationException("This operation handler has not been opened");
+      ipaCommand = new String[]{
+          "user-add",
+          deconstructedPrincipal.getPrimary(),
+          "--principal",
+          principalName,
+          "--first",
+          deconstructedPrincipal.getPrimary(),
+          "--last",
+          deconstructedPrincipal.getPrimary()
+      };
     }
 
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to set password - no principal specified");
-    } else if ((password == null) || password.isEmpty()) {
-      throw new KerberosOperationException("Failed to set password - no password specified");
-    } else if (!isServicePrincipal(principal)) {
-      DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-
-      if (usePasswordExpiry) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.add(Calendar.YEAR, PASSWORD_EXPIRY_YEAR);
+    ShellCommandUtil.Result result = invokeIpa(ipaCommand);
+    if (!result.isSuccessful()) {
+      String message = String.format("Failed to create principal for %s\n%s\nSTDOUT: %s\nSTDERR: %s",
+          normalizedPrincipal, StringUtils.join(ipaCommand, " "), result.getStdout(), result.getStderr());
+      LOG.error(message);
 
-        // Create the ipa query:  user-mod <user> --setattr userPassword=<password>
-        invokeIpa(String.format("user-mod %s --setattr userPassword=%s", deconstructedPrincipal.getPrimary(), password));
+      String stdErr = result.getStderr();
 
-        List<String> command = new ArrayList<>();
-        command.add(executableIpa);
-        command.add("user-mod");
-        command.add(deconstructedPrincipal.getPrimary());
-        command.add("--setattr");
-        command.add(String.format("krbPasswordExpiration=%s", expiryFormat.format(calendar.getTime())));
-        ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
-        if (!result.isSuccessful()) {
-          throw new KerberosOperationException("Failed to set password expiry");
-        }
+      if ((stdErr != null) &&
+          ((service && stdErr.contains(String.format("service with name \"%s\" already exists", normalizedPrincipal))) ||
+          (!service && stdErr.contains(String.format("user with name \"%s\" already exists", deconstructedPrincipal.getPrimary()))))) {
+        throw new KerberosPrincipalAlreadyExistsException(principal);
       } else {
-        updatePassword(deconstructedPrincipal.getPrimary(), password);
+        throw new KerberosOperationException(String.format("Failed to create principal for %s\nSTDOUT: %s\nSTDERR: %s",
+            normalizedPrincipal, result.getStdout(), result.getStderr()));
       }
-    } else {
-      ShellCommandUtil.Result result = invokeIpa(String.format("service-show %s", principal));
-      // ignore the keytab but set the password for this principal
-      if (result.isSuccessful() && result.getStdout().contains("Keytab: False")) {
-        LOG.debug("Found service principal {} without password/keytab. Setting one", principal);
-        createKeytab(principal, password, 0);
+    }
+
+    if ((!service) && !StringUtils.isEmpty(userPrincipalGroup)) {
+      result = invokeIpa(new String[]{"group-add-member", userPrincipalGroup, "--users", deconstructedPrincipal.getPrimary()});
+      if (!result.isSuccessful()) {
+        LOG.warn("Failed to add account for {} to group {}: \nSTDOUT: {}\nSTDERR: {}",
+            normalizedPrincipal, userPrincipalGroup, result.getStdout(), result.getStderr());
       }
     }
-    return getKeyNumber(principal);
+
+    // Always return 0 since we do not have a key to get a key number for.
+    return 0;
   }
 
   /**
@@ -418,6 +225,7 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to remove
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal was successfully removed; otherwise false
    * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
    * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -425,696 +233,95 @@ public class IPAKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public boolean removePrincipal(String principal) throws KerberosOperationException {
+  public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
     if (!isOpen()) {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to remove new principal - no principal specified");
-    } else {
-      ShellCommandUtil.Result result = null;
-      if (isServicePrincipal(principal)) {
-        result = invokeIpa(String.format("service-del %s", principal));
-      } else {
-        DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
-        result = invokeIpa(String.format("user-del %s", deconstructedPrincipal.getPrincipalName()));
-      }
-      return result.isSuccessful();
+    if (StringUtils.isEmpty(principal)) {
+      throw new KerberosOperationException("Failed to remove principal - no principal specified");
     }
-  }
 
-  /**
-   * Sets the name of the group where user principals should be members of
-   *
-   * @param userPrincipalGroup the name of the group
-   */
-  public void setUserPrincipalGroup(String userPrincipalGroup) {
-    this.userPrincipalGroup = userPrincipalGroup;
-  }
+    DeconstructedPrincipal deconstructedPrincipal = createDeconstructPrincipal(principal);
 
-  /**
-   * Gets the name of the group where user principals should be members of
-   *
-   * @return name of the group where user principals should be members of
-   */
-  public String getUserPrincipalGroup() {
-    return this.userPrincipalGroup;
-  }
+    String[] ipaCommand = (service)
+        ? new String[]{"service-del", deconstructedPrincipal.getNormalizedPrincipal()}
+        : new String[]{"user-del", deconstructedPrincipal.getPrincipalName()};
 
-  /**
-   * Sets the KDC administrator server host address
-   *
-   * @param adminServerHost the ip address or FQDN of the IPA administrator server
-   */
-  public void setAdminServerHost(String adminServerHost) {
-    this.adminServerHost = adminServerHost;
+    return invokeIpa(ipaCommand).isSuccessful();
   }
 
-  /**
-   * Gets the IP address or FQDN of the IPA administrator server
-   *
-   * @return the IP address or FQDN of the IPA administrator server
-   */
-  public String getAdminServerHost() {
-    return this.adminServerHost;
+  @Override
+  protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) {
+    return new String[]{
+        executableKinit,
+        "-c",
+        credentialsCache,
+        credentials.getPrincipal()
+    };
   }
 
-  /**
-   * Reads data from a stream without blocking and when available. Allows some time for the
-   * stream to become ready.
-   *
-   * @param stdin  the stdin BufferedReader to read from
-   * @param stderr the stderr BufferedReader in case something goes wrong
-   * @return a String with available data
-   * @throws KerberosOperationException if a timeout happens
-   * @throws IOException                when somethings goes wrong with the underlying stream
-   * @throws InterruptedException       if the thread is interrupted
-   */
-  private String readData(BufferedReader stdin, BufferedReader stderr) throws KerberosOperationException, IOException, InterruptedException {
-    char[] data = new char[1024];
-    StringBuilder sb = new StringBuilder();
-
-    int count = 0;
-    while (!stdin.ready()) {
-      Thread.sleep(1000L);
-      if (count >= timeout) {
-        char[] err_data = new char[1024];
-        StringBuilder err = new StringBuilder();
-        while (stderr.ready()) {
-          stderr.read(err_data);
-          err.append(err_data);
+  @Override
+  protected void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException {
+    String encryptionTypeSpec = null;
+    if (!CollectionUtils.isEmpty(keyEncryptionTypes)) {
+      StringBuilder encryptionTypeSpecBuilder = new StringBuilder();
+      for (EncryptionType encryptionType : keyEncryptionTypes) {
+        if (encryptionTypeSpecBuilder.length() > 0) {
+          encryptionTypeSpecBuilder.append(',');
         }
-        throw new KerberosOperationException("No answer data available from stdin stream. STDERR: " + err);
+        encryptionTypeSpecBuilder.append(encryptionType.getName());
       }
-      count++;
-    }
 
-    while (stdin.ready()) {
-      stdin.read(data);
-      sb.append(data);
+      encryptionTypeSpec = encryptionTypeSpecBuilder.toString();
     }
 
-    return sb.toString();
-  }
-
-  /**
-   * Updates a  password for a (user) principal. This is done by first setting a random password and
-   * then invoking kInit to directly set the password. This is done to circumvent issues with expired
-   * password in IPA, as IPA needs passwords set by the admin to be set again by the user. Note that
-   * this resets the current principal to the principal specified here. To invoke further administrative
-   * commands a new kInit to admin is required.
-   *
-   * @param principal The principal user name that needs to be updated
-   * @param password  The new password
-   * @throws KerberosOperationException if something is not as expected
-   */
-  private void updatePassword(String principal, String password) throws KerberosOperationException {
-    BufferedReader reader = null;
-    BufferedReader stderr = null;
-    OutputStreamWriter out = null;
-
-    LOG.debug("Updating password for: {}", principal);
-
-    UUID uuid = UUID.randomUUID();
-    String fileName = System.getProperty("java.io.tmpdir") +
-            File.pathSeparator +
-            "krb5cc_" + uuid;
-
-    try {
-      ShellCommandUtil.Result result = invokeIpa(String.format("user-mod %s --random", principal));
-      if (!result.isSuccessful()) {
-        throw new KerberosOperationException(result.getStderr());
-      }
-      Pattern pattern = Pattern.compile("password: (.*)");
-      Matcher matcher = pattern.matcher(result.getStdout());
-      if (!matcher.find()) {
-        throw new KerberosOperationException("Unexpected response from ipa: " + result.getStdout());
-      }
-      String old_password = matcher.group(1);
-
-      String credentialsCache = String.format("FILE:%s", fileName);
-      Process process = Runtime.getRuntime().exec(new String[]{executableKinit, "-c", credentialsCache, principal});
-      reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
-      stderr = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
-      out = new OutputStreamWriter(process.getOutputStream());
-
-      String data = readData(reader, stderr);
-      if (!data.startsWith("Password")) {
-        process.destroy();
-        throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
-                + principal + " got: " + data);
-      }
-      LOG.debug("Sending old password");
-      out.write(old_password);
-      out.write('\n');
-      out.flush();
-
-      data = readData(reader, stderr);
-      if (!data.contains("Enter")) {
-        process.destroy();
-        throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
-                + principal + " got: " + data);
-      }
-      LOG.debug("Sending new password");
-      out.write(password);
-      out.write('\n');
-      out.flush();
-
-      data = readData(reader, stderr);
-      if (!data.contains("again")) {
-        process.destroy();
-        throw new KerberosOperationException("Unexpected response from kinit while trying to password for "
-                + principal + " got: " + data);
-      }
-      LOG.debug("Sending new password again");
-      out.write(password);
-      out.write('\n');
-      out.flush();
+    String[] createKeytabFileCommand = (StringUtils.isEmpty(encryptionTypeSpec))
+        ? new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-p", principal, "-k", keytabFileDestinationPath}
+        : new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-e", encryptionTypeSpec, "-p", principal, "-k", keytabFileDestinationPath};
 
-      process.waitFor();
-    } catch (IOException e) {
-      LOG.error("Cannot read stream: " + e);
-      throw new KerberosOperationException(e.getMessage());
-    } catch (InterruptedException e) {
-      LOG.error("Process interrupted: " + e);
-      throw new KerberosOperationException(e.getMessage());
-    } finally {
-      try {
-        if (out != null)
-          out.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close out stream: " + e);
-      }
-      try {
-        if (reader != null)
-          reader.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close stdin stream: " + e);
-      }
-      try {
-        if (stderr != null)
-          stderr.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close stderr stream: " + e);
-      }
-      File ccache = new File(fileName);
-      ccache.delete();
+    ShellCommandUtil.Result result = executeCommand(createKeytabFileCommand);
+    if (!result.isSuccessful()) {
+      String message = String.format("Failed to export the keytab file for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+          principal, result.getExitCode(), result.getStdout(), result.getStderr());
+      LOG.warn(message);
+      throw new KerberosOperationException(message);
     }
-
   }
 
   /**
    * Invokes the ipa shell command with administrative credentials to issue queries
    *
-   * @param query a String containing the query to send to the kdamin command
+   * @param query a String containing the query to send to the ipa command
    * @return a ShellCommandUtil.Result containing the result of the operation
    * @throws KerberosOperationException if an unexpected error occurred
    */
-  protected ShellCommandUtil.Result invokeIpa(String query)
-          throws KerberosOperationException {
-    LOG.debug("Entering invokeipa");
+  private ShellCommandUtil.Result invokeIpa(String[] query) throws KerberosOperationException {
 
-    ShellCommandUtil.Result result = null;
-
-    if ((query == null) || query.isEmpty()) {
+    if ((query == null) || (query.length == 0)) {
       throw new KerberosOperationException("Missing ipa query");
     }
-    PrincipalKeyCredential administratorCredentials = getAdministratorCredential();
-    String defaultRealm = getDefaultRealm();
-
-    List<String> command = new ArrayList<>();
-    List<String> kinit = new ArrayList<>();
 
-    String adminPrincipal = (administratorCredentials == null)
-            ? null
-            : administratorCredentials.getPrincipal();
-
-    if ((adminPrincipal == null) || adminPrincipal.isEmpty()) {
-      throw new KerberosOperationException("No admin principal for ipa available - " +
-              "this KerberosOperationHandler may not have been opened.");
-    }
-
-    if ((executableIpa == null) || executableIpa.isEmpty()) {
-      throw new KerberosOperationException("No path for ipa is available - " +
-              "this KerberosOperationHandler may not have been opened.");
+    if (StringUtils.isEmpty(executableIpa)) {
+      throw new KerberosOperationException("No path for ipa is available - this KerberosOperationHandler may not have been opened.");
     }
 
-    // Set the ipa interface to be ipa
-    command.add(executableIpa);
-    command.add(query);
-
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Executing: {}", createCleanCommand(command));
-    }
+    String[] command = new String[query.length + 1];
+    command[0] = executableIpa;
+    System.arraycopy(query, 0, command, 1, query.length);
 
-    List<String> fixedCommand = fixCommandList(command);
-    result = executeCommand(fixedCommand.toArray(new String[fixedCommand.size()]));
-
-
-    LOG.debug("Done invokeipa");
-    return result;
-  }
+    ShellCommandUtil.Result result = executeCommand(command);
 
-  /**
-   * Executes a shell command in a credentials context
-   * <p/>
-   * See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[])}
-   *
-   * @param command an array of String value representing the command and its arguments
-   * @return a ShellCommandUtil.Result declaring the result of the operation
-   * @throws KerberosOperationException
-   */
-  @Override
-  protected ShellCommandUtil.Result executeCommand(String[] command)
-          throws KerberosOperationException {
-    return credentialsContext.executeCommand(command);
-  }
-
-  /**
-   * Rebuilds the command line to make sure space are converted to arguments
-   *
-   * @param command a List of items making up the command
-   * @return the fixed command
-   */
-  private List<String> fixCommandList(List<String> command) {
-    List<String> fixedCommandList = new ArrayList<>();
-    Iterator<String> iterator = command.iterator();
-
-    if (iterator.hasNext()) {
-      fixedCommandList.add(iterator.next());
-    }
-
-    while (iterator.hasNext()) {
-      String part = iterator.next();
-
-      // split arguments
-      if (part.contains(" ")) {
-        StringTokenizer st = new StringTokenizer(part, " ");
-        while (st.hasMoreElements()) {
-          fixedCommandList.add(st.nextToken());
-        }
-      } else {
-        fixedCommandList.add(part);
-      }
-    }
-
-    return fixedCommandList;
-  }
-
-  /**
-   * Build the ipa command string, replacing administrator password with "********"
-   *
-   * @param command a List of items making up the command
-   * @return the cleaned command string
-   */
-  private String createCleanCommand(List<String> command) {
-    StringBuilder cleanedCommand = new StringBuilder();
-    Iterator<String> iterator = command.iterator();
-
-    if (iterator.hasNext()) {
-      cleanedCommand.append(iterator.next());
-    }
-
-    while (iterator.hasNext()) {
-      String part = iterator.next();
-
-      cleanedCommand.append(' ');
-      cleanedCommand.append(part);
-
-      if ("--setattr".equals(part)) {
-        // Skip the password and use "********" instead
-        String arg= null;
-        if (iterator.hasNext()) {
-          arg = iterator.next();
-          if (arg.contains("userPassword")) {
-            cleanedCommand.append("userPassword=******");
-          } else {
-            cleanedCommand.append(arg);
-          }
-        }
-      }
-    }
-
-    return cleanedCommand.toString();
-  }
-
-  /**
-   * Determine is a principal is a service principal
-   *
-   * @param principal
-   * @return true if the principal is a (existing) service principal
-   * @throws KerberosOperationException
-   */
-  private boolean isServicePrincipal(String principal)
-          throws KerberosOperationException {
-
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to determine principal type- no principal specified");
-    } else if (!principal.contains("/")) {
-      return false;
-    }
-
-    try {
-      ShellCommandUtil.Result result = invokeIpa(String.format("service-show %s", principal));
-
-      // TODO: unfortunately we can be in limbo if the "Keytab: False" is present
-      if (result.isSuccessful()) {
-        return true;
+    if (result.isSuccessful()) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Executed the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+            StringUtils.join(command, " "), result.getStdout(), result.getStderr());
       }
-    } catch (KerberosOperationException e) {
-      LOG.warn("Exception while invoking ipa service-show: " + e);
-      return false;
-    }
-
-    return false;
-  }
-
-  /**
-   * Retrieves the current key number assigned to the identity identified by the specified principal
-   *
-   * @param principal a String declaring the principal to look up
-   * @return an Integer declaring the current key number
-   * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
-   * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
-   * @throws KerberosRealmException               if the realm does not map to a KDC
-   * @throws KerberosOperationException           if an unexpected error occurred
-   */
-  private Integer getKeyNumber(String principal) throws KerberosOperationException {
-    if (!isOpen()) {
-      throw new KerberosOperationException("This operation handler has not been opened");
-    }
-
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to get key number for principal  - no principal specified");
     } else {
-      // Create the kvno query:  <principal>
-      List<String> command = new ArrayList<>();
-      command.add(executableKvno);
-      command.add(principal);
-
-      ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
-      String stdOut = result.getStdout();
-      if (stdOut == null) {
-        String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-                principal, result.getExitCode(), result.getStderr());
-        LOG.warn(message);
-        throw new KerberosOperationException(message);
-      }
-
-      Matcher matcher = PATTERN_GET_KEY_NUMBER.matcher(stdOut);
-      if (matcher.matches()) {
-        NumberFormat numberFormat = NumberFormat.getIntegerInstance();
-        String keyNumber = matcher.group(1);
-
-        numberFormat.setGroupingUsed(false);
-        try {
-          Number number = numberFormat.parse(keyNumber);
-          return (number == null) ? 0 : number.intValue();
-        } catch (ParseException e) {
-          String message = String.format("Failed to get key number for %s - invalid key number value (%s):\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-                  principal, keyNumber, result.getExitCode(), result.getStderr());
-          LOG.warn(message);
-          throw new KerberosOperationException(message);
-        }
-      } else {
-        String message = String.format("Failed to get key number for %s - unexpected STDOUT data:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
-                principal, result.getExitCode(), result.getStderr());
-        LOG.warn(message);
-        throw new KerberosOperationException(message);
-      }
-
-    }
-  }
-
-  /*
-   * Creates a key tab by using the ipa commandline utilities.
-   *
-   * @param principal a String containing the principal to test
-   * @param password  a String containing the password to use when creating the principal
-   * @return
-   * @throws KerberosOperationException
-   */
-  /*private Keytab createKeytabCredentials(String principal, String password)
-          throws KerberosOperationException {
-
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to create keytab file, missing principal");
-    }
-
-    BufferedReader reader = null;
-    BufferedReader stderr = null;
-    OutputStreamWriter out = null;
-
-    UUID uuid = UUID.randomUUID();
-    String fileName = System.getProperty("java.io.tmpdir") +
-            File.pathSeparator +
-            "ambari." + uuid.toString();
-
-    try {
-      // TODO: add ciphers
-      Process p = credentialsContext.exec(new String[]{executableIpaGetKeytab, "-s",
-              getAdminServerHost(), "-p", principal, "-k", fileName, "-P"});
-      reader = new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8));
-      stderr = new BufferedReader(new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8));
-      out = new OutputStreamWriter(p.getOutputStream());
-
-      String data = readData(reader, stderr);
-      if (!data.startsWith("New")) {
-        p.destroy();
-        throw new KerberosOperationException("Unexpected response from ipa-getkeytab while trying to password for "
-                + principal + " got: " + data);
-      }
-      LOG.debug("Sending password");
-      out.write(password);
-      out.write('\n');
-      out.flush();
-
-      data = readData(reader, stderr);
-      if (!data.contains("Verify")) {
-        p.destroy();
-        throw new KerberosOperationException("Unexpected response from ipa-getkeytab while trying to password for "
-                + principal + " got: " + data);
-      }
-      LOG.debug("Sending new password");
-      out.write(password);
-      out.write('\n');
-      out.flush();
-
-      p.waitFor();
-    } catch (IOException e) {
-      LOG.error("Cannot read stream: " + e);
-      throw new KerberosOperationException(e.getMessage());
-    } catch (InterruptedException e) {
-      LOG.error("Process interrupted: " + e);
-      throw new KerberosOperationException(e.getMessage());
-    } finally {
-      try {
-        if (out != null)
-          out.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close out stream: " + e);
-      }
-      try {
-        if (reader != null)
-          reader.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close stdin stream: " + e);
-      }
-      try {
-        if (stderr != null)
-          stderr.close();
-      } catch (IOException e) {
-        LOG.warn("Cannot close stderr stream: " + e);
-      }
-    }
-
-    File keytabFile = new File(fileName);
-    Keytab keytab = readKeytabFile(keytabFile);
-    keytabFile.delete();
-
-    return keytab;
-  }*/
-
-  /**
-   * Creates a key tab by using the ipa commandline utilities. It ignores key number and password
-   * as this will be handled by IPA
-   *
-   * @param principal a String containing the principal to test
-   * @param password  (IGNORED) a String containing the password to use when creating the principal
-   * @param keyNumber (IGNORED) a Integer indicating the key number for the keytab entries
-   * @return
-   * @throws KerberosOperationException
-   */
-  @Override
-  protected Keytab createKeytab(String principal, String password, Integer keyNumber)
-          throws KerberosOperationException {
-
-    if ((principal == null) || principal.isEmpty()) {
-      throw new KerberosOperationException("Failed to create keytab file, missing principal");
-    }
-
-    // use cache if available
-    if (cachedKeytabs.containsKey(principal)) {
-      return cachedKeytabs.get(principal);
-    }
-
-    UUID uuid = UUID.randomUUID();
-    String fileName = System.getProperty("java.io.tmpdir") +
-            File.pathSeparator +
-            "ambari." + uuid;
-
-    // TODO: add ciphers
-    List<String> command = new ArrayList<>();
-    command.add(executableIpaGetKeytab);
-    command.add("-s");
-    command.add(getAdminServerHost());
-    command.add("-p");
-    command.add(principal);
-    command.add("-k");
-    command.add(fileName);
-
-    // TODO: is it really required to set the password?
-    ShellCommandUtil.Result result = executeCommand(command.toArray(new String[command.size()]));
-    if (!result.isSuccessful()) {
-      String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
-              principal, result.getExitCode(), result.getStdout(), result.getStderr());
-      LOG.warn(message);
-      throw new KerberosOperationException(message);
-    }
-
-    File keytabFile = new File(fileName);
-    Keytab keytab = readKeytabFile(keytabFile);
-    keytabFile.delete();
-
-    cachedKeytabs.put(principal, keytab);
-    return keytab;
-  }
-
-
-  /**
-   * Credentials context executes commands wrapped with kerberos credentials
-   */
-  class CredentialsContext {
-    private PrincipalKeyCredential credentials;
-    Map<String, String> env = new HashMap<>();
-    private String fileName;
-    private List<Process> processes = new ArrayList<>();
-
-    public CredentialsContext(PrincipalKeyCredential credentials) throws KerberosOperationException {
-      this.credentials = credentials;
-
-      UUID uuid = UUID.randomUUID();
-      fileName = System.getProperty("java.io.tmpdir") +
-              File.pathSeparator +
-              "krb5cc_" + uuid;
-      env.put("KRB5CCNAME", String.format("FILE:%s", fileName));
-
-      init(credentials, fileName);
-    }
-
-    protected ShellCommandUtil.Result executeCommand(String[] command)
-            throws KerberosOperationException {
-
-      if ((command == null) || (command.length == 0)) {
-        return null;
-      } else {
-        try {
-          return ShellCommandUtil.runCommand(command, env);
-        } catch (IOException e) {
-          String message = String.format("Failed to execute the command: %s", e.getLocalizedMessage());
-          LOG.error(message, e);
-          throw new KerberosOperationException(message, e);
-        } catch (InterruptedException e) {
-          String message = String.format("Failed to wait for the command to complete: %s", e.getLocalizedMessage());
-          LOG.error(message, e);
-          throw new KerberosOperationException(message, e);
-        }
-      }
-    }
-
-    /**
-     * Does a kinit to obtain a ticket for the specified principal and stores it in the specified cache
-     *
-     * @param credentials Credentials to be used to obtain the ticket
-     * @param fileName    Filename where to store the credentials
-     * @throws KerberosOperationException In case the ticket cannot be obtained
-     */
-    private void init(PrincipalKeyCredential credentials, String fileName) throws KerberosOperationException {
-      Process process;
-      BufferedReader reader = null;
-      OutputStreamWriter osw = null;
-
-      LOG.debug("Entering doKinit");
-      try {
-        String credentialsCache = String.format("FILE:%s", fileName);
-
-        LOG.debug("start subprocess {} {}", executableKinit, credentials.getPrincipal());
-        process = Runtime.getRuntime().exec(new String[]{executableKinit, "-c", credentialsCache, credentials.getPrincipal()});
-        reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
-        osw = new OutputStreamWriter(process.getOutputStream());
-
-        char[] data = new char[1024];
-        StringBuilder sb = new StringBuilder();
-
-        int count = 0;
-        while (!reader.ready()) {
-          Thread.sleep(1000L);
-          if (count >= 5) {
-            process.destroy();
-            throw new KerberosOperationException("No answer from kinit");
-          }
-          count++;
-        }
-
-        while (reader.ready()) {
-          reader.read(data);
-          sb.append(data);
-        }
-
-        String line = sb.toString();
-        LOG.debug("Reading a line: {}", line);
-        if (!line.startsWith("Password")) {
-          throw new KerberosOperationException("Unexpected response from kinit while trying to get ticket for "
-                  + credentials.getPrincipal() + " got: " + line);
-        }
-        osw.write(credentials.getKey());
-        osw.write('\n');
-        osw.close();
-
-        process.waitFor();
-
-        LOG.debug("done subprocess");
-      } catch (IOException | InterruptedException e) {
-        String message = String.format("Failed to execute the command: %s", e.getLocalizedMessage());
-        LOG.error(message, e);
-        throw new KerberosOperationException(message, e);
-      } finally {
-        Closeables.closeSilently(osw);
-        Closeables.closeSilently(reader);
-      }
-
-      if (process.exitValue() != 0) {
-        throw new KerberosOperationException("kinit failed for " + credentials.getPrincipal() + ". Wrong password?");
-      }
-
-    }
-
-    public Process exec(String[] args) throws IOException {
-      Process process = Runtime.getRuntime().exec(args);
-      processes.add(process);
-
-      return process;
-    }
-
-    public void delete() {
-      File ccache = new File(fileName);
-      ccache.delete();
-      for (Process p : processes) {
-        p.destroy();
-      }
+      LOG.error("Failed to execute the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+          StringUtils.join(command, " "), result.getStdout(), result.getStderr());
     }
 
+    return result;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
new file mode 100644
index 0000000..e5696cd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
@@ -0,0 +1,391 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.serveraction.kerberos;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
+import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.collections.MapUtils;
+import org.apache.directory.server.kerberos.shared.keytab.Keytab;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * KDCKerberosOperationHandler is an implementation of a KerberosOperationHandler providing
+ * functionality KDC-based Kerberos providers.
+ * <p>
+ * This implementation provides kinit functionality and keytab file caching utilities for classes.
+ */
+abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
+  private static Logger LOG = LoggerFactory.getLogger(KDCKerberosOperationHandler.class);
+
+  /**
+   * The FQDN of the host where KDC administration server is
+   */
+  private String adminServerHost = null;
+
+  /**
+   * A map of principal names to {@link Keytab} entries to ensure a Keyab file is not created/exported
+   * for the same principal more than once.
+   */
+  private HashMap<String, Keytab> cachedKeytabs = null;
+
+  /**
+   * A String containing the resolved path to the kinit executable
+   */
+  private String executableKinit = null;
+
+  /**
+   * The absolute path to the KDC administrator's Kerberos ticket cache.
+   * <p>
+   * This path is created as as temporary file with a randomized name when this {@link KerberosOperationHandler}
+   * is open.  It is destoryed when this {@link KerberosOperationHandler} is closed.
+   */
+  private File credentialsCacheFile = null;
+
+  /**
+   * A Map of environmet values to send to system command invocations.
+   * <p>
+   * This map is to be appened to any map of environment values passed in when
+   * invoking {@link KerberosOperationHandler#executeCommand(String[], Map, ShellCommandUtil.InteractiveHandler)}
+   */
+  private Map<String, String> environmentMap = null;
+
+  @Override
+  public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
+      throws KerberosOperationException {
+
+    super.open(administratorCredentials, realm, kerberosConfiguration);
+
+    if (kerberosConfiguration != null) {
+      adminServerHost = kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST);
+    }
+
+    // Pre-determine the paths to relevant Kerberos executables
+    executableKinit = getExecutable("kinit");
+
+    setOpen(init());
+  }
+
+  @Override
+  public void close() throws KerberosOperationException {
+
+    if (credentialsCacheFile != null) {
+      if (credentialsCacheFile.delete()) {
+        LOG.debug("Failed to remove the cache file, {}", credentialsCacheFile.getAbsolutePath());
+      }
+      credentialsCacheFile = null;
+    }
+
+    environmentMap = null;
+    executableKinit = null;
+    cachedKeytabs = null;
+    adminServerHost = null;
+
+    super.close();
+  }
+
+  /**
+   * Updates the password for an existing user principal in a previously configured IPA KDC
+   * <p/>
+   * This implementation creates a query to send to the ipa shell command and then interrogates
+   * the exit code to determine if the operation executed successfully.
+   *
+   * @param principal a String containing the principal to update
+   * @param password  a String containing the password to set
+   * @param service   a boolean value indicating whether the principal is for a service or not
+   * @return an Integer declaring the new key number
+   * @throws KerberosOperationException if an unexpected error occurred
+   */
+  @Override
+  public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
+    if (!isOpen()) {
+      throw new KerberosOperationException("This operation handler has not been opened");
+    }
+
+    // It is expected that KerberosPrincipalDoesNotExistException is thrown if the principal does not exist.
+    // The caller expects so that it can attempt to set the password for a principal without checking
+    // to see if it exists first. If the principal does not exist and is required, the caller will
+    // create it.  This saves a potentially unnecessary round trip to the KDC and back.
+    if(!principalExists(principal, service)) {
+      throw new KerberosPrincipalDoesNotExistException(String.format("Principal does not exist while attempting to set its password: %s", principal));
+    }
+
+    // This operation does nothing since a new key will be created when exporting the keytab file...
+    return 0;
+  }
+
+  /**
+   * Creates a key tab by using the ipa commandline utilities. It ignores key number and password
+   * as this will be handled by IPA
+   *
+   * @param principal a String containing the principal to test
+   * @param password  (IGNORED) a String containing the password to use when creating the principal
+   * @param keyNumber (IGNORED) a Integer indicating the key number for the keytab entries
+   * @return the created Keytab
+   * @throws KerberosOperationException
+   */
+  @Override
+  protected Keytab createKeytab(String principal, String password, Integer keyNumber)
+      throws KerberosOperationException {
+
+    if ((principal == null) || principal.isEmpty()) {
+      throw new KerberosOperationException("Failed to create keytab file, missing principal");
+    }
+
+    // use cache if available
+    if (cachedKeytabs.containsKey(principal)) {
+      return cachedKeytabs.get(principal);
+    }
+
+    File keytabFile = null;
+
+    try {
+      try {
+        keytabFile = File.createTempFile("ambari_tmp", ".keytab");
+
+        // Remove the file else the command will fail...
+        if (!keytabFile.delete()) {
+          LOG.warn("Failed to remove temporary file to hold keytab.  Exporting the keytab file for {} may fail.", principal);
+        }
+      } catch (IOException e) {
+        throw new KerberosOperationException(String.format("Failed to create the temporary file needed to hold the exported keytab file for %s: %s", principal, e.getLocalizedMessage()), e);
+      }
+
+
+      exportKeytabFile(principal, keytabFile.getAbsolutePath(), getKeyEncryptionTypes());
+
+      Keytab keytab = readKeytabFile(keytabFile);
+      cachedKeytabs.put(principal, keytab);
+      return keytab;
+    } finally {
+      if ((keytabFile != null) && keytabFile.exists()) {
+        if (!keytabFile.delete()) {
+          LOG.debug("Failed to remove the temporary keytab file, {}", keytabFile.getAbsolutePath());
+        }
+      }
+    }
+  }
+
+  /**
+   * Executes a shell command in a credentials context
+   * <p/>
+   * See {@link ShellCommandUtil#runCommand(String[])}
+   * <p>
+   * This implementation sets the proper environment for the custom <code>KRB5CCNAME </code> value.
+   *
+   * @param command            an array of String value representing the command and its arguments
+   * @param envp               a map of string, string of environment variables
+   * @param interactiveHandler a handler to provide responses to queries from the command,
+   *                           or null if no queries are expected
+   * @return a ShellCommandUtil.Result declaring the result of the operation
+   * @throws KerberosOperationException
+   */
+  @Override
+  protected ShellCommandUtil.Result executeCommand(String[] command, Map<String, String> envp, ShellCommandUtil.InteractiveHandler interactiveHandler)
+      throws KerberosOperationException {
+
+    Map<String, String> _envp;
+
+    if (MapUtils.isEmpty(environmentMap)) {
+      _envp = envp;
+    } else if (MapUtils.isEmpty(envp)) {
+      _envp = environmentMap;
+    } else {
+      _envp = new HashMap<>();
+      _envp.putAll(envp);
+      _envp.putAll(environmentMap);
+    }
+
+    return super.executeCommand(command, _envp, interactiveHandler);
+  }
+
+  String getAdminServerHost() {
+    return adminServerHost;
+  }
+
+  String getCredentialCacheFilePath() {
+    return (credentialsCacheFile == null) ? null : credentialsCacheFile.getAbsolutePath();
+  }
+
+  /**
+   * Return an array of Strings containing the command and the relavant arguments needed authenticate
+   * with the KDC and create the Kerberos ticket/credential cache.
+   *
+   * @param executableKinit  the absolute path to the kinit executable
+   * @param credentials      the KDC adminisrator's credentials
+   * @param credentialsCache the absolute path to the expected location of the Kerberos ticket/credential cache file
+   * @return an array of Strings containing the command to execute
+   */
+  protected abstract String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache);
+
+  /**
+   * Export the requested keytab entries for a given principal into the specified file.
+   *
+   * @param principal                 the principal name
+   * @param keytabFileDestinationPath the absolute path to the keytab file
+   * @param keyEncryptionTypes        a collection of encrption algorithm types indicating which ketyab entries are requested
+   * @throws KerberosOperationException
+   */
+  protected abstract void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException;
+
+  /**
+   * Initialize the Kerberos ticket cache using the supplied KDC administrator's credentials.
+   * <p>
+   * A randomly named temporary file is created to store the Kerberos ticket cache for this {@link KerberosOperationHandler}'s
+   * session. The file will be removed upon closing when the session is complete.  The geneated ticket cache
+   * filename is set in the environment variable map using the variable name "KRB5CCNAME". This will be passed
+   * in for all relevant-system commands.
+   *
+   * @return
+   * @throws KerberosOperationException
+   */
+  protected boolean init() throws KerberosOperationException {
+    if (credentialsCacheFile != null) {
+      if (!credentialsCacheFile.delete()) {
+        LOG.debug("Failed to remove the orphaned cache file, {}", credentialsCacheFile.getAbsolutePath());
+      }
+      credentialsCacheFile = null;
+    }
+
+    try {
+      credentialsCacheFile = File.createTempFile("ambari_krb_", "cc");
+      credentialsCacheFile.deleteOnExit();
+      ensureAmbariOnlyAccess(credentialsCacheFile);
+    } catch (IOException e) {
+      throw new KerberosOperationException(String.format("Failed to create the temporary file needed to hold the administrator ticket cache: %s", e.getLocalizedMessage()), e);
+    }
+
+    String credentialsCache = String.format("FILE:%s", credentialsCacheFile.getAbsolutePath());
+
+    environmentMap = new HashMap<>();
+    environmentMap.put("KRB5CCNAME", credentialsCache);
+
+    PrincipalKeyCredential credentials = getAdministratorCredential();
+
+    ShellCommandUtil.Result result = executeCommand(getKinitCommand(executableKinit, credentials, credentialsCache),
+        environmentMap,
+        new InteractivePasswordHandler(String.valueOf(credentials.getKey()), null));
+
+    if (!result.isSuccessful()) {
+      String message = String.format("Failed to kinit as the KDC administrator user, %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+          credentials.getPrincipal(), result.getExitCode(), result.getStdout(), result.getStderr());
+      LOG.warn(message);
+      throw new KerberosAdminAuthenticationException(message);
+    }
+
+    cachedKeytabs = new HashMap<>();
+
+    return true;
+  }
+
+  /**
+   * Ensures that the owner of the Ambari server process is the only local user account able to
+   * read and write to the specified file or read, write to, and execute the specified directory.
+   *
+   * @param file the file or directory for which to modify access
+   */
+  private void ensureAmbariOnlyAccess(File file) throws AmbariException {
+    if (file.exists()) {
+      if (!file.setReadable(false, false) || !file.setReadable(true, true)) {
+        String message = String.format("Failed to set %s readable only by Ambari", file.getAbsolutePath());
+        LOG.warn(message);
+        throw new AmbariException(message);
+      }
+
+      if (!file.setWritable(false, false) || !file.setWritable(true, true)) {
+        String message = String.format("Failed to set %s writable only by Ambari", file.getAbsolutePath());
+        LOG.warn(message);
+        throw new AmbariException(message);
+      }
+
+      if (file.isDirectory()) {
+        if (!file.setExecutable(false, false) || !file.setExecutable(true, true)) {
+          String message = String.format("Failed to set %s executable by Ambari", file.getAbsolutePath());
+          LOG.warn(message);
+          throw new AmbariException(message);
+        }
+      } else {
+        if (!file.setExecutable(false, false)) {
+          String message = String.format("Failed to set %s not executable", file.getAbsolutePath());
+          LOG.warn(message);
+          throw new AmbariException(message);
+        }
+      }
+    }
+  }
+
+  /**
+   * InteractivePasswordHandler is a {@link ShellCommandUtil.InteractiveHandler}
+   * implementation that answers queries from kadmin or kdamin.local command for the admin and/or user
+   * passwords.
+   */
+  protected static class InteractivePasswordHandler implements ShellCommandUtil.InteractiveHandler {
+    /**
+     * The queue of responses to return
+     */
+    private LinkedList<String> responses;
+    private Queue<String> currentResponses;
+
+    /**
+     * Constructor.
+     *
+     * @param adminPassword the KDC administrator's password (optional)
+     * @param userPassword  the user's password (optional)
+     */
+    InteractivePasswordHandler(String adminPassword, String userPassword) {
+      responses = new LinkedList<>();
+
+      if (adminPassword != null) {
+        responses.offer(adminPassword);
+      }
+
+      if (userPassword != null) {
+        responses.offer(userPassword);
+        responses.offer(userPassword);  // Add a 2nd time for the password "confirmation" request
+      }
+
+      currentResponses = new LinkedList<>(responses);
+    }
+
+    @Override
+    public boolean done() {
+      return currentResponses.size() == 0;
+    }
+
+    @Override
+    public String getResponse(String query) {
+      return currentResponses.poll();
+    }
+
+    @Override
+    public void start() {
+      currentResponses = new LinkedList<>(responses);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
index 8749f81..948fd60 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
@@ -67,22 +67,7 @@ public abstract class KerberosOperationHandler {
   /**
    * Kerberos-env configuration property name: group
    */
-  public final static String KERBEROS_ENV_USER_PRINCIPAL_GROUP = "group";
-
-  /**
-   * Kerberos-env configuration property name: password_chat_timeout
-   */
-  public final static String KERBEROS_ENV_PASSWORD_CHAT_TIMEOUT = "password_chat_timeout";
-
-  /**
-   * Default timeout for password chat
-   */
-  public final static int DEFAULT_PASSWORD_CHAT_TIMEOUT = 5;
-
-  /**
-   * Kerberos-env configuration property name: set_password_expiry
-   */
-  public final static String KERBEROS_ENV_SET_PASSWORD_EXPIRY = "set_password_expiry";
+  public final static String KERBEROS_ENV_USER_PRINCIPAL_GROUP = "ipa_user_group";
 
   /**
    * Kerberos-env configuration property name: ad_create_attributes_template
@@ -232,16 +217,26 @@ public abstract class KerberosOperationHandler {
    * @param defaultRealm            a String declaring the default Kerberos realm (or domain)
    * @param kerberosConfiguration   a Map of key/value pairs containing data from the kerberos-env configuration set
    */
-  public abstract void open(PrincipalKeyCredential administratorCredential, String defaultRealm, Map<String, String> kerberosConfiguration)
-      throws KerberosOperationException;
+  public void open(PrincipalKeyCredential administratorCredential, String defaultRealm, Map<String, String> kerberosConfiguration)
+      throws KerberosOperationException {
+
+    setAdministratorCredential(administratorCredential);
+    setDefaultRealm(defaultRealm);
+
+    if (kerberosConfiguration != null) {
+      setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
+      setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
+    }
+  }
 
   /**
    * Closes and cleans up any resources used by this KerberosOperationHandler
    * <p/>
    * It is expected that this KerberosOperationHandler will not be used after this call.
    */
-  public abstract void close()
-      throws KerberosOperationException;
+  public void close() throws KerberosOperationException {
+    setOpen(false);
+  }
 
   /**
    * Test to see if the specified principal exists in a previously configured KDC
@@ -249,10 +244,11 @@ public abstract class KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to test
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal exists; false otherwise
    * @throws KerberosOperationException
    */
-  public abstract boolean principalExists(String principal)
+  public abstract boolean principalExists(String principal, boolean service)
       throws KerberosOperationException;
 
   /**
@@ -277,11 +273,12 @@ public abstract class KerberosOperationHandler {
    *
    * @param principal a String containing the principal to update
    * @param password  a String containing the password to set
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return an Integer declaring the new key number
    * @throws KerberosOperationException
    * @throws KerberosPrincipalDoesNotExistException if the principal does not exist
    */
-  public abstract Integer setPrincipalPassword(String principal, String password)
+  public abstract Integer setPrincipalPassword(String principal, String password, boolean service)
       throws KerberosOperationException;
 
   /**
@@ -290,10 +287,11 @@ public abstract class KerberosOperationHandler {
    * The implementation is specific to a particular type of KDC.
    *
    * @param principal a String containing the principal to remove
+   * @param service   a boolean value indicating whether the principal is for a service or not
    * @return true if the principal was successfully removed; otherwise false
    * @throws KerberosOperationException
    */
-  public abstract boolean removePrincipal(String principal)
+  public abstract boolean removePrincipal(String principal, boolean service)
       throws KerberosOperationException;
 
   /**
@@ -313,7 +311,7 @@ public abstract class KerberosOperationHandler {
     if (credential == null) {
       throw new KerberosOperationException("Missing KDC administrator credential");
     } else {
-      return principalExists(credential.getPrincipal());
+      return principalExists(credential.getPrincipal(), false);
     }
   }
 
@@ -568,11 +566,11 @@ public abstract class KerberosOperationHandler {
    * @param keyEncryptionTypes a Set of EncryptionKey values or null to indicate the default set
    */
   public void setKeyEncryptionTypes(Set<EncryptionType> keyEncryptionTypes) {
-    this.keyEncryptionTypes = new HashSet<>(
-      (keyEncryptionTypes == null)
-        ? DEFAULT_CIPHERS
-        : keyEncryptionTypes
-    );
+    this.keyEncryptionTypes = Collections.unmodifiableSet(new HashSet<>(
+        (keyEncryptionTypes == null)
+            ? DEFAULT_CIPHERS
+            : keyEncryptionTypes
+    ));
   }
 
 
@@ -713,8 +711,8 @@ public abstract class KerberosOperationHandler {
    * <p/>
    * See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[], Map<String,String>)}
    *
-   * @param command an array of String value representing the command and its arguments
-   * @param envp a map of string, string of environment variables
+   * @param command            an array of String value representing the command and its arguments
+   * @param envp               a map of string, string of environment variables
    * @param interactiveHandler a handler to provide responses to queries from the command,
    *                           or null if no queries are expected
    * @return a ShellCommandUtil.Result declaring the result of the operation
@@ -751,7 +749,7 @@ public abstract class KerberosOperationHandler {
    * @see #executeCommand(String[], Map, ShellCommandUtil.InteractiveHandler)
    */
   protected ShellCommandUtil.Result executeCommand(String[] command)
-          throws KerberosOperationException {
+      throws KerberosOperationException {
     return executeCommand(command, null);
   }
 
@@ -760,7 +758,7 @@ public abstract class KerberosOperationHandler {
    * <p/>
    * See {@link org.apache.ambari.server.utils.ShellCommandUtil#runCommand(String[])}
    *
-   * @param command an array of String value representing the command and its arguments
+   * @param command            an array of String value representing the command and its arguments
    * @param interactiveHandler a handler to provide responses to queries from the command,
    *                           or null if no queries are expected
    * @return a ShellCommandUtil.Result declaring the result of the operation


[25/51] [abbrv] ambari git commit: AMBARI-22377 Ambari 3.0: Implement new design for Admin View: Views page. (atkach)

Posted by nc...@apache.org.
AMBARI-22377 Ambari 3.0: Implement new design for Admin View: Views page. (atkach)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: dd0421a214f2f9b6c2546bad6d2bc5d743094a40
Parents: 654404d
Author: Andrii Tkach <at...@apache.org>
Authored: Tue Nov 7 18:17:20 2017 +0200
Committer: Andrii Tkach <at...@apache.org>
Committed: Tue Nov 7 19:52:10 2017 +0200

----------------------------------------------------------------------
 .../main/resources/ui/admin-web/app/index.html  |   1 +
 .../ambariViews/CloneViewInstanceCtrl.js        | 274 ++++++++++++++
 .../ambariViews/CreateViewInstanceCtrl.js       | 353 +++++++-----------
 .../controllers/ambariViews/ViewsListCtrl.js    | 360 +++++++------------
 .../ui/admin-web/app/scripts/i18n.config.js     |  14 +-
 .../ui/admin-web/app/scripts/routes.js          |  34 +-
 .../ui/admin-web/app/scripts/services/View.js   |  32 +-
 .../resources/ui/admin-web/app/styles/main.css  |  45 ++-
 .../resources/ui/admin-web/app/styles/views.css |  49 +++
 .../app/views/ambariViews/listTable.html        | 110 ------
 .../app/views/ambariViews/listUrls.html         | 117 ------
 .../app/views/ambariViews/modals/create.html    | 238 +++++++-----
 .../app/views/ambariViews/modals/edit.html      | 138 -------
 .../app/views/ambariViews/viewsList.html        | 134 +++++++
 .../ui/admin-web/app/views/urls/create.html     |   4 +-
 .../ui/admin-web/app/views/urls/edit.html       |   4 +-
 .../unit/controllers/CloneViewInstanceCtrl.js   | 135 +++++++
 .../unit/controllers/CreateViewInstanceCtrl.js  | 135 -------
 18 files changed, 1050 insertions(+), 1127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/index.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
index e9983aa..41cc60f 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html
@@ -139,6 +139,7 @@
 <script src="scripts/controllers/ambariViews/ViewUrlCtrl.js"></script>
 <script src="scripts/controllers/ambariViews/ViewUrlEditCtrl.js"></script>
 <script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script>
+<script src="scripts/controllers/ambariViews/CloneViewInstanceCtrl.js"></script>
 <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script>
 <script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script>
 <script src="scripts/controllers/clusters/ExportBlueprintCtrl.js"></script>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
new file mode 100644
index 0000000..cb37e63
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CloneViewInstanceCtrl.js
@@ -0,0 +1,274 @@
+/**
+ * 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.controller('CloneViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) {
+  var $t = $translate.instant;
+  $scope.form = {};
+  $scope.constants = {
+    props: $t('views.properties')
+  };
+  $scope.isClone = $routeParams.instanceId ? true : false;
+  var targetUrl = '';
+
+  function loadMeta(){
+    View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
+      var viewVersion = data.data,
+        parameters;
+
+      $scope.view = viewVersion;
+      parameters = viewVersion.ViewVersionInfo.parameters;
+
+      angular.forEach(parameters, function (item) {
+        item.value = item['defaultValue'];
+        item.clusterConfig = !!item.clusterConfig;
+        item.displayName = item.name.replace(/\./g, '\.\u200B');
+        item.clusterConfig ? $scope.numberOfClusterConfigs++ : $scope.numberOfSettingConfigs++;
+      });
+
+      $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
+      $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : $t('views.alerts.cannotUseOption');
+
+      $scope.instance = {
+        view_name: viewVersion.ViewVersionInfo.view_name,
+        version: viewVersion.ViewVersionInfo.version,
+        instance_name: '',
+        label: '',
+        visible: true,
+        icon_path: '',
+        icon64_path: '',
+        properties: parameters,
+        description: '',
+        clusterType: 'NONE'
+      };
+
+      //if cloning view instance, then get the instance data and populate settings and properties
+      if($scope.isClone) {
+        View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
+          .then(function(instance) {
+            $scope.instanceClone = instance;
+            $scope.instance.version = instance.ViewInstanceInfo.version;
+            $scope.version =  instance.ViewInstanceInfo.version;
+            $scope.instance.instance_name = instance.ViewInstanceInfo.instance_name + $t('common.copy');
+            $scope.instance.label = instance.ViewInstanceInfo.label + $t('common.copy');
+            $scope.instance.visible = instance.ViewInstanceInfo.visible;
+            $scope.instance.description = instance.ViewInstanceInfo.description;
+            $scope.instance.clusterType=instance.ViewInstanceInfo.cluster_type;
+
+            initConfigurations(parameters);
+          })
+          .catch(function(data) {
+            Alert.error($t('views.alerts.cannotLoadInstanceInfo'), data.data.message);
+          });
+      }
+
+      loadClusters();
+      loadRemoteClusters();
+
+    });
+  }
+
+  function initConfigurations(parameters) {
+    var configuration = angular.copy($scope.instanceClone.ViewInstanceInfo.properties);
+
+    //iterate through the view parameters and get the values from the instance being cloned
+    for (var i = 0; i < parameters.length; i++) {
+      parameters[i].value = configuration[parameters[i].name];
+      parameters[i].clusterConfig = !!parameters[i].clusterConfig;
+    }
+  }
+
+  $scope.$watch(function(scope) {
+    return scope.version;
+  }, function(version) {
+    if( version ){
+      loadMeta();
+    }
+  });
+
+  $scope.enableLocalCluster = function () {
+    if($scope.errorKeys.length > 0) {
+      $scope.errorKeys.forEach( function (key) {
+        try {
+          $scope.form.instanceCreateForm[key].validationError = false;
+          $scope.form.instanceCreateForm[key].validationMessage = '';
+        } catch (e) {
+          console.log($t('views.alerts.unableToResetErrorMessage', {key: key}));
+        }
+      });
+      $scope.errorKeys = [];
+    }
+  };
+
+  // $scope.view = viewVersion;
+  $scope.isAdvancedClosed = true;
+  $scope.instanceExists = false;
+  $scope.errorKeys = [];
+
+  $scope.clusterConfigurable = false;
+  $scope.clusterConfigurableErrorMsg = "";
+  $scope.clusters = [];
+  $scope.remoteClusters = [];
+  $scope.noLocalClusterAvailible = true;
+  $scope.noRemoteClusterAvailible = true;
+  $scope.cluster = null;
+  $scope.data = {};
+  $scope.data.remoteCluster = null;
+  $scope.numberOfClusterConfigs = 0;
+  $scope.numberOfSettingConfigs = 0;
+
+  function loadClusters() {
+    Cluster.getAllClusters().then(function (clusters) {
+      if(clusters.length >0){
+        clusters.forEach(function(cluster) {
+          $scope.clusters.push({
+            "name" : cluster.Clusters.cluster_name,
+            "id" : cluster.Clusters.cluster_id
+          })
+        });
+        $scope.noLocalClusterAvailible = false;
+        //do not set to default Local Cluster configuration when cloning instance
+        if($scope.clusterConfigurable && !$scope.isClone){
+          $scope.instance.clusterType = "LOCAL_AMBARI";
+        }
+      }else{
+        $scope.clusters.push($t('common.noClusters'));
+      }
+      $scope.cluster = $scope.clusters[0];
+    });
+  }
+
+  function loadRemoteClusters() {
+    RemoteCluster.listAll().then(function (clusters) {
+      if(clusters.length >0){
+        clusters.forEach(function(cluster) {
+          $scope.remoteClusters.push({
+            "name" : cluster.ClusterInfo.name,
+            "id" : cluster.ClusterInfo.cluster_id
+          })
+        });
+        $scope.noRemoteClusterAvailible = false;
+      }else{
+        $scope.remoteClusters.push($t('common.noClusters'));
+      }
+      $scope.data.remoteCluster = $scope.remoteClusters[0];
+    });
+  }
+
+
+  $scope.versions = [];
+  $scope.version = null;
+
+  View.getVersions($routeParams.viewId).then(function(versions) {
+    $scope.versions = versions;
+    $scope.version = $scope.versions[$scope.versions.length-1];
+  });
+
+
+  $scope.nameValidationPattern = /^\s*\w*\s*$/;
+
+  $scope.save = function() {
+    if (!$scope.form.instanceCreateForm.isSaving) {
+      $scope.form.instanceCreateForm.submitted = true;
+      if($scope.form.instanceCreateForm.$valid){
+        $scope.form.instanceCreateForm.isSaving = true;
+
+        switch($scope.instance.clusterType) {
+          case 'LOCAL_AMBARI':
+            console.log($scope.cluster);
+            $scope.instance.clusterId = $scope.cluster.id;
+            break;
+          case 'REMOTE_AMBARI':
+            console.log($scope.data.remoteCluster);
+            $scope.instance.clusterId = $scope.data.remoteCluster.id;
+
+            break;
+          default:
+            $scope.instance.clusterId = null;
+        }
+        console.log($scope.instance.clusterId);
+        View.createInstance($scope.instance)
+          .then(function(data) {
+            Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name}));
+            $scope.form.instanceCreateForm.$setPristine();
+            if( targetUrl ){
+              $location.path(targetUrl);
+            } else {
+              $location.path('/views/' + $scope.instance.view_name + '/versions/' + $scope.instance.version + '/instances/' + $scope.instance.instance_name + '/edit');
+            }
+            $scope.form.instanceCreateForm.isSaving = false;
+            $scope.$root.$emit('instancesUpdate');
+          })
+          .catch(function (data) {
+            var errorMessage = data.message;
+            var showGeneralError = true;
+
+            if (data.status >= 400 && $scope.instance.clusterType == 'NONE') {
+              try {
+                var errorObject = JSON.parse(errorMessage);
+                errorMessage = errorObject.detail;
+                angular.forEach(errorObject.propertyResults, function (item, key) {
+                  $scope.form.instanceCreateForm[key].validationError = !item.valid;
+                  if (!item.valid) {
+                    showGeneralError = false;
+                    $scope.form.instanceCreateForm[key].validationMessage = item.detail;
+                    $scope.errorKeys.push(key);
+                  }
+                });
+
+                if (showGeneralError) {
+                  $scope.form.instanceCreateForm.generalValidationError = errorMessage;
+                }
+              } catch (e) {
+                console.error($t('views.alerts.unableToParseError', {message: data.message}));
+              }
+            }
+            Alert.error($t('views.alerts.cannotCreateInstance'), errorMessage);
+            $scope.form.instanceCreateForm.isSaving = false;
+          });
+      }
+    }
+  };
+
+  $scope.cancel = function() {
+    $scope.form.instanceCreateForm.$setPristine();
+    $location.path('/views');
+  };
+
+  $scope.$on('$locationChangeStart', function(event, __targetUrl) {
+    if( $scope.form.instanceCreateForm.$dirty ){
+      UnsavedDialog().then(function(action) {
+        targetUrl = __targetUrl.split('#').pop();
+        switch(action){
+          case 'save':
+            $scope.save();
+            break;
+          case 'discard':
+            $scope.form.instanceCreateForm.$setPristine();
+            $location.path(targetUrl);
+            break;
+          case 'cancel':
+            targetUrl = '';
+            break;
+        }
+      });
+      event.preventDefault();
+    }
+  });
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
index 94b8cc1..d5e3758 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js
@@ -18,263 +18,170 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('CreateViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) {
+.controller('CreateViewInstanceCtrl',
+['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', '$modalInstance', 'views', '$q',
+function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate, $modalInstance, views, $q) {
+
   var $t = $translate.instant;
+  var viewToVersionMap = {};
+  var instances = {};
   $scope.form = {};
-  $scope.constants = {
-    props: $t('views.properties')
+  $scope.nameValidationPattern = /^\s*\w*\s*$/;
+  $scope.isLoading = false;
+  $scope.isLocalTypeChosen = true;
+  $scope.views = views;
+  $scope.viewOptions = [];
+  $scope.versionOptions = [];
+  $scope.localClusters = [];
+  $scope.remoteClusters = [];
+  $scope.clusterOptions = [];
+  $scope.isInstanceExists = false;
+  $scope.formData = {
+    view: null,
+    version: null,
+    instanceName: '',
+    displayName: '',
+    description: '',
+    clusterName: null,
+    visible: true
   };
-  $scope.isClone = $routeParams.instanceId ? true : false;
-  var targetUrl = '';
-
-  function loadMeta(){
-    View.getMeta($routeParams.viewId, $scope.version).then(function(data) {
-      var viewVersion = data.data,
-        parameters;
-
-      $scope.view = viewVersion;
-      parameters = viewVersion.ViewVersionInfo.parameters;
-
-      angular.forEach(parameters, function (item) {
-        item.value = item['defaultValue'];
-        item.clusterConfig = !!item.clusterConfig;
-        item.displayName = item.name.replace(/\./g, '\.\u200B');
-        item.clusterConfig ? $scope.numberOfClusterConfigs++ : $scope.numberOfSettingConfigs++;
-      });
-
-      $scope.clusterConfigurable = viewVersion.ViewVersionInfo.cluster_configurable;
-      $scope.clusterConfigurableErrorMsg = $scope.clusterConfigurable ? "" : $t('views.alerts.cannotUseOption');
-
-      $scope.instance = {
-        view_name: viewVersion.ViewVersionInfo.view_name,
-        version: viewVersion.ViewVersionInfo.version,
-        instance_name: '',
-        label: '',
-        visible: true,
-        icon_path: '',
-        icon64_path: '',
-        properties: parameters,
-        description: '',
-        clusterType: 'NONE'
-      };
-
-      //if cloning view instance, then get the instance data and populate settings and properties
-      if($scope.isClone) {
-        View.getInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId)
-        .then(function(instance) {
-          $scope.instanceClone = instance;
-          $scope.instance.version = instance.ViewInstanceInfo.version;
-          $scope.version =  instance.ViewInstanceInfo.version;
-          $scope.instance.instance_name = instance.ViewInstanceInfo.instance_name + $t('common.copy');
-          $scope.instance.label = instance.ViewInstanceInfo.label + $t('common.copy');
-          $scope.instance.visible = instance.ViewInstanceInfo.visible;
-          $scope.instance.description = instance.ViewInstanceInfo.description;
-          $scope.instance.clusterType=instance.ViewInstanceInfo.cluster_type;
-          
-          initConfigurations(parameters);
-        })
-        .catch(function(data) {
-          Alert.error($t('views.alerts.cannotLoadInstanceInfo'), data.data.message);
-        });
-      }
-
-      loadClusters();
-      loadRemoteClusters();
-
-    });
-  }
 
-   function initConfigurations(parameters) {
-      var configuration = angular.copy($scope.instanceClone.ViewInstanceInfo.properties);
-
-      //iterate through the view parameters and get the values from the instance being cloned
-      for (var i = 0; i < parameters.length; i++) {
-        parameters[i].value = configuration[parameters[i].name];
-        parameters[i].clusterConfig = !!parameters[i].clusterConfig;
-      }
+  $scope.updateVersionOptions = function () {
+    if (viewToVersionMap[$scope.formData.view.value]) {
+      $scope.versionOptions = viewToVersionMap[$scope.formData.view.value];
+      $scope.formData.version = $scope.versionOptions[0];
     }
+  };
 
-  $scope.$watch(function(scope) {
-    return scope.version;
-  }, function(version) {
-    if( version ){
-      loadMeta();
-    }
-  });
-
-  $scope.enableLocalCluster = function () {
-    if($scope.errorKeys.length > 0) {
-      $scope.errorKeys.forEach( function (key) {
-        try {
-          $scope.form.instanceCreateForm[key].validationError = false;
-          $scope.form.instanceCreateForm[key].validationMessage = '';
-        } catch (e) {
-          console.log($t('views.alerts.unableToResetErrorMessage', {key: key}));
-        }
-      });
-      $scope.errorKeys = [];
+  $scope.switchClusterType = function(bool) {
+    $scope.isLocalTypeChosen = bool;
+    if ($scope.isLocalTypeChosen) {
+      $scope.clusterOptions = $scope.localClusters;
+    } else {
+      $scope.clusterOptions = $scope.remoteClusters;
     }
+    $scope.formData.clusterName = $scope.clusterOptions[0];
   };
 
-  // $scope.view = viewVersion;
-  $scope.isAdvancedClosed = true;
-  $scope.instanceExists = false;
-  $scope.errorKeys = [];
-
-  $scope.clusterConfigurable = false;
-  $scope.clusterConfigurableErrorMsg = "";
-  $scope.clusters = [];
-  $scope.remoteClusters = [];
-  $scope.noLocalClusterAvailible = true;
-  $scope.noRemoteClusterAvailible = true;
-  $scope.cluster = null;
-  $scope.data = {};
-  $scope.data.remoteCluster = null;
-  $scope.numberOfClusterConfigs = 0;
-  $scope.numberOfSettingConfigs = 0;
-
-  function loadClusters() {
-       Cluster.getAllClusters().then(function (clusters) {
-         if(clusters.length >0){
-           clusters.forEach(function(cluster) {
-             $scope.clusters.push({
-              "name" : cluster.Clusters.cluster_name,
-              "id" : cluster.Clusters.cluster_id
-             })
-           });
-           $scope.noLocalClusterAvailible = false;
-           //do not set to default Local Cluster configuration when cloning instance
-           if($scope.clusterConfigurable && !$scope.isClone){
-             $scope.instance.clusterType = "LOCAL_AMBARI";
-           }
-         }else{
-           $scope.clusters.push($t('common.noClusters'));
-         }
-         $scope.cluster = $scope.clusters[0];
-       });
-  }
-
-   function loadRemoteClusters() {
-         RemoteCluster.listAll().then(function (clusters) {
-           if(clusters.length >0){
-             clusters.forEach(function(cluster) {
-               $scope.remoteClusters.push({
-                "name" : cluster.ClusterInfo.name,
-                "id" : cluster.ClusterInfo.cluster_id
-               })
-             });
-             $scope.noRemoteClusterAvailible = false;
-           }else{
-             $scope.remoteClusters.push($t('common.noClusters'));
-           }
-           $scope.data.remoteCluster = $scope.remoteClusters[0];
-         });
-   }
-
-
-  $scope.versions = [];
-  $scope.version = null;
-
-  View.getVersions($routeParams.viewId).then(function(versions) {
-    $scope.versions = versions;
-    $scope.version = $scope.versions[$scope.versions.length-1];
-  });
-
-
-  $scope.nameValidationPattern = /^\s*\w*\s*$/;
-
-  $scope.save = function() {
-  if (!$scope.form.instanceCreateForm.isSaving) {
+  $scope.save = function () {
+    var instanceName = $scope.form.instanceCreateForm.instanceName.$viewValue;
     $scope.form.instanceCreateForm.submitted = true;
-    if($scope.form.instanceCreateForm.$valid){
-      $scope.form.instanceCreateForm.isSaving = true;
-
-      switch($scope.instance.clusterType) {
-        case 'LOCAL_AMBARI':
-          console.log($scope.cluster);
-          $scope.instance.clusterId = $scope.cluster.id;
-          break;
-        case 'REMOTE_AMBARI':
-          console.log($scope.data.remoteCluster);
-          $scope.instance.clusterId = $scope.data.remoteCluster.id;
-
-          break;
-        default:
-          $scope.instance.clusterId = null;
-      }
-      console.log($scope.instance.clusterId);
-      View.createInstance($scope.instance)
-        .then(function(data) {
-          Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name}));
-          $scope.form.instanceCreateForm.$setPristine();
-          if( targetUrl ){
-            $location.path(targetUrl);
-          } else {
-            $location.path('/views/' + $scope.instance.view_name + '/versions/' + $scope.instance.version + '/instances/' + $scope.instance.instance_name + '/edit');
-          }
-            $scope.form.instanceCreateForm.isSaving = false;
-            $scope.$root.$emit('instancesUpdate');
+    if ($scope.form.instanceCreateForm.$valid) {
+      View.createInstance({
+        instance_name: instanceName,
+        label: $scope.form.instanceCreateForm.displayName.$viewValue,
+        visible: $scope.form.instanceCreateForm.visible.$viewValue,
+        icon_path: '',
+        icon64_path: '',
+        description: $scope.form.instanceCreateForm.description.$viewValue,
+        view_name: $scope.form.instanceCreateForm.view.$viewValue.value,
+        version: $scope.form.instanceCreateForm.version.$viewValue.value,
+        properties: [],
+        clusterId: $scope.form.instanceCreateForm.clusterName.$viewValue.id,
+        clusterType: $scope.isLocalTypeChosen ? 'LOCAL_AMBARI': 'REMOTE_AMBARI'
+      })
+        .then(function () {
+          $modalInstance.dismiss('created');
+          Alert.success($t('views.alerts.instanceCreated', {instanceName: instanceName}));
+          $location.path('/views/' + $scope.form.instanceCreateForm.view.$viewValue.value +
+            '/versions/' + $scope.form.instanceCreateForm.version.$viewValue.value +
+            '/instances/' + instanceName + '/edit');
         })
         .catch(function (data) {
           var errorMessage = data.message;
-          var showGeneralError = true;
 
-          if (data.status >= 400 && $scope.instance.clusterType == 'NONE') {
+          if (data.status >= 400) {
             try {
-              var errorObject = JSON.parse(errorMessage);
-              errorMessage = errorObject.detail;
-              angular.forEach(errorObject.propertyResults, function (item, key) {
-                $scope.form.instanceCreateForm[key].validationError = !item.valid;
-                if (!item.valid) {
-                  showGeneralError = false;
-                  $scope.form.instanceCreateForm[key].validationMessage = item.detail;
-                  $scope.errorKeys.push(key);
-                }
-              });
-
-              if (showGeneralError) {
-                $scope.form.instanceCreateForm.generalValidationError = errorMessage;
-              }
+              errorMessage = JSON.parse(errorMessage).detail;
             } catch (e) {
-              console.error($t('views.alerts.unableToParseError', {message: data.message}));
+              console.warn(data.message, e);
             }
           }
           Alert.error($t('views.alerts.cannotCreateInstance'), errorMessage);
-          $scope.form.instanceCreateForm.isSaving = false;
         });
-      }
     }
   };
 
-  $scope.cancel = function() {
-    $scope.form.instanceCreateForm.$setPristine();
-    $location.path('/views');
+  $scope.cancel = function () {
+    unsavedChangesCheck();
+  };
+
+  $scope.checkIfInstanceExist = function() {
+    $scope.isInstanceExists = Boolean(instances[$scope.formData.instanceName]);
   };
 
-  $scope.$on('$locationChangeStart', function(event, __targetUrl) {
-    if( $scope.form.instanceCreateForm.$dirty ){
-      UnsavedDialog().then(function(action) {
-        targetUrl = __targetUrl.split('#').pop();
-        switch(action){
+  function initViewAndVersionSelect () {
+    $scope.viewOptions = [];
+    angular.forEach($scope.views, function(view) {
+      $scope.viewOptions.push({
+        label: view.view_name,
+        value: view.view_name
+      });
+      viewToVersionMap[view.view_name] = view.versionsList.map(function(version) {
+        angular.forEach(version.instances, function(instance) {
+          instances[instance.ViewInstanceInfo.instance_name] = true;
+        });
+        return {
+          label: version.ViewVersionInfo.version,
+          value: version.ViewVersionInfo.version
+        }
+      });
+    });
+    $scope.formData.view = $scope.viewOptions[0];
+    $scope.updateVersionOptions();
+  }
+
+  function loadClusters() {
+    return Cluster.getAllClusters().then(function (clusters) {
+      clusters.forEach(function (cluster) {
+        $scope.localClusters.push({
+          label: cluster.Clusters.cluster_name,
+          value: cluster.Clusters.cluster_name,
+          id: cluster.Clusters.cluster_id
+        });
+      });
+    });
+  }
+
+  function loadRemoteClusters() {
+    return RemoteCluster.listAll().then(function (clusters) {
+      clusters.forEach(function (cluster) {
+        $scope.remoteClusters.push({
+          label: cluster.ClusterInfo.name,
+          value: cluster.ClusterInfo.name,
+          id: cluster.ClusterInfo.cluster_id
+        });
+      });
+    });
+  }
+
+  function loadFormData () {
+    $scope.isLoading = true;
+    initViewAndVersionSelect();
+    $q.all(loadClusters(), loadRemoteClusters()).then(function() {
+      $scope.isLoading = false;
+      $scope.switchClusterType(true);
+    });
+  }
+
+  function unsavedChangesCheck() {
+    if ($scope.form.instanceCreateForm.$dirty) {
+      UnsavedDialog().then(function (action) {
+        switch (action) {
           case 'save':
             $scope.save();
             break;
           case 'discard':
-            $scope.form.instanceCreateForm.$setPristine();
-            $location.path(targetUrl);
+            $modalInstance.close('discard');
             break;
           case 'cancel':
-            targetUrl = '';
             break;
         }
       });
-      event.preventDefault();
+    } else {
+      $modalInstance.close('discard');
     }
-  });
-
-
-
-
-
+  }
 
+  loadFormData();
 }]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
index 4e7bae3..aba5702 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsListCtrl.js
@@ -18,272 +18,186 @@
 'use strict';
 
 angular.module('ambariAdminConsole')
-.controller('ViewsListCtrl',['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$location', '$translate', function($scope, View, $modal, Alert, ConfirmationModal, $location, $translate) {
-  var deferredList = [],
-    $t = $translate.instant;
-  $scope.isLoadingViews = false;
-  $scope.isLoadingUrls = false;
-  $scope.constants = {
-    unable: $t('views.alerts.unableToCreate'),
-    views: $t('common.views').toLowerCase()
-  };
-  $scope.$on('$locationChangeStart', function() {
-    deferredList.forEach(function(def) {
-      def.reject();
-    })
-  });
-
-  $scope.createUrlDisabled = false;
+.controller('ViewsListCtrl',['$scope', 'View','$modal', 'Alert', 'ConfirmationModal', '$translate', function($scope, View, $modal, Alert, ConfirmationModal, $translate) {
+  var $t = $translate.instant;
+  var VIEWS_VERSION_STATUS_TIMEOUT = 5000;
+  $scope.isLoading = false;
+  $scope.minInstanceForPagination = 10;
 
-  function checkViewVersionStatus(view, versionObj, versionNumber){
+  function checkViewVersionStatus(view, versionObj, versionNumber) {
     var deferred = View.checkViewVersionStatus(view.view_name, versionNumber);
-    deferredList.push(deferred);
 
-    deferred.promise.then(function(status) {
-      deferredList.splice(deferredList.indexOf(deferred), 1);
-      if (status !== 'DEPLOYED' && status !== 'ERROR') {
-        checkViewVersionStatus(view, versionObj, versionNumber);
+    deferred.promise.then(function (status) {
+      if (versionNeedStatusUpdate(status)) {
+        setTimeout(function() {
+          checkViewVersionStatus(view, versionObj, versionNumber);
+        }, VIEWS_VERSION_STATUS_TIMEOUT);
       } else {
-        $scope.$evalAsync(function() {
-          versionObj.status = status;
-          angular.forEach(view.versions, function(version) {
-            if(version.status === 'DEPLOYED'){
-              view.canCreateInstance = true;
-            }
-          })
-        });
+        versionObj.status = status;
+        angular.forEach(view.versions, function (version) {
+          if (version.status === 'DEPLOYED') {
+            view.canCreateInstance = true;
+          }
+        })
       }
     });
   }
 
-  function loadViews(){
-    $scope.isLoadingViews = true;
-    View.all().then(function(views) {
-      $scope.isLoadingViews = false;
+  function versionNeedStatusUpdate(status) {
+    return status !== 'DEPLOYED' && status !== 'ERROR';
+  }
+
+  function loadViews() {
+    $scope.isLoading = true;
+    View.all().then(function (views) {
+      $scope.isLoading = false;
       $scope.views = views;
-      $scope.getFilteredViews();
-      angular.forEach(views, function(view) {
-        angular.forEach(view.versions, function(versionObj, versionNumber) {
-          if (versionObj.status !== 'DEPLOYED' || versionObj.status !== 'ERROR'){
-            checkViewVersionStatus(view, versionObj, versionNumber);
-          }
+      $scope.instances = [];
+      angular.forEach(views, function (view) {
+        // TODO uncomment if view need status update
+        // angular.forEach(view.versions, function (versionObj, versionNumber) {
+        //   if (versionNeedStatusUpdate(versionObj.status)) {
+        //     checkViewVersionStatus(view, versionObj, versionNumber);
+        //   }
+        // });
+        angular.forEach(view.instances, function (instance) {
+          instance.ViewInstanceInfo.short_url_name = instance.ViewInstanceInfo.short_url_name || '';
+          instance.ViewInstanceInfo.short_url = instance.ViewInstanceInfo.short_url || '';
+          $scope.instances.push(instance.ViewInstanceInfo);
         });
-      })
-    }).catch(function(data) {
+      });
+      initTypeFilter();
+      $scope.filterInstances();
+    }).catch(function (data) {
       Alert.error($t('views.alerts.cannotLoadViews'), data.data.message);
     });
   }
 
-  loadViews();
+  function initTypeFilter() {
+    var uniqTypes = $.unique($scope.instances.map(function(instance) {
+      return instance.view_name;
+    }));
+    $scope.typeFilterOptions = [ { label: $t('common.all'), value: '*'} ]
+      .concat(uniqTypes.map(function(type) {
+        return {
+          label: type,
+          value: type
+        };
+      }));
+    $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
+  }
 
-  $scope.createInstance = function(view) {
-    var modalInstance = $modal.open({
-      templateUrl: 'views/ambariViews/modals/create.html',
-      size: 'lg',
-      controller: 'CreateViewInstanceCtrl',
-      resolve: {
-        viewVersion: function(){
-          return view.versionsList[ view.versionsList.length-1];
+  function showInstancesOnPage() {
+    var startIndex = ($scope.currentPage - 1) * $scope.instancesPerPage + 1;
+    var endIndex = $scope.currentPage * $scope.instancesPerPage;
+    var showedCount = 0;
+    var filteredCount = 0;
+
+    angular.forEach($scope.instances, function(instance) {
+      instance.isShowed = false;
+      if (instance.isFiltered) {
+        filteredCount++;
+        if (filteredCount >= startIndex && filteredCount <= endIndex) {
+          instance.isShowed = true;
+          showedCount++;
         }
       }
     });
+    $scope.tableInfo.showed = showedCount;
+  }
 
-    modalInstance.result.then(loadViews);
-  };
-
-  $scope.viewsFilter = '';
-  $scope.filteredViews = [];
-  $scope.getFilteredViews = function(views) {
-    var result = [];
-    var filter = $scope.viewsFilter.toLowerCase();
-    if(!filter){  // if no filter return all views
-      result = $scope.views.map(function(view) {
-        view.isOpened = false;
-        return view;
-      });
-    } else {
-      result = $scope.views.map(function(view) {
-        view.isOpened = true;
-        if(view.view_name.toLowerCase().indexOf(filter) >= 0){
-          return view; // if filter matched with view name -- return whole view
-        } else {
-          var instances = [];
-          angular.forEach(view.instances, function(instance) {
-            if(instance.ViewInstanceInfo.label.toLowerCase().indexOf(filter) >= 0){
-              instances.push(instance);
-            }
-          });
-          if( instances.length ){ // If inside view exists instances with matched filter - show only this instances
-            var v = angular.copy(view);
-            v.instances = instances;
-            return v;
-          }
-        }
-      }).filter(function(view) {
-        return !!view; // Remove 'undefined'
-      });
-    }
-    $scope.filteredViews = result;
-  };
-
-  $scope.gotoCreate = function(viewName, isAllowed) {
-    if(isAllowed){
-      $location.path('/views/'+viewName+'/new');
-    }
-  };
-
-  $scope.deleteInstance = function(instance) {
-      ConfirmationModal.show(
-        $t('common.delete', {
-          term: $t('views.viewInstance')
-        }),
-        $t('common.deleteConfirmation', {
-          instanceType: $t('views.viewInstance'),
-          instanceName: instance.ViewInstanceInfo.label
-        })
-      ).then(function() {
-        View.deleteInstance(instance.ViewInstanceInfo.view_name, instance.ViewInstanceInfo.version, instance.ViewInstanceInfo.instance_name)
-          .then(function() {
-            loadViews();
-          })
-          .catch(function(data) {
-            Alert.error($t('views.alerts.cannotDeleteInstance'), data.data.message);
-          });
-      });
-    };
-
-  $scope.reloadViews = function () {
-    loadViews();
-  };
-
-  /**
-   * Url listing
-   */
-
-  $scope.loadedUrls = [];
-  $scope.urlsPerPage = 10;
+  $scope.views = [];
+  $scope.instances = [];
+  $scope.instancesPerPage = 10;
   $scope.currentPage = 1;
-  $scope.totalUrls = 1;
-  $scope.urlNameFilter = '';
-  $scope.urlSuffixfilter = '';
-  $scope.maxVisiblePages=20;
+  $scope.instanceNameFilter = '';
+  $scope.instanceUrlFilter = '';
+  $scope.maxVisiblePages = 10;
+  $scope.isNotEmptyFilter = true;
+  $scope.instanceTypeFilter = '';
   $scope.tableInfo = {
-    total: 0,
+    filtered: 0,
     showed: 0
   };
 
-  $scope.isNotEmptyFilter = true;
-
-
-  $scope.pageChanged = function() {
-    $scope.listViewUrls();
-  };
+  loadViews();
 
-  $scope.urlsPerPageChanged = function() {
+  $scope.filterInstances = function() {
+    var filteredCount = 0;
+    angular.forEach($scope.instances, function(instance) {
+      if ($scope.instanceNameFilter && instance.short_url_name.indexOf($scope.instanceNameFilter) === -1) {
+        return instance.isFiltered = false;
+      }
+      if ($scope.instanceUrlFilter && ('/main/view/'+ instance.view_name + '/' + instance.short_url).indexOf($scope.instanceUrlFilter) === -1) {
+        return instance.isFiltered = false;
+      }
+      if ($scope.instanceTypeFilter.value !== '*' && instance.view_name.indexOf($scope.instanceTypeFilter.value) === -1) {
+        return instance.isFiltered = false;
+      }
+      filteredCount++;
+      instance.isFiltered = true;
+    });
+    $scope.tableInfo.filtered = filteredCount;
     $scope.resetPagination();
   };
 
+  $scope.pageChanged = function() {
+    showInstancesOnPage();
+  };
 
   $scope.resetPagination = function() {
     $scope.currentPage = 1;
-    $scope.listViewUrls();
+    showInstancesOnPage();
   };
 
-
-  $scope.getVersions = function(instances) {
-    var names = [];
-
-    instances.map(function(view){
-      var name = view.view_name;
-      names.push(name);
-    });
-
-    var output = [],
-        keys = [];
-
-    angular.forEach(names, function(item) {
-      var key = item;
-      if(keys.indexOf(key) === -1) {
-        keys.push(key);
-        output.push(item);
-      }
-    });
-    return output;
-    };
-
-
-
   $scope.clearFilters = function () {
-    $scope.urlNameFilter = '';
-    $scope.urlSuffixfilter = '';
+    $scope.instanceNameFilter = '';
+    $scope.instanceUrlFilter = '';
     $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
     $scope.resetPagination();
   };
 
-
-
   $scope.$watch(
-      function (scope) {
-        return Boolean(scope.urlNameFilter || scope.urlSuffixfilter || (scope.instanceTypeFilter && scope.instanceTypeFilter.value !== '*'));
-      },
-      function (newValue, oldValue, scope) {
-        scope.isNotEmptyFilter = newValue;
-      }
+    function (scope) {
+      return Boolean(scope.instanceNameFilter || scope.instanceUrlFilter || (scope.instanceTypeFilter && scope.instanceTypeFilter.value !== '*'));
+    },
+    function (newValue, oldValue, scope) {
+      scope.isNotEmptyFilter = newValue;
+    }
   );
 
-
-
-
-  $scope.listViewUrls = function(){
-    $scope.isLoadingUrls = true;
-    View.allUrls({
-      currentPage: $scope.currentPage,
-      urlsPerPage: $scope.urlsPerPage,
-      searchString: $scope.urlNameFilter,
-      suffixSearch: $scope.urlSuffixfilter,
-      instanceType: $scope.instanceTypeFilter?$scope.instanceTypeFilter.value:'*'
-    }).then(function(urls) {
-      $scope.isLoadingUrls = false;
-      $scope.urls = urls;
-      $scope.ViewNameFilterOptions = urls.items.map(function(url){
-        return url.ViewUrlInfo.view_instance_common_name;
-      });
-
-      $scope.totalUrls = urls.itemTotal;
-      $scope.tableInfo.showed = urls.items.length;
-      $scope.tableInfo.total = urls.itemTotal;
-
-      // get all view instances to enable/disable creation if empty
-
-    }).catch(function(data) {
-      Alert.error($t('views.alerts.cannotLoadViewUrls'), data.message);
+  $scope.createInstance = function () {
+    var modalInstance = $modal.open({
+      templateUrl: 'views/ambariViews/modals/create.html',
+      controller: 'CreateViewInstanceCtrl',
+      resolve: {
+        views: function() {
+          return $scope.views;
+        }
+      },
+      backdrop: 'static'
     });
-  };
 
+    modalInstance.result.then(loadViews);
+  };
 
-  $scope.initViewUrls = function(){
-    $scope.listViewUrls();
-    View.getAllVisibleInstance().then(function(instances){
-      // if no instances then disable the create button
-      if(!instances.length){
-        $scope.createUrlDisabled = true;
-      } else {
-        $scope.typeFilterOptions = [{ label: $t('common.all'), value: '*'}]
-            .concat($scope.getVersions(instances).map(function(key) {
-              return {
-                label: key,
-                value: key
-              };
-            }));
-
-        $scope.instanceTypeFilter = $scope.typeFilterOptions[0];
-      }
-
-    }).catch(function(data) {
-      // Make the create button enabled, and swallow the error
-      $scope.createUrlDisabled = false;
+  $scope.deleteInstance = function (instance) {
+    ConfirmationModal.show(
+      $t('common.delete', {
+        term: $t('views.viewInstance')
+      }),
+      $t('common.deleteConfirmation', {
+        instanceType: $t('views.viewInstance'),
+        instanceName: instance.label
+      })
+    ).then(function () {
+      View.deleteInstance(instance.view_name, instance.version, instance.instance_name)
+        .then(function () {
+          loadViews();
+        })
+        .catch(function (data) {
+          Alert.error($t('views.alerts.cannotDeleteInstance'), data.data.message);
+        });
     });
-
   };
-
-}]);
\ No newline at end of file
+}]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
index cb52df1..73ab064 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
@@ -32,7 +32,6 @@ angular.module('ambariAdminConsole')
     'common.register': 'Register',
     'common.clusters': 'Clusters',
     'common.views': 'Views',
-    'common.viewUrls': 'View URLs',
     'common.roles': 'Roles',
     'common.users': 'Users',
     'common.groups': 'Groups',
@@ -80,6 +79,7 @@ angular.module('ambariAdminConsole')
     'common.remoteClusterDelConfirmation': 'Are you sure you want to delete {{instanceType}} {{instanceName}}? This operation cannot be undone.',
     'common.messageInstanceAffected': 'The following View Instances are using this Remote Cluster for configuration, and will need to be reconfigured:',
     'common.local': 'Local',
+    'common.remote': 'Remote',
     'common.pam': 'PAM',
     'common.ldap': 'LDAP',
     'common.jwt': 'JWT',
@@ -100,6 +100,7 @@ angular.module('ambariAdminConsole')
     'common.clusterManagement': 'Cluster Management',
     'common.userManagement': 'User Management',
     'common.admin': 'Admin',
+    'common.actions': 'Actions',
 
     'common.clusterNameChangeConfirmation.title': 'Confirm Cluster Name Change',
     'common.clusterNameChangeConfirmation.message': 'Are you sure you want to change the cluster name to {{clusterName}}?',
@@ -191,7 +192,7 @@ angular.module('ambariAdminConsole')
     'views.viewInstance': 'View Instance',
     'views.create': 'Create Instance',
     'views.clone': 'Clone Instance',
-    'views.createViewInstance': 'Create View Instance',
+    'views.createViewInstance': 'Create Instance',
     'views.edit': 'Edit',
     'views.viewName': 'View Name',
     'views.instances': 'Instances',
@@ -239,7 +240,6 @@ angular.module('ambariAdminConsole')
     'views.alerts.cannotEditInstance': 'Cannot Edit Static Instances',
     'views.alerts.cannotDeleteStaticInstance': 'Cannot Delete Static Instances',
     'views.alerts.deployError': 'Error deploying. Check Ambari Server log.',
-    'views.alerts.unableToCreate': 'Unable to create view instances',
     'views.alerts.cannotUseOption': 'This view cannot use this option',
     'views.alerts.unableToResetErrorMessage': 'Unable to reset error message for prop: {{key}}',
     'views.alerts.instanceCreated': 'Created View Instance {{instanceName}}',
@@ -256,7 +256,12 @@ angular.module('ambariAdminConsole')
     'views.alerts.savedRemoteClusterInformation': 'Remote cluster information is saved.',
     'views.alerts.credentialsUpdated': 'Credentials Updated.',
 
-    'urls.name': 'Name',
+    'views.table.viewType': 'View Type',
+    'views.emptyTable': 'No Views to display',
+    'views.createInstance.selectView': 'Select View',
+    'views.createInstance.selectVersion': 'Select Version',
+    'views.createInstance.clusterType': 'Cluster Type',
+
     'urls.url': 'URL',
     'urls.viewUrls': 'View URLs',
     'urls.createNewUrl': 'Create New URL',
@@ -267,7 +272,6 @@ angular.module('ambariAdminConsole')
     'urls.step1': 'Create URL',
     'urls.step2': 'Select instance',
     'urls.step3': 'Assign URL',
-    'urls.noUrlsToDisplay': 'No URLs to display.',
     'urls.noViewInstances': 'No view instances',
     'urls.none': 'None',
     'urls.change': 'Change',

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
index d2d8253..2cb077a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js
@@ -93,14 +93,20 @@ angular.module('ambariAdminConsole')
   views: {
     list: {
       url: '/views',
-      templateUrl: 'views/ambariViews/listTable.html',
+      templateUrl: 'views/ambariViews/viewsList.html',
       controller: 'ViewsListCtrl',
       label: 'Views'
     },
-    listViewUrls: {
-      url: '/viewUrls',
-      templateUrl: 'views/ambariViews/listUrls.html',
-      controller: 'ViewsListCtrl',
+    clone: {
+      url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
+      templateUrl: 'views/ambariViews/create.html',
+      controller: 'CloneViewInstanceCtrl',
+      label: 'Views'
+    },
+    edit: {
+      url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
+      templateUrl: 'views/ambariViews/edit.html',
+      controller: 'ViewsEditCtrl',
       label: 'Views'
     },
     createViewUrl:{
@@ -120,24 +126,6 @@ angular.module('ambariAdminConsole')
       templateUrl: 'views/urls/edit.html',
       controller: 'ViewUrlEditCtrl',
       label: 'Views'
-    },
-    clone: {
-      url: '/views/:viewId/versions/:version/instances/:instanceId/clone',
-      templateUrl: 'views/ambariViews/create.html',
-      controller: 'CreateViewInstanceCtrl',
-      label: 'Views'
-    },
-    edit: {
-      url: '/views/:viewId/versions/:version/instances/:instanceId/edit',
-      templateUrl: 'views/ambariViews/edit.html',
-      controller: 'ViewsEditCtrl',
-      label: 'Views'
-    },
-    create: {
-      url: '/views/:viewId/new',
-      templateUrl: 'views/ambariViews/create.html',
-      controller: 'CreateViewInstanceCtrl',
-      label: 'Views'
     }
   },
   stackVersions: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
index f549b29..b38b0c2 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js
@@ -61,32 +61,6 @@ angular.module('ambariAdminConsole')
     angular.element(this,item);
   }
 
-  ViewUrl.all = function(params) {
-    var deferred = $q.defer();
-
-    $http({
-      method: 'GET',
-      dataType: "json",
-      url: Settings.baseUrl + '/view/urls?'
-      + 'ViewUrlInfo/url_name.matches(.*'+params.searchString+'.*)'
-      + '&ViewUrlInfo/url_suffix.matches(.*'+params.suffixSearch+'.*)'
-      + '&fields=*'
-      + '&from=' + (params.currentPage-1)*params.urlsPerPage
-      + '&page_size=' + params.urlsPerPage
-      + (params.instanceType === '*' ? '' : '&ViewUrlInfo/view_instance_common_name=' + params.instanceType)
-
-    })
-        .success(function(data) {
-          deferred.resolve(new ViewUrl(data));
-        })
-        .error(function(data) {
-          deferred.reject(data);
-        });
-
-    return deferred.promise;
-  };
-
-
   ViewUrl.updateShortUrl = function(payload){
     var deferred = $q.defer();
 
@@ -176,7 +150,7 @@ angular.module('ambariAdminConsole')
     var versions = {};
     angular.forEach(item.versions, function(version) {
       versions[version.ViewVersionInfo.version] = {count: version.instances.length, status: version.ViewVersionInfo.status};
-      if(version.ViewVersionInfo.status === 'DEPLOYED'){ // if atelast one version is deployed
+      if (version.ViewVersionInfo.status === 'DEPLOYED'){ // if at least one version is deployed
         self.canCreateInstance = true;
       }
 
@@ -203,10 +177,6 @@ angular.module('ambariAdminConsole')
     return ViewInstance.find(viewName, version, instanceName);
   };
 
-  View.allUrls =  function(req){
-    return ViewUrl.all(req)
-  };
-
   View.getUrlInfo = function(urlName){
     return ViewUrl.urlInfo(urlName);
   };

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
index 66f23af..bd06bc0 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
@@ -367,10 +367,6 @@ a.gotoinstance{
   width: 14px;
 }
 
-.namefilter {
-  font-weight: normal;
-}
-
 .settings-edit-toggle.disabled, .properties-toggle.disabled{
   color: #999;
   cursor: not-allowed;
@@ -480,25 +476,18 @@ a.gotoinstance{
 .search-container{
   position: relative;
 }
-.search-container .close{
+.search-container .close {
   position: absolute;
   right: 10px;
-  top: 32px;
+  top: 8px;
+}
+.search-container input {
+  font-weight: normal;
 }
 .groups-pane .search-container .close{
   top: 32px;
 }
-.views-urls-table .search-container .close{
-  top: 7px;
-  right: 10px;
-  z-index: 10;
-}
 
-.views-list-table .search-container .close{
-  right: 50px;
-  top: 7px;
-  z-index: 10;
-}
 .groups-pane table thead th{
   border-top: 0;
 }
@@ -563,9 +552,7 @@ table.no-border tr td{
 .no-border{
   border: none !important;
 }
-.top-margin-4{
-  margin-top: 4px;
-}
+
 .table > thead > tr > th.vertical-top{
   vertical-align: top;
 }
@@ -647,10 +634,14 @@ button.btn.btn-xs{
   border-radius: 3px;
 }
 
-a.btn-primary {
+a.btn-primary, a.btn-primary:focus {
   color: #fff;
 }
 
+a.btn-default, a.btn-default:focus {
+  color: #666;
+}
+
 .clusterDisplayName {
   display:inline-block;
   width:90%;
@@ -686,6 +677,12 @@ a.alert-link, a.alert-link:hover, a.alert-link:visited{
   color: #666;
 }
 
+.empty-table-alert {
+  background-color: #f0f0f0;
+  text-align: center;
+  text-transform: uppercase;
+}
+
 .alert-container {
   position: fixed;
   top: 50px;
@@ -1475,10 +1472,6 @@ legend {
   text-overflow: ellipsis;
 }
 
-.pull-right {
-  float: right;
-}
-
 body {
   height: 100%;
   background-color: #f0f0f0;
@@ -1498,3 +1491,7 @@ body {
   background-color: #fff;
   padding: 15px;
 }
+
+.navigation-bar-fit-height {
+  z-index: 1001;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
new file mode 100644
index 0000000..9ab66f5
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/views.css
@@ -0,0 +1,49 @@
+/**
+ * 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.
+ */
+
+.view-instance-actions>a {
+  color: inherit;
+  font-size: 16px;
+  cursor: pointer;
+  padding: 0 5px;
+}
+
+td.view-instance-actions,
+th.view-instance-actions {
+  width: 10%;
+}
+
+.view-instance-actions>a:hover,
+.view-instance-actions>a:visited:hover,
+.view-instance-actions>a:focus:hover {
+  text-decoration: none;
+}
+
+#create-instance-form i {
+  cursor: pointer;
+}
+
+#create-instance-form button.active {
+  color: #333;
+  background-color: #e6e6e6;
+  border-color: #adadad;
+}
+
+input[type="checkbox"] + label {
+  line-height: 18px;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
deleted file mode 100644
index 91b9a93..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listTable.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div class="views-list-table">
-    <div class="clearfix">
-        <ol class="breadcrumb pull-left">
-            <li class="active">{{'common.views' | translate}}</li>
-            <button ng-click="reloadViews()"
-                    class="btn btn-xs">
-                <i class="glyphicon glyphicon-refresh"></i>
-            </button>
-        </ol>
-        <div class="pull-right col-sm-4">
-            <div class="input-group search-container">
-                <input type="text" class="form-control search-input" placeholder="{{'common.search' | translate}}" ng-model="viewsFilter" ng-change="getFilteredViews()">
-                <button type="button" class="close clear-search" ng-show="viewsFilter" ng-click="viewsFilter=''; getFilteredViews()"><span aria-hidden="true">&times;</span><span class="sr-only">{{"common.controls.close" | translate}}</span></button>
-        <span class="input-group-addon">
-          <span class="glyphicon glyphicon-search"></span>
-        </span>
-            </div>
-        </div>
-    </div>
-    <hr>
-    <div class="row">
-        <div class="col-sm-3 padding-left-30"><h4>{{'views.viewName' | translate}}</h4></div>
-        <div class="col-sm-3"><h4>{{'views.instances' | translate}}</h4></div>
-        <div class="col-sm-6"><h4></h4></div>
-    </div>
-    <accordion close-others="false">
-        <accordion-group ng-repeat="view in filteredViews" is-open="view.isOpened">
-            <accordion-heading>
-                <div class="row">
-                    <div class="col-sm-4">
-                        <i class="glyphicon glyphicon-chevron-right" ng-class="{'opened': view.isOpened}"></i>
-                        {{view.view_name}}
-                    </div>
-                    <div class="col-sm-3">
-            <span ng-repeat="(version, vData) in view.versions">
-              {{version}}
-                <span ng-switch="vData.status">
-                  <span ng-switch-when="PENDING" class="viewstatus pending" ng-switch-when="true" tooltip="{{'views.pending' | translate}}"></span>
-                  <div class="viewstatus deploying" ng-switch-when="DEPLOYING" tooltip="{{'views.deploying' | translate}}">
-                      <div class="rect1"></div>
-                      <div class="rect2"></div>
-                      <div class="rect3"></div>
-                  </div>
-                  <span ng-switch-when="DEPLOYED">({{vData.count}})</span>
-                  <span ng-switch-when="ERROR" tooltip="{{'views.alerts.deployError' | translate}}"><i class="fa fa-exclamation-triangle"></i></span>
-                </span>
-              {{$last ? '' : ', '}}
-            </span>
-                    </div>
-                    <div class="col-sm-6">{{view.description}}</div>
-                </div>
-            </accordion-heading>
-            <table class="table instances-table">
-                <tbody>
-                <tr ng-repeat="instance in view.instances">
-                    <td class="col-sm-1"></td>
-                    <td class="col-sm-5">
-                        <a href="#/views/{{view.view_name}}/versions/{{instance.ViewInstanceInfo.version}}/instances/{{instance.ViewInstanceInfo.instance_name}}/edit" class="instance-link">{{instance.label}}</a>
-                    </td>
-                    <td class="col-sm-5">{{instance.ViewInstanceInfo.version}}</td>
-                    <td class="col-sm-5 " ><div class="description-column" tooltip="{{instance.ViewInstanceInfo.description}}">{{instance.ViewInstanceInfo.description || 'No description'}}</div>
-                    </td>
-                    <td class="col-sm-1">
-                        <a class="instance-link ng-scope ng-binding" href="#/views/{{view.view_name}}/versions/{{instance.ViewInstanceInfo.version}}/instances/{{instance.ViewInstanceInfo.instance_name}}/clone"><i class="fa fa-copy"></i></a>
-                    </td>
-                    <td class="col-sm-1">
-                        <a class="instance-link ng-scope ng-binding" href ng-click="deleteInstance(instance)"><i class="fa fa-trash-o"></i></a>
-                    </td>
-                </tr>
-                </tbody>
-                <tfoot>
-                <tr>
-                    <td class="col-sm-4"></td>
-                    <td class="col-sm-3 padding-left-30">
-                        <a tooltip="{{view.canCreateInstance ? '' : constants.unable}}" class="btn btn-default createisntance-btn {{view.canCreateInstance ? '' : 'disabled'}}" href ng-click="gotoCreate(view.view_name, view.canCreateInstance);"><span class="glyphicon glyphicon-plus"></span> {{'views.create' | translate}}</a>
-                    </td>
-                    <td class="col-sm-3"></td>
-                    <td class="col-sm-3">
-                    </td>
-                </tr>
-                </tfoot>
-            </table>
-        </accordion-group>
-        <div ng-if="isLoadingViews" class="spinner-container">
-          <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
-        </div>
-        <div class="alert alert-info" ng-show="views && !filteredViews.length && !isLoadingViews">
-            {{'common.alerts.nothingToDisplay' | translate: '{term: constants.views}'}}
-        </div>
-
-    </accordion>
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
deleted file mode 100644
index 13ff311..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/listUrls.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div class="views-urls-table" data-ng-init="initViewUrls()">
-
-
-    <div class="clearfix">
-        <ol class="breadcrumb pull-left">
-            <li class="active">{{'common.viewUrls' | translate}}</li>
-        </ol>
-        <div class="pull-right top-margin-4">
-            <div class="tooltip-wrapper"  tooltip="{{(createUrlDisabled)? ('urls.noViewInstances' | translate) : ''}}">
-            <link-to ng-disabled="createUrlDisabled" route="views.createViewUrl" class="btn btn-primary createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'urls.createNewUrl' | translate}}</link-to>
-        </div>
-        </div>
-    </div>
-    <hr>
-    <table class="table table-striped table-hover">
-        <thead>
-        <tr class="fix-bottom">
-
-            <th class="fix-bottom col-md-2">
-                <span>{{'urls.name' | translate}}</span>
-            </th>
-            <th class="fix-bottom col-md-3">
-                <span>{{'urls.url' | translate}}</span>
-            </th>
-            <th class="fix-bottom col-md-2">
-                <span >{{'urls.view' | translate}}</span>
-            </th>
-            <th class="fix-bottom col-md-2">
-                <span>{{'urls.viewInstance' | translate}}</span>
-            </th>
-        </tr>
-
-        <tr>
-
-            <th class="fix-top">
-                <div class="search-container">
-                    <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="urlNameFilter" ng-change="resetPagination()">
-                    <button type="button" class="close clearfilter" ng-show="urlNameFilter" ng-click="urlNameFilter=''; resetPagination()"><span class="pull-right" aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
-                    </div>
-            </th>
-            <th class="fix-top">
-                <div class="search-container">
-                    <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="urlSuffixfilter" ng-change="resetPagination()">
-                    <button type="button" class="close clearfilter" ng-show="urlSuffixfilter" ng-click="urlSuffixfilter=''; resetPagination()"><span class="pull-right" aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
-                </div>
-            </th>
-            <th class="fix-top">
-                <select class="form-control typefilter v-small-input"
-                        ng-model="instanceTypeFilter"
-                        ng-options="item.label for item in typeFilterOptions"
-                        ng-change="resetPagination()">
-                </select>
-            </th>
-            <th class="fix-top">
-            </th>
-        </tr>
-
-        </thead>
-        <tbody>
-        <tr ng-repeat="url in urls.items">
-
-            <td>
-                <a href="#/urls/edit/{{url.ViewUrlInfo.url_name}}">{{url.ViewUrlInfo.url_name}}</a>
-            </td>
-            <td>
-                <a target="_blank" href="{{fromSiteRoot('/#/main/view/' + url.ViewUrlInfo.view_instance_common_name + '/' + url.ViewUrlInfo.url_suffix)}}">/main/view/{{url.ViewUrlInfo.view_instance_common_name}}/{{url.ViewUrlInfo.url_suffix}}
-                    &nbsp;<i class="fa fa-external-link" aria-hidden="true"></i></a>
-
-            </td>
-            <td>
-                <span>{{url.ViewUrlInfo.view_instance_common_name}} {{"{"+url.ViewUrlInfo.view_instance_version+"}"}} </span>
-            </td>
-            <td>
-                <span>{{url.ViewUrlInfo.view_instance_name}}</span>
-            </td>
-
-        </tr>
-        </tbody>
-    </table>
-    <div ng-if="isLoadingUrls" class="spinner-container">
-      <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
-    </div>
-    <div class="alert alert-info col-sm-12" ng-show="!urls.items.length && !isLoadingUrls">
-        {{'urls.noUrlsToDisplay'| translate}}
-    </div>
-    <div class="col-sm-12 table-bar">
-        <div class="pull-left filtered-info">
-            <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: urs.urls}'}}</span>
-            <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
-        </div>
-        <div class="pull-right left-margin">
-            <pagination class="paginator" total-items="totalUrls" max-size="maxVisiblePages" items-per-page="urlsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
-        </div>
-        <div class="pull-right">
-            <select class="form-control" ng-model="urlsPerPage" ng-change="urlsPerPageChanged()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
-        </div>
-    </div>
-
-</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
index c5410c1..48757d4 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/create.html
@@ -15,110 +15,160 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 -->
-<form class="form-horizontal" role="form" name="form.instanceCreateForm" novalidate>
+<form role="form" id="create-instance-form" name="form.instanceCreateForm" novalidate>
 <div class="modal-header">
   <h3 class="modal-title">{{'views.createViewInstance' | translate}}</h3>
 </div>
-<div class="modal-body createViewModal">
-  <div class="view-header">
-    <img src="http://placehold.it/64x64" alt="" class="icon-big">
-    <img src="http://placehold.it/32x32" alt="" class="icon-small">
-    <div class="description">
-      <h3>{{view.ViewVersionInfo.view_name}}</h3>
-      <span>{{view.ViewVersionInfo.label}} | Version: {{view.ViewVersionInfo.version}}</span>
+<div class="modal-body" ng-hide="isLoading">
+
+  <div class="row">
+
+    <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.view.$error.required && form.instanceCreateForm.submitted }">
+      <label for="view">
+        {{'views.createInstance.selectView' | translate}}<span>*</span>&nbsp;
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <select
+        class="form-control"
+        id="view"
+        name="view"
+        ng-model="formData.view"
+        ng-change="updateVersionOptions()"
+        ng-options="item.label for item in viewOptions"
+        required>
+      </select>
+      <span class="help-block validation-block" ng-show='form.instanceCreateForm.view.$error.required && form.instanceCreateForm.submitted'>
+        {{'common.alerts.fieldRequired' | translate}}
+      </span>
+    </div>
+
+    <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.version.$error.required && form.instanceCreateForm.submitted }">
+      <label for="version">
+        {{'views.createInstance.selectVersion' | translate}}<span>*</span>&nbsp;
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <select
+        class="form-control"
+        id="version"
+        name="version"
+        ng-model="formData.version"
+        ng-options="item.label for item in versionOptions">
+      </select>
+      <span class="help-block validation-block" ng-show='form.instanceCreateForm.version.$error.required && form.instanceCreateForm.submitted'>
+        {{'common.alerts.fieldRequired' | translate}}
+      </span>
     </div>
   </div>
-  
-    <div class="panel panel-default">
-      <div class="panel-heading">
-        <h3 class="panel-title">{{'common.details' | translate}}</h3>
-      </div>
-      <div class="panel-body">
-        <div class="form-group" 
-        ng-class="{'has-error' : ( (form.instanceCreateForm.instanceNameInput.$error.required || form.instanceCreateForm.instanceNameInput.$error.pattern) && form.instanceCreateForm.submitted) || instanceExists }"
-        >
-          <label for="" class="control-labe col-sm-2">{{'views.instanceName' | translate}}</label>
-          <div class="col-sm-10">
-            <input type="text" class="form-control" name="instanceNameInput" ng-pattern="nameValidationPattern" required ng-model="instance.instance_name">
 
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.required && form.instanceCreateForm.submitted'>
-              {{'common.alerts.fieldRequired' | translate}}
-            </div>
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.instanceNameInput.$error.pattern && form.instanceCreateForm.submitted'>
-              {{'common.alerts.noSpecialChars' | translate}}
-            </div>
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='instanceExists'>
-              {{'views.alerts.instanceExists' | translate}}
-            </div>
-          </div>
-        </div>
-        <div class="form-group"
-        ng-class="{'has-error' : ( (form.instanceCreateForm.displayLabel.$error.required || form.instanceCreateForm.displayLabel.$error.pattern) && form.instanceCreateForm.submitted)}">
-          <label for="" class="control-labe col-sm-2">{{'common.displayLabel' | translate}}</label>
-          <div class="col-sm-10">
-            <input type="text" class="form-control" name="displayLabel" ng-model="instance.label" required ng-pattern="nameValidationPattern">
+  <div class="h4">{{'common.details' | translate}}</div>
+  <div class="form-group"
+       ng-class="{ 'has-error': (form.instanceCreateForm.instanceName.$error.required || form.instanceCreateForm.instanceName.$error.pattern || isInstanceExists) && form.instanceCreateForm.submitted }">
+    <label for="instanceName">
+      {{'views.instanceName' | translate}}<span>*</span>&nbsp;
+      <i class="fa fa-question-circle" aria-hidden="true"></i>
+    </label>
+    <input type="text" class="form-control"
+           ng-model="formData.instanceName"
+           name="instanceName"
+           id="instanceName"
+           ng-change="checkIfInstanceExist()"
+           ng-pattern="nameValidationPattern" required>
+    <span class="help-block validation-block"
+         ng-show='form.instanceCreateForm.instanceName.$error.required && form.instanceCreateForm.submitted'>
+      {{'common.alerts.fieldRequired' | translate}}
+    </span>
+    <span class="help-block validation-block"
+         ng-show='form.instanceCreateForm.instanceName.$error.pattern && form.instanceCreateForm.submitted'>
+      {{'common.alerts.noSpecialChars' | translate}}
+    </span>
+    <span class="help-block validation-block"
+         ng-show='isInstanceExists && form.instanceCreateForm.submitted'>
+      {{'views.alerts.instanceExists' | translate}}
+    </span>
+  </div>
 
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.required && form.instanceCreateForm.submitted'>
-              {{'common.alerts.fieldRequired' | translate}}
-            </div>
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm.displayLabel.$error.pattern && form.instanceCreateForm.submitted'>
-              {{'common.alerts.noSpecialChars' | translate}}
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="form-group">
-          <div class="col-sm-10 col-sm-offset-2">
-            <button class="btn btn-default" ng-click="isAdvancedClosed = !isAdvancedClosed">{{'views.advanced' | translate}}</button>
-          </div>
-      </div>
-      <div collapse="isAdvancedClosed">
-        <div class="form-group">
-          <div class="col-sm-10 col-sm-offset-2">
-            <div class="checkbox">
-              <label>
-                <input type="checkbox" ng-model='instance.visible'> {{'views.visible' | translate}}
-              </label>
-            </div>
-          </div>
-        </div>
-        <div class="form-group">
-          <div class="col-sm-10 col-sm-offset-2">
-            <label for="" class="control-label col-sm-2">{{'views.icon' | translate}}</label>
-            <div class="col-sm-10">
-              <input type="text" class="form-control" name="iconUrl" ng-model="instance.icon_path">
-            </div>
-          </div>
-        </div>
-        <div class="form-group">
-          <div class="col-sm-10 col-sm-offset-2">
-            <label for="" class="control-label col-sm-2">{{'views.icon64' | translate}}</label>
-            <div class="col-sm-10">
-              <input type="text" class="form-control" name="icon64Url" ng-model="instance.icon64_path">
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
+  <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted }">
+    <label for="displayName">
+      {{'views.displayName' | translate}}<span>*</span>&nbsp;
+      <i class="fa fa-question-circle" aria-hidden="true"></i>
+    </label>
+    <input type="text" class="form-control" required
+           name="displayName"
+           ng-model="formData.displayName"
+           id="displayName">
+    <span class="help-block validation-block" ng-show='form.instanceCreateForm.displayName.$error.required && form.instanceCreateForm.submitted'>
+      {{'common.alerts.fieldRequired' | translate}}
+    </span>
+  </div>
 
-    <div class="panel panel-default">
-      <div class="panel-heading">
-        <h3 class="panel-title">{{'views.configuration' | translate}}</h3>
-      </div>
-      <div class="panel-body">
-      <div class="form-group" ng-repeat="parameter in instance.properties"
-        ng-class="{'has-error' : (form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted)}" >
-        <label for="" class="col-sm-3 control-label">{{parameter.description}}</label>
-        <div class="col-sm-9">
-          <input type="text" class="form-control"  name="{{parameter.name}}" ng-required="parameter.required" ng-model="parameter.value">
-          <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted'>
-            {{'common.alerts.fieldRequired' | translate}}
-          </div>
-        </div>
-      </div>
+  <div class="form-group" ng-class="{ 'has-error': form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted }">
+    <label for="description">
+      {{'views.description' | translate}}<span>*</span>&nbsp;
+      <i class="fa fa-question-circle" aria-hidden="true"></i>
+    </label>
+    <input type="text" class="form-control" required
+           name="description"
+           ng-model="formData.description"
+           id="description">
+    <span class="help-block validation-block" ng-show='form.instanceCreateForm.description.$error.required && form.instanceCreateForm.submitted'>
+      {{'common.alerts.fieldRequired' | translate}}
+    </span>
+  </div>
+
+  <div class="form-group checkbox">
+    <input type="checkbox" class="form-control"
+           name="visible"
+           ng-model="formData.visible"
+           id="visible">
+    <label for="visible">
+      {{'views.visible' | translate}}
+      <i class="fa fa-question-circle" aria-hidden="true"></i>
+    </label>
+  </div>
+
+  <div class="h4">{{'views.clusterConfiguration' | translate}}</div>
+  <div class="form-group">
+    <label for="clusterType">
+      {{'views.createInstance.clusterType' | translate}}?&nbsp;
+      <i class="fa fa-question-circle" aria-hidden="true"></i>
+    </label>
+    <div>
+      <div class="btn-group" role="group" id="clusterType">
+        <button type="button" class="btn btn-default"
+                ng-class="isLocalTypeChosen && 'active'"
+                ng-click="switchClusterType(true)">
+          {{'common.local' | translate}}
+        </button>
+        <button type="button" class="btn btn-default"
+                ng-class="!isLocalTypeChosen && 'active'"
+                ng-click="switchClusterType(false)">
+          {{'common.remote' | translate}}
+        </button>
       </div>
     </div>
-  
+  </div>
+  <div class="row">
+    <div class="form-group col-sm-6" ng-class="{ 'has-error': form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted }">
+      <label for="clusterName">
+        {{'views.clusterName' | translate}}<span>*</span>&nbsp;
+        <i class="fa fa-question-circle" aria-hidden="true"></i>
+      </label>
+      <select
+        required
+        name="clusterName"
+        ng-options="item.label for item in clusterOptions"
+        class="form-control"
+        ng-model="formData.clusterName"
+        id="clusterName">
+      </select>
+      <span class="help-block validation-block" ng-show='form.instanceCreateForm.clusterName.$error.required && form.instanceCreateForm.submitted'>
+        {{'common.alerts.fieldRequired' | translate}}
+      </span>
+    </div>
+  </div>
+</div>
+<div ng-if="isLoading" class="spinner-container">
+  <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
 </div>
 <div class="modal-footer">
   <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
deleted file mode 100644
index aab526e..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/modals/edit.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!--
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
--->
-
-<div class="modal-header">
-  <h3 class="modal-title">{{'views.edit' | translate}} {{instance.ViewInstanceInfo.view_name}}: {{instance.ViewInstanceInfo.label}}</h3>
-</div>
-<div class="modal-body">
-  <div class="panel panel-default">
-    <div class="panel-heading clearfix">
-      <h3 class="panel-title pull-left">{{'views.settings' | translate}}</h3>
-      <div class="pull-right">
-        <a href ng-click="edit.editSettingsDisabled = !edit.editSettingsDisabled" ng-show="edit.editSettingsDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
-      </div>
-    </div>
-    <div class="panel-body">
-      <form class="form-horizontal">
-        <fieldset ng-disabled="edit.editSettingsDisabled">
-          <div class="form-group">
-            <label for="" class="col-sm-2 control-label">{{'views.instanceId' | translate}}</label>
-            <label for="" class="col-sm-10 control-label text-left">{{instance.ViewInstanceInfo.instance_name}}</label>
-          </div>
-          <div class="form-group">
-            <label for="" class="col-sm-2 control-label">{{'views.displayName' | translate}}</label>
-            <div class="col-sm-10"><input type="text" class="form-control" placeholder="{{'views.displayName' | translate}}" ng-model="settings.label"></div>
-          </div>
-          <div class="form-group">
-            <div class="col-sm-offset-2 col-sm-10">
-              <div class="checkbox">
-                <label>
-                  <input type="checkbox" ng-model="settings.visible"> {{'views.visible' | translate}}
-                </label>
-              </div>
-            </div>
-          </div>
-          <div class="form-group" ng-hide="edit.editSettingsDisabled">
-            <div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-default pull-right left-margin" ng-click="cancelSettings()">{{'common.controls.cancel' | translate}}</button>
-              <button class="btn btn-primary pull-right" ng-click="saveSettings()">{{'common.controls.save' | translate}}</button>
-            </div>
-          </div>
-        </fieldset>
-      </form>
-    </div>
-  </div>
-
-  <div class="panel panel-default views-permissions-panel" style="">
-    <div class="panel-heading clearfix">
-      <h3 class="panel-title pull-left">{{'views.permissions' | translate}}</h3>
-      <div class="pull-right">
-        <a href ng-click="edit.editPermissionDisabled = !edit.editPermissionDisabled" ng-show="edit.editPermissionDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
-      </div>
-    </div>
-    <div class="panel-body">
-      <form class="form-horizontal">
-        <div class="form-group">
-          <div class="col-sm-2"></div>
-          <label class="col-sm-5 control-label text-left">{{'common.users' | translate}}</label>
-          <label class="col-sm-5 control-label text-left">{{'common.groups' | translate}}</label>
-        </div>
-        <div class="form-group" ng-repeat="permission in permissions">
-          <label class="col-sm-2 control-label">{{permission.PermissionInfo.permission_name}}</label>
-          <div class="col-sm-5" ng-switch="edit.editPermissionDisabled">
-            <textarea name="" id="" cols="30" rows="4" class="form-control" ng-model="permissionsEdit[permission.PermissionInfo.permission_name].USER" ng-switch-when="false"></textarea>
-            <div class="well" ng-switch-when="true">
-              <span ng-repeat="user in permission.USER">
-                <link-to route="users.show" id="{{user}}">{{user}}</link-to>
-                <button type="button" class="close remove-button" 
-                  ng-click="removePermission(permission.name, 'USER', user)"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
-                {{$last ? '' :', '}}
-              </span>
-            </div>
-          </div>
-          <div class="col-sm-5" ng-switch="edit.editPermissionDisabled">
-            <textarea name="" id="" cols="30" rows="4" class="form-control" ng-model="permissionsEdit[permission.PermissionInfo.permission_name].GROUP" ng-switch-when="false"></textarea>
-            <div class="well" ng-switch-when="true">
-              <span ng-repeat="group in permission.GROUP">
-                <link-to route="groups.edit" id="{{group}}" >{{group}}</link-to>
-                <button type="button" class="close remove-button" 
-                  ng-click="removePermission(permission.name, 'GROUP', group)"><span aria-hidden="true">&times;</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button>
-                {{$last ? '' :', '}}
-              </span>
-            </div>
-          </div>
-        </div>
-        <div class="form-group" ng-hide="edit.editPermissionDisabled">
-          <div class="col-sm-offset-2 col-sm-10">
-            <button class="btn btn-default pull-right left-margin" ng-click="cancelPermissions()">{{'common.controls.cancel' | translate}}</button>
-            <button class="btn btn-primary pull-right" ng-click="savePermissions()">{{'common.controls.save' | translate}}</button>
-          </div>
-        </div>
-      </form>
-        
-    </div>
-  </div>
-
-  <div class="panel panel-default">
-    <div class="panel-heading clearfix">
-      <h3 class="panel-title pull-left">{{'views.configuration' | translate}}</h3>
-      <div class="pull-right">
-        <a href ng-click="edit.editConfigurationDisabled = !edit.editConfigurationDisabled" ng-show="edit.editConfigurationDisabled"> <span class="glyphicon glyphicon-cog"></span> {{'views.edit' | translate}}</a>
-      </div>
-    </div>
-    <div class="panel-body">
-      <form action="" class="form-horizontal">
-        <fieldset ng-disabled="edit.editConfigurationDisabled">
-          <div class="form-group" ng-repeat="(propertyName, propertyValue) in configuration">
-            <label for="" class="control-label col-sm-3">{{propertyName}}</label>
-            <div class="col-sm-9"><input type="text" class="form-control" ng-model="configuration[propertyName]"></div>
-          </div>
-          <div class="form-group" ng-hide="edit.editConfigurationDisabled">
-            <div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-default pull-right left-margin" ng-click="cancelConfiguration()">{{'common.controls.cancel' | translate}}</button>
-              <button class="btn btn-primary pull-right" ng-click="saveConfiguration()">{{'common.controls.save' | translate}}</button>
-            </div>
-          </div>
-        </fieldset>
-      </form>
-    </div>
-  </div>
-</div>
-<div class="modal-footer">
-  <button class="btn btn-default" ng-click="close()">{{'common.controls.save' | translate}}</button>
-</div>


[14/51] [abbrv] ambari git commit: AMBARI-22301. HOU: Service desired repo versions are not being set (ncole)

Posted by nc...@apache.org.
AMBARI-22301. HOU: Service desired repo versions are not being set (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 0c6cf8147d657923fec1c4f5fe8a234117689052
Parents: afb9a66
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 3 16:18:45 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 3 16:18:45 2017 -0400

----------------------------------------------------------------------
 .../server/controller/internal/UpgradeResourceProvider.java  | 4 ++--
 .../controller/internal/UpgradeResourceProviderTest.java     | 8 ++++++++
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0c6cf814/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
index a1ec98a..14b1b86 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UpgradeResourceProvider.java
@@ -762,11 +762,11 @@ public class UpgradeResourceProvider extends AbstractControllerResourceProvider
     The Upgrade Pack is responsible for calling {@link org.apache.ambari.server.serveraction.upgrades.UpdateDesiredRepositoryAction}
     at the appropriate moment during the orchestration.
     */
-    if (pack.getType() == UpgradeType.ROLLING) {
+    if (pack.getType() == UpgradeType.ROLLING || pack.getType() == UpgradeType.HOST_ORDERED) {
       s_upgradeHelper.updateDesiredRepositoriesAndConfigs(upgradeContext);
     }
 
-    @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES, comment = "This is wrong")
+    @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES, comment = "This is SO VERY wrong")
     StackId configurationPackSourceStackId = upgradeContext.getSourceVersions().values().iterator().next().getStackId();
 
     // resolve or build a proper config upgrade pack - always start out with the config pack

http://git-wip-us.apache.org/repos/asf/ambari/blob/0c6cf814/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
index d6b1ab3..64d416f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UpgradeResourceProviderTest.java
@@ -1443,6 +1443,14 @@ public class UpgradeResourceProviderTest extends EasyMockSupport {
 
     requestProps.put(UpgradeResourceProvider.UPGRADE_HOST_ORDERED_HOSTS, hostsOrder);
     upgradeResourceProvider.createResources(request);
+
+
+    // make sure that the desired versions are updated
+    Cluster cluster = clusters.getCluster("c1");
+    assertNotNull(cluster);
+
+    Service service = cluster.getService("ZOOKEEPER");
+    assertEquals(repoVersionEntity2200, service.getDesiredRepositoryVersion());
   }
 
   /**


[40/51] [abbrv] ambari git commit: AMBARI-22386 - Patch Upgrades Broken For Clients Due To Versioned LD Library (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22386 - Patch Upgrades Broken For Clients Due To Versioned LD Library (jonathanhurley)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: feccebcb9b4cf56d8ea0cc021d5250a711f37596
Parents: c693de3
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Nov 8 16:20:30 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Nov 9 16:36:49 2017 -0500

----------------------------------------------------------------------
 .../TEZ/0.9.0.3.0/configuration/tez-site.xml    |  2 +-
 .../configuration-mapred/mapred-site.xml        |  2 +-
 .../configuration-mapred/mapred-site.xml        |  2 +-
 .../2.2/services/TEZ/configuration/tez-site.xml |  4 ++--
 .../YARN/configuration-mapred/mapred-site.xml   |  2 +-
 .../resources/stacks/HDP/2.6/repos/repoinfo.xml |  2 +-
 .../stacks/HDP/2.6/upgrades/config-upgrade.xml  | 23 ++++++++++++++++++++
 .../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml |  9 ++++++++
 .../stacks/HDP/2.6/upgrades/upgrade-2.6.xml     |  4 ++++
 .../YARN/configuration-mapred/mapred-site.xml   |  2 +-
 10 files changed, 44 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
index 5c17044..58558af 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/configuration/tez-site.xml
@@ -78,7 +78,7 @@
   </property>
   <property>
     <name>tez.am.launch.env</name>
-    <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
     <description>
         Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
         you want to have access to native libraries.

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
index a7d8cd6..3438c45 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/configuration-mapred/mapred-site.xml
@@ -438,7 +438,7 @@
   </property>
   <property>
     <name>mapreduce.admin.user.env</name>
-    <value>LD_LIBRARY_PATH={{hadoop_lib_home}}/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:{{hadoop_lib_home}}/native/Linux-{{architecture}}-64</value>
     <description>
       Additional execution environment entries for map and reduce task processes.
       This is not an additive property. You must preserve the original value if

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
index 705763f..882cf83 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration-mapred/mapred-site.xml
@@ -438,7 +438,7 @@
   </property>
   <property>
     <name>mapreduce.admin.user.env</name>
-    <value>LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/Linux-amd64-64</value>
+    <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/Linux-amd64-64</value>
     <description>
       Additional execution environment entries for map and reduce task processes.
       This is not an additive property. You must preserve the original value if

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
index 1427a6f..4ffb7a4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/configuration/tez-site.xml
@@ -78,7 +78,7 @@
   </property>
   <property>
     <name>tez.am.launch.env</name>
-    <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
     <description>
         Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
         you want to have access to native libraries.
@@ -124,7 +124,7 @@
   </property>
   <property>
     <name>tez.task.launch.env</name>
-    <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
     <description>
       Additional execution environment entries for tez. This is not an additive property. You must preserve the original value if
       you want to have access to native libraries.

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
index 4ad08ce..084e912 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
@@ -20,7 +20,7 @@
 <configuration xmlns:xi="http://www.w3.org/2001/XInclude" supports_final="true">
   <property>
     <name>mapreduce.admin.user.env</name>
-    <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
     <description>
       Additional execution environment entries for map and reduce task processes.
       This is not an additive property. You must preserve the original value if

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
index ff132aa..eb0b0ef 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/repos/repoinfo.xml
@@ -33,7 +33,7 @@
   </os>
   <os family="redhat-ppc7">
     <repo>
-      <baseurl>http://public-repo-1.hortonworks.com/HDP/centos7/2.x/updates/2.6.0.3</baseurl>
+      <baseurl>http://public-repo-1.hortonworks.com/HDP/centos7-ppc/2.x/updates/2.6.0.3</baseurl>
       <repoid>HDP-2.6</repoid>
       <reponame>HDP</reponame>
       <unique>true</unique>

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
index 63624d6..45b1707 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/config-upgrade.xml
@@ -258,5 +258,28 @@
       </component>
     </service>
 
+    <service name="TEZ">
+      <component name="TEZ_CLIENT">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library">
+            <type>tez-site</type>
+            <set key="tez.am.launch.env" value="LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64"/>
+            <set key="tez.task.launch.env" value="LD_LIBRARY_PATH=./tezlib/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
+    <service name="MAPREDUCE2">
+      <component name="MAPREDUCE2_CLIENT">
+        <changes>
+          <definition xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library">
+            <type>mapred-site</type>
+            <set key="mapreduce.admin.user.env" value="LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:{{hadoop_lib_home}}/native/Linux-{{architecture}}-64"/>
+          </definition>
+        </changes>
+      </component>
+    </service>
+
   </services>
 </upgrade-config-changes>

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
index c9e90a9..ae2a855 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
@@ -409,6 +409,15 @@
         </task>
       </execute-stage>
 
+      <!-- TEZ -->
+      <execute-stage service="TEZ" component="TEZ_CLIENT" title="Updating LD Library Classpath for Tarball" >
+        <task xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library" supports-patch="true"/>
+      </execute-stage>
+      
+      <!-- MapR -->
+      <execute-stage service="MAPREDUCE2" component="MAPREDUCE2_CLIENT" title="Updating LD Library Classpath for Tarball">
+        <task xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library" supports-patch="true"/>
+      </execute-stage>
     </group>
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
index 176143c..37847a2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
@@ -675,6 +675,8 @@
           <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FixLzoCodecPath">
             <summary>Verifying LZO codec path for mapreduce</summary>
           </task>
+          
+          <task xsi:type="configure" id="hdp_2_6_mapreduce_tarball_ld_library" supports-patch="true"/>
         </pre-upgrade>
 
         <pre-downgrade copy-upgrade="true" />
@@ -757,6 +759,8 @@
           <task xsi:type="server_action" class="org.apache.ambari.server.serveraction.upgrades.FixLzoCodecPath">
             <summary>Verifying LZO codec path for Tez</summary>
           </task>
+          
+          <task xsi:type="configure" id="hdp_2_6_tez_tarball_ld_library" supports-patch="true"/>
         </pre-upgrade>
 
         <pre-downgrade copy-upgrade="true" />

http://git-wip-us.apache.org/repos/asf/ambari/blob/feccebcb/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
index 6ce4d72..489754f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/services/YARN/configuration-mapred/mapred-site.xml
@@ -31,7 +31,7 @@
   <!-- These configs were inherited from HDP 2.2 -->
   <property>
     <name>mapreduce.admin.user.env</name>
-    <value>LD_LIBRARY_PATH=/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
+    <value>LD_LIBRARY_PATH=./mr-framework/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native:/usr/hdp/${hdp.version}/hadoop/lib/native/Linux-{{architecture}}-64</value>
     <description>
       Additional execution environment entries for map and reduce task processes.
       This is not an additive property. You must preserve the original value if


[34/51] [abbrv] ambari git commit: AMBARI-22388 Log Search UI: restyle logs list. (Istvan Tobias via ababiichuk)

Posted by nc...@apache.org.
AMBARI-22388 Log Search UI: restyle logs list. (Istvan Tobias via ababiichuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 38476f7a1a7a371fd0f57af2f931427f1e276d27
Parents: 5f714ce
Author: Istvan Tobias <to...@gmail.com>
Authored: Thu Nov 9 13:24:16 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Nov 9 13:24:16 2017 +0200

----------------------------------------------------------------------
 .../ambari-logsearch-web/src/app/app.module.ts  |   4 +
 .../log-level/log-level.component.html          |  18 +++
 .../log-level/log-level.component.spec.ts       |  73 +++++++++++
 .../components/log-level/log-level.component.ts |  52 ++++++++
 .../log-message/log-message.component.html      |  24 ++++
 .../log-message/log-message.component.less      |  69 ++++++++++
 .../log-message/log-message.component.spec.ts   |  64 +++++++++
 .../log-message/log-message.component.ts        | 129 ++++++++++++++++++
 .../logs-list/logs-list.component.html          |  92 +++++++------
 .../logs-list/logs-list.component.less          | 130 +++++++++----------
 .../ambari-logsearch-web/webpack.config.js      |  15 ++-
 11 files changed, 550 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 488437e..56562df 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -68,6 +68,8 @@ import {FilterButtonComponent} from '@app/components/filter-button/filter-button
 import {AccordionPanelComponent} from '@app/components/accordion-panel/accordion-panel.component';
 import {CollapsiblePanelComponent} from '@app/components/collapsible-panel/collapsible-panel.component';
 import {LogsListComponent} from '@app/components/logs-list/logs-list.component';
+import {LogMessageComponent} from '@app/components/log-message/log-message.component';
+import {LogLevelComponent} from '@app/components/log-level/log-level.component';
 import {DropdownButtonComponent} from '@app/components/dropdown-button/dropdown-button.component';
 import {PaginationComponent} from '@app/components/pagination/pagination.component';
 import {PaginationControlsComponent} from '@app/components/pagination-controls/pagination-controls.component';
@@ -121,6 +123,8 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
     AccordionPanelComponent,
     CollapsiblePanelComponent,
     LogsListComponent,
+    LogLevelComponent,
+    LogMessageComponent,
     DropdownButtonComponent,
     PaginationComponent,
     PaginationControlsComponent,

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
new file mode 100644
index 0000000..d72c9d33
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.html
@@ -0,0 +1,18 @@
+<!--
+  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.
+-->
+<i class="fa {{cssClass}}"></i>
+{{logEntry.level}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
new file mode 100644
index 0000000..c13d373
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.spec.ts
@@ -0,0 +1,73 @@
+/**
+ * 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.
+ */
+import {DebugElement} from '@angular/core';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {LogLevelComponent} from './log-level.component';
+import {By} from '@angular/platform-browser';
+
+describe('LogLevelComponent', () => {
+  let component: LogLevelComponent;
+  let fixture: ComponentFixture<LogLevelComponent>;
+  let de: DebugElement;
+  let el: HTMLElement;
+  let logLevelMap = {
+    warn: 'fa-exclamation-triangle',
+    fatal: 'fa-exclamation-circle',
+    error: 'fa-exclamation-circle',
+    info: 'fa-info-circle',
+    debug: 'fa-bug',
+    trace: 'fa-random',
+    unknown: 'fa-question-circle'
+  };
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ LogLevelComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(LogLevelComponent);
+    component = fixture.componentInstance;
+    component.logEntry = {level: 'unknown'};
+    fixture.detectChanges();
+    de = fixture.debugElement.query(By.css('i.fa'));
+    el = de.nativeElement;
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  Object.keys(logLevelMap).forEach((level) => {
+    describe(level, () => {
+      beforeEach(() => {
+        component.logEntry = {level: level};
+        fixture.detectChanges();
+      });
+      it(`should return with the ${logLevelMap[level]} css class for ${level} log level`, () => {
+        expect(component.cssClass).toEqual(logLevelMap[level]);
+      });
+      it(`should set the ${logLevelMap[level]} css class on the icon element`, () => {
+        expect(el.classList).toContain(logLevelMap[level]);
+      });
+    });
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
new file mode 100644
index 0000000..8542770
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-level/log-level.component.ts
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+import {Component, Input} from '@angular/core';
+
+/**
+ * This is a simple UI component to display the log message. The goal is to be able to show one line and be collapsile
+ * to show the full log message with new lines.
+ * @class LogMessageComponent
+ */
+@Component({
+  selector: 'log-level',
+  templateUrl: './log-level.component.html',
+  styleUrls: []
+})
+export class LogLevelComponent {
+
+  /**
+   * This is the log entry object
+   * @type {object}
+   */
+  @Input()
+  logEntry: any;
+
+  private classMap: object = {
+    warn: 'fa-exclamation-triangle',
+    fatal: 'fa-exclamation-circle',
+    error: 'fa-exclamation-circle',
+    info: 'fa-info-circle',
+    debug: 'fa-bug',
+    trace: 'fa-random',
+    unknown: 'fa-question-circle'
+  };
+
+  get cssClass() {
+    return this.classMap[((this.logEntry && this.logEntry.level) || 'unknown').toLowerCase()];
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
new file mode 100644
index 0000000..d4c2902
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.html
@@ -0,0 +1,24 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<div [ngClass]="{
+  'log-message-container': true,
+  'log-message-container-collapsible': addCaret,
+  'log-message-container-open': isOpen
+  }">
+  <button *ngIf="addCaret" (click)="onCaretClick($event)"><i class="caret"></i></button>
+  <div #content class="log-message-content"><ng-content></ng-content></div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
new file mode 100644
index 0000000..602d7bd
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.less
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ */
+@import '../variables';
+:host {
+  .log-message-container {
+    display: block;
+    margin: 0;
+    padding: 0;
+
+    .caret {
+      margin-top: -3px;
+      transition: transform 250ms;
+      transform: rotate(-90deg);
+    }
+    &.log-message-container-open .caret {
+      transform: rotate(0deg);
+    }
+
+    .log-message-content {
+      max-height: calc(20em/14); // from Bootstrap
+      overflow: hidden;
+      padding-left: 1em;
+      position: relative;
+    }
+    &.log-message-container-open .log-message-content {
+      max-height: none;
+      white-space: pre-wrap;
+      &:before {
+        display: none;
+      }
+    }
+    &.log-message-container-collapsible {
+      .log-message-content {
+        padding-left: 0;
+        &:before {
+          content: "...";
+          float: right;
+          margin-left: 1em;
+        }
+      }
+
+    }
+
+    button, button:active {
+      background: none transparent;
+      border: none transparent;
+      color: @base-font-color;
+      cursor: pointer;
+      float: left;
+      height: 1em;
+      outline: none;
+      padding: 0 .15em;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
new file mode 100644
index 0000000..edc2515
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.spec.ts
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ */
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {LogMessageComponent} from './log-message.component';
+
+describe('LogMessageComponent', () => {
+  let component: LogMessageComponent;
+  let fixture: ComponentFixture<LogMessageComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ LogMessageComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(LogMessageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('event handler should call the toggleOpen method', () => {
+    let mockEvent: MouseEvent = document.createEvent('MouseEvent');
+    mockEvent.initEvent('click', true, true);
+    spyOn(component,'toggleOpen');
+    component.onCaretClick(mockEvent);
+    expect(component.toggleOpen).toHaveBeenCalled();
+  });
+
+  it('event handler should prevent the default behaviour of the action', () => {
+    let mockEvent: MouseEvent = document.createEvent('MouseEvent');
+    mockEvent.initEvent('click', true, true);
+    spyOn(mockEvent,'preventDefault');
+    component.onCaretClick(mockEvent);
+    expect(mockEvent.preventDefault).toHaveBeenCalled();
+  });
+
+  it('calling the toggleOpen method should negate the isOpen property', () => {
+    let currentState = component.isOpen;
+    component.toggleOpen();
+    expect(component.isOpen).toEqual(!currentState);
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
new file mode 100644
index 0000000..b8be61b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/log-message/log-message.component.ts
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+import {Component, Input, AfterViewInit, ElementRef, ViewChild, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef} from '@angular/core';
+
+/**
+ * This is a simple UI component to display the log message. The goal is to be able to show one line and be collapsile
+ * to show the full log message with new lines.
+ * @class LogMessageComponent
+ */
+@Component({
+  selector: 'log-message',
+  templateUrl: './log-message.component.html',
+  styleUrls: ['./log-message.component.less']
+})
+export class LogMessageComponent implements AfterViewInit, OnChanges {
+
+  /**
+   * This is the element reference to the message log container element. So that we can calculate if the caret should be
+   * displayed or not.
+   * @type ElementRef
+   */
+  @ViewChild('content') content: ElementRef;
+
+  /**
+   * This is the flag property to indicate if the content container is open or not.
+   * @type {boolean}
+   */
+  @Input()
+  isOpen: boolean = false;
+
+  /**
+   * This is a helper property to handle the changes on the parent component. The goal of this input is to be able to
+   * react when the parent component (currently the log-list component) has changed (its size) in a way that the
+   * LogMessageComponent should check if the caret should be visible or not.
+   */
+  @Input()
+  listenChangesOn: any;
+
+  /**
+   * This is a private flag to check if it should display the caret or not, it depends on the size of the size of
+   * the content container element. Handled by the @checkAddCaret method
+   * @type {boolean}
+   */
+  private addCaret: boolean = false;
+
+  /**
+   * This is a primary check if the message content does contain new line (/n) characters. If so than we display the
+   * caret to give a possibility to the user to see the message as it is (pre-wrapped).
+   * @type {boolean}
+   */
+  private isMultiLineMessage: boolean = false;
+
+  constructor(private cdRef:ChangeDetectorRef) {}
+
+  /**
+   * This change handler's goal is to check if we should add the caret or not. Mainly it is because currently we have
+   * the LogListComponent where columns can be added or removed and we have to recheck the visibility of the caret every
+   * changes of the displayed columns.
+   * @param {SimpleChanges} changes
+   */
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes.listenChangesOn !== undefined) {
+      this.checkAddCaret();
+    }
+  }
+
+  /**
+   * The goal is to perform a initial caret display check when the component has been initialized.
+   */
+  ngAfterViewInit(): void {
+    let text = this.content.nativeElement.textContent;
+    let newLinePos = text.indexOf('\n');
+    this.isMultiLineMessage = ((text.length - 1) > newLinePos) && (newLinePos > 0);
+    this.checkAddCaret();
+  }
+
+  /**
+   * Since the size of the column is depends on the window size we have to listen the resize event and show/hide the
+   * caret corresponding the new size of the content container element.
+   * Using the arrow function will keep the instance scope.
+   */
+  @HostListener('window:resize', ['$event'])
+  onWindowResize = (): void => {
+    this.isMultiLineMessage || this.checkAddCaret();
+  };
+
+  /**
+   * The goal is to perform a height check on the content container element. It is based on the comparison of the
+   * scrollHeight and the clientHeight.
+   */
+  checkAddCaret = (): void =>  {
+    let el = this.content.nativeElement;
+    this.addCaret = this.isMultiLineMessage || (el.scrollHeight > el.clientHeight);
+    this.cdRef.detectChanges();
+  };
+
+  /**
+   * This is the click event handler of the caret button element. It will only toggle the isOpen property so that the
+   * component element css classes will follow its state.
+   * @param ev {MouseEvent}
+   */
+  onCaretClick(ev:MouseEvent) {
+    ev.preventDefault();
+    this.toggleOpen();
+  }
+
+  /**
+   * This is a simple property toggle method of the @isOpen property.
+   * The goal is to separate this logic from the event handling and give a way to call it from anywhere.
+   */
+  toggleOpen():void {
+    this.isOpen = !this.isOpen;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
index 1e0f49c..10f4af1 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.html
@@ -20,46 +20,54 @@
                    [defaultLabel]="filters.sorting.defaultLabel" [isRightAlign]="true"
                    class="col-md-12"></filter-dropdown>
 </form>
-<div *ngFor="let log of logs; let i = index" class="row">
-  <div class="logs-header col-md-12"
-       *ngIf="!isServiceLogsFileView && (i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime))">
-    <div class="col-md-12">{{log.logtime | amTz: timeZone | amDateFormat: dateFormat}}</div>
-  </div>
-  <accordion-panel *ngIf="!isServiceLogsFileView" [toggleId]="'details-' + i" class="col-md-12">
-    <ng-template>
-      <div *ngIf="isColumnDisplayed('level')" [ngClass]="'hexagon ' + (log.level ? log.level.toLowerCase() : '')"></div>
-      <div class="col-md-1">
-        <dropdown-button iconClass="fa fa-ellipsis-h" [hideCaret]="true" [options]="logActions"
-                         [additionalArgs]="[log]"></dropdown-button>
-      </div>
-      <div *ngIf="isColumnDisplayed('level')" [ngClass]="'col-md-1 log-status ' + (log.level ? log.level.toLowerCase() : '')">
-        {{log.level}}
-      </div>
-      <div *ngIf="isColumnDisplayed('type') || isColumnDisplayed('logtime')" class="col-md-3">
-        <div *ngIf="isColumnDisplayed('type')" class="log-type">{{log.type}}</div>
-        <time *ngIf="isColumnDisplayed('logtime')" class="log-time">
-          {{log.logtime | amTz: timeZone | amDateFormat: timeFormat}}
-        </time>
-      </div>
-      <div class="col-md-6 log-content-wrapper">
-        <div class="collapse log-actions" attr.id="details-{{i}}">
-          <!-- TODO remove after restyling the table -->
-        </div>
-        <div class="log-content-inner-wrapper">
-          <div class="log-content" *ngIf="isColumnDisplayed('log_message')"
-               (contextmenu)="openMessageContextMenu($event)">{{log.log_message}}</div>
-        </div>
-      </div>
-      <div *ngFor="let column of displayedColumns">
-        <div *ngIf="customStyledColumns.indexOf(column.name) === -1" [innerHTML]="log[column.name]"
-             class="col-md-1"></div>
-      </div>
-    </ng-template>
-  </accordion-panel>
-  <log-file-entry *ngIf="isServiceLogsFileView" [time]="log.logtime" [level]="log.level"
-                  [fileName]="log.file" [lineNumber]="log.line_number" [message]="log.log_message"></log-file-entry>
+<div class="panel panel-default">
+ <div class="panel-body">
+   <table class="table table-hover">
+     <tbody>
+     <ng-container *ngFor="let log of logs; let i = index">
+         <tr *ngIf="!isServiceLogsFileView && (i === 0 || isDifferentDates(log.logtime, logs[i - 1].logtime))"
+                              class="log-date-row" >
+           <th attr.colspan="{{displayedColumns.length + 1}}">
+             {{log.logtime | amTz: timeZone | amDateFormat: dateFormat}}
+           </th>
+         </tr>
+         <tr class="log-item-row">
+           <td class="log-action">
+             <dropdown-button iconClass="fa fa-ellipsis-h action" [hideCaret]="true" [options]="logActions"
+                [additionalArgs]="[log]"></dropdown-button>
+           </td>
+           <td *ngIf="isColumnDisplayed('logtime')" class="log-time">
+             <time>
+               {{log.logtime | amTz: timeZone | amDateFormat: timeFormat}}
+             </time>
+           </td>
+           <td *ngIf="isColumnDisplayed('level')" [ngClass]="'log-level ' + log.level.toLowerCase()">
+             <log-level [logEntry]="log"></log-level>
+           </td>
+           <td *ngIf="isColumnDisplayed('type')" [ngClass]="'log-type'">
+             {{log.type}}
+           </td>
+           <td *ngIf="isColumnDisplayed('log_message')" [ngClass]="'log-message'" width="*"
+               (contextmenu)="openMessageContextMenu($event)">
+             <log-message [listenChangesOn]="displayedColumns">{{log.log_message}}</log-message>
+           </td>
+           <ng-container *ngFor="let column of displayedColumns">
+             <td *ngIf="customStyledColumns.indexOf(column.name) === -1"
+               [ngClass]="'log-' + column.name">{{log[column.name]}}</td>
+           </ng-container>
+         </tr>
+       </ng-container>
+   </tbody>
+     <tfoot>
+     <tr>
+         <td attr.colspan="{{displayedColumns.length + 1}}">
+           <pagination class="col-md-12" *ngIf="logs && logs.length" [totalCount]="totalCount"
+             [filtersForm]="filtersForm" [filterInstance]="filters.pageSize" [currentCount]="logs.length"></pagination>
+         </td>
+       </tr>
+   </tfoot>
+   </table>
+   <ul #contextmenu data-component="dropdown-list" class="dropdown-menu context-menu" [items]="contextMenuItems"
+                  (selectedItemChange)="updateQuery($event)"></ul>
+ </div>
 </div>
-<ul #contextmenu *ngIf="!isServiceLogsFileView" data-component="dropdown-list" class="dropdown-menu context-menu"
-    [items]="contextMenuItems" (selectedItemChange)="updateQuery($event)"></ul>
-<pagination class="pull-right" *ngIf="logs && logs.length" [totalCount]="totalCount" [filtersForm]="filtersForm"
-            [filterInstance]="filters.pageSize" [currentCount]="logs.length"></pagination>

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
index 67d0615..c5c4c5a 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-list/logs-list.component.less
@@ -17,93 +17,81 @@
 
 @import '../mixins';
 
-.logs-header {
-  // TODO get rid of magic numbers, base on actual design
-  margin: 10px 0;
-  padding: 5px 0;
-  background-color: @list-header-background-color; // TODO implement actual color
-  overflow: hidden;
-}
-
-/deep/ filter-dropdown {
-  justify-content: flex-end;
-}
-
-.hexagon {
-  // TODO remove, since it's not a part of updated design
-  left: -7.5px;
-
-  &.fatal {
-    .common-hexagon(15px, @fatal-color);
-  }
-
-  &.error {
-    .common-hexagon(15px, @error-color);
+:host {
+  /deep/ filter-dropdown {
+    justify-content: flex-end;
   }
 
-  &.warn {
-    .common-hexagon(15px, @warning-color);
+  .panel-body {
+    overflow: hidden;
+    width: 100%;
   }
 
-  &.info {
-    .common-hexagon(15px, @info-color);
+  table {
+    width: 100%;
   }
 
-  &.debug {
-    .common-hexagon(15px, @debug-color);
+  tr.log-date-row, tr.log-date-row:hover {
+    background: @list-header-background-color;
+    border: none transparent;
+    th {
+      border: none transparent;
+    }
   }
-
-  &.trace {
-    .common-hexagon(15px, @trace-color);
+  tr.log-item-row td {
+    background: none transparent;
   }
 
-  &.unknown {
-    .common-hexagon(15px, @unknown-color);
+  td {
+    &.log-action {
+      min-width: 3em;
+      /deep/ .btn, /deep/ .filter-label {
+        font-size: 1em;
+        height: auto;
+        line-height: 1em;
+        padding: 0;
+      }
+    }
+    &.log-time {
+      color: @grey-color;
+      min-width: 7em;
+      text-align: right;
+    }
+    &.log-level {
+      text-transform: uppercase;
+      min-width: 8em;
+      .log-colors;
+    }
+    &.log-type {
+      color: @link-color;
+    }
+    &.log-message, &.log-path {
+      width: 100%;
+    }
   }
-}
-
-.log-status {
-  text-transform: uppercase;
-  .log-colors;
-}
-
-.log-type {
-  color: @link-color;
-}
-
-.log-time {
-  color: @grey-color;
-}
-
-.log-content-wrapper {
-  position: relative;
 
-  // TODO get rid of magic numbers, base on actual design
-  .log-content-inner-wrapper {
-    overflow: hidden;
-    max-height: @default-line-height * 2em;
-    padding-right: 65px;
-
-    .log-content {
-      white-space: pre-wrap;
+  tr:hover td.log-action {
+    /deep/ .btn {
+      display: inline-block;
     }
   }
 
-  .log-actions {
-    &.collapsing + .log-content-inner-wrapper, &.collapse.in + .log-content-inner-wrapper {
-      min-height: 6em;
-      max-height: none;
-      overflow-x: auto;
+  .table.table-hover>tbody>tr{
+    box-sizing: border-box;
+    border-width: 1px;
+    >td {
+      border-top: 0 none;
     }
-
-    .action-icon {
-      .clickable-item;
-      display: block;
-      padding: 5px;
+    &:first-of-type {
+      border-top-color: transparent;
+    }
+    &:last-of-type {
+      border-bottom-color: transparent;
     }
   }
-}
 
-.context-menu {
-  position: fixed;
+  .context-menu {
+    position: fixed;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/38476f7a/ambari-logsearch/ambari-logsearch-web/webpack.config.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/webpack.config.js b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
index 7a60df2..75d6aee 100644
--- a/ambari-logsearch/ambari-logsearch-web/webpack.config.js
+++ b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
@@ -81,18 +81,17 @@ module.exports = {
   "resolve": {
     "extensions": [
       ".ts",
-      ".js"
+      ".js",
+      ".less"
     ],
     "modules": [
-      "./node_modules",
-      "./node_modules"
+      "node_modules"
     ],
     "symlinks": true
   },
   "resolveLoader": {
     "modules": [
-      "./node_modules",
-      "./node_modules"
+      "node_modules"
     ]
   },
   "entry": {
@@ -229,7 +228,9 @@ module.exports = {
             "loader": "less-loader",
             "options": {
               "sourceMap": false,
-              "paths": []
+              "paths": [
+                "./node_modules"
+              ]
             }
           }
         ]
@@ -359,7 +360,7 @@ module.exports = {
             "loader": "less-loader",
             "options": {
               "sourceMap": false,
-              "paths": []
+              "paths": ["./node_modules"]
             }
           }
         ]


[30/51] [abbrv] ambari git commit: AMBARI-22379 : get_phoenix_query_server_hosts is undefined in hbase service_advisor. (Ted Yu via avijayan)

Posted by nc...@apache.org.
AMBARI-22379 : get_phoenix_query_server_hosts is undefined in hbase service_advisor. (Ted Yu via avijayan)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: b04e142b3f80d4713ed154e17c0ab877d46500a4
Parents: 08d3826
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Wed Nov 8 11:14:54 2017 -0800
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Wed Nov 8 11:14:54 2017 -0800

----------------------------------------------------------------------
 .../common-services/HBASE/2.0.0.3.0/service_advisor.py  | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b04e142b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
index f9d1a59..9dc5708 100644
--- a/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
+++ b/ambari-server/src/main/resources/common-services/HBASE/2.0.0.3.0/service_advisor.py
@@ -461,6 +461,16 @@ class HBASERecommender(service_advisor.ServiceAdvisor):
     else:
       putHbaseSiteProperty('hbase.master.ui.readonly', 'false')
 
+  """
+  Returns the list of Phoenix Query Server host names, or None.
+  """
+  def get_phoenix_query_server_hosts(self, services, hosts):
+    if len(hosts['items']) > 0:
+      phoenix_query_server_hosts = self.getHostsWithComponent("HBASE", "PHOENIX_QUERY_SERVER", services, hosts)
+      if phoenix_query_server_hosts is None:
+        return []
+      return [host['Hosts']['host_name'] for host in phoenix_query_server_hosts]
+
 
   def recommendHBASEConfigurationsFromHDP26(self, configurations, clusterData, services, hosts):
     if 'hbase-env' in services['configurations'] and 'hbase_user' in services['configurations']['hbase-env']['properties']:
@@ -672,4 +682,4 @@ class HBASEValidator(service_advisor.ServiceAdvisor):
                                   " {0} needs to contain {1} instead of {2}".format(prop_name,prop_val,exclude_val))})
 
     validationProblems = self.toConfigurationValidationProblems(validationItems, "hbase-site")
-    return validationProblems
\ No newline at end of file
+    return validationProblems


[51/51] [abbrv] ambari git commit: Merge branch 'trunk' into branch-feature-AMBARI-21674

Posted by nc...@apache.org.
Merge branch 'trunk' into branch-feature-AMBARI-21674


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: ff8f686f85e7a97f1fee87646686b02b296a5481
Parents: c839dbf 6e706d4
Author: Nate Cole <nc...@hortonworks.com>
Authored: Mon Nov 13 11:56:52 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Nov 13 11:56:52 2017 -0500

----------------------------------------------------------------------
 ambari-admin/pom.xml                            |    2 +-
 .../app/assets/fonts/Roboto-Regular-webfont.eot |  Bin 0 -> 79547 bytes
 .../app/assets/fonts/Roboto-Regular-webfont.svg | 7606 ++++++++++++++++++
 .../app/assets/fonts/Roboto-Regular-webfont.ttf |  Bin 0 -> 234464 bytes
 .../assets/fonts/Roboto-Regular-webfont.woff    |  Bin 0 -> 105700 bytes
 .../main/resources/ui/admin-web/app/index.html  |   82 +-
 .../app/scripts/controllers/AppCtrl.js          |  177 +
 .../controllers/ClusterInformationCtrl.js       |   65 +
 .../app/scripts/controllers/NavbarCtrl.js       |  106 -
 .../app/scripts/controllers/SideNavCtrl.js      |   68 +
 .../ambariViews/CloneViewInstanceCtrl.js        |  274 +
 .../ambariViews/CreateViewInstanceCtrl.js       |  353 +-
 .../controllers/ambariViews/ViewsListCtrl.js    |  360 +-
 .../controllers/clusters/ExportBlueprintCtrl.js |   58 -
 .../app/scripts/controllers/mainCtrl.js         |  183 -
 .../ui/admin-web/app/scripts/i18n.config.js     |   38 +-
 .../ui/admin-web/app/scripts/routes.js          |  134 +-
 .../ui/admin-web/app/scripts/services/View.js   |   32 +-
 .../app/scripts/theme/bootstrap-ambari.js       |  269 +
 .../app/styles/cluster-information.css          |   59 +
 .../resources/ui/admin-web/app/styles/main.css  |  566 +-
 .../app/styles/theme/bootstrap-ambari.css       | 1518 ++++
 .../ui/admin-web/app/styles/top-nav.css         |  197 +
 .../resources/ui/admin-web/app/styles/views.css |   49 +
 .../app/views/ambariViews/listTable.html        |  110 -
 .../app/views/ambariViews/listUrls.html         |  117 -
 .../app/views/ambariViews/modals/create.html    |  238 +-
 .../app/views/ambariViews/modals/edit.html      |  138 -
 .../app/views/ambariViews/viewsList.html        |  134 +
 .../admin-web/app/views/clusterInformation.html |   66 +
 .../app/views/clusters/exportBlueprint.html     |   40 -
 .../ui/admin-web/app/views/groups/list.html     |    7 +-
 .../ui/admin-web/app/views/leftNavbar.html      |  126 -
 .../resources/ui/admin-web/app/views/main.html  |   96 -
 .../app/views/remoteClusters/list.html          |    6 +-
 .../ui/admin-web/app/views/sideNav.html         |  113 +
 .../admin-web/app/views/stackVersions/list.html |    8 +-
 .../ui/admin-web/app/views/urls/create.html     |    4 +-
 .../ui/admin-web/app/views/urls/edit.html       |    4 +-
 .../ui/admin-web/app/views/users/list.html      |    7 +-
 .../src/main/resources/ui/admin-web/bower.json  |    2 +-
 .../src/main/resources/ui/admin-web/gulpfile.js |   10 +-
 .../main/resources/ui/admin-web/package.json    |    6 +-
 .../test/unit/controllers/AppCtrl_test.js       |  211 +
 .../unit/controllers/CloneViewInstanceCtrl.js   |  135 +
 .../unit/controllers/CreateViewInstanceCtrl.js  |  135 -
 .../test/unit/controllers/mainCtrl_test.js      |  215 -
 .../test/unit/services/Utility_test.js          |    3 +-
 .../src/main/python/ambari_agent/AmbariAgent.py |    3 -
 .../python/ambari_agent/alerts/base_alert.py    |    2 +-
 .../libraries/functions/__init__.py             |    1 -
 .../libraries/functions/conf_select.py          |   58 +
 .../libraries/functions/curl_krb_request.py     |   22 +-
 .../libraries/functions/get_lzo_packages.py     |   50 -
 .../libraries/functions/package_conditions.py   |   14 +-
 .../libraries/functions/stack_select.py         |    3 +-
 ambari-logsearch/README.md                      |   26 +-
 .../ambari-logsearch-logfeeder/README.md        |   17 +-
 .../ambari-logsearch-logfeeder/pom.xml          |    6 +-
 .../src/main/resources/log-samples/.gitignore   |    4 +
 .../log-samples/logs/service_sample.txt         |    3 +
 .../log-samples/shipper-conf/global.config.json |   10 +
 .../shipper-conf/input.config-sample.json       |   31 +
 .../shipper-conf/output.config-sample.json      |   34 +
 .../src/main/resources/log4j.xml                |    4 +-
 .../src/main/resources/logfeeder.properties     |   31 +-
 .../ambari-logsearch-server/.gitignore          |    1 +
 .../ambari-logsearch-server/README.md           |   44 +-
 .../ambari-logsearch-server/pom.xml             |    2 +-
 ambari-logsearch/ambari-logsearch-server/run.sh |    2 +-
 .../ambari/logsearch/conf/AuthPropsConfig.java  |   18 +
 .../ambari/logsearch/conf/SecurityConfig.java   |    6 +-
 .../LogsearchAuthenticationEntryPoint.java      |    2 +-
 .../src/main/resources/logsearch.properties     |   54 +-
 .../ambari-logsearch-web/src/app/app.module.ts  |    8 +-
 .../src/app/classes/filtering.ts                |  355 +-
 .../src/app/classes/models/app-state.ts         |    6 +-
 .../src/app/classes/models/node-item.ts         |   30 +
 .../src/app/classes/models/node.ts              |   30 -
 .../src/app/classes/models/store.ts             |    6 +-
 .../src/app/classes/models/tab.ts               |   12 +-
 .../action-menu/action-menu.component.html      |   20 +
 .../action-menu/action-menu.component.less      |   27 +
 .../action-menu/action-menu.component.spec.ts   |   47 +
 .../action-menu/action-menu.component.ts        |  105 +
 .../src/app/components/app.component.html       |    4 +-
 .../src/app/components/app.component.less       |    5 +-
 .../src/app/components/app.component.ts         |    6 +-
 .../dropdown-button.component.html              |    4 +-
 .../dropdown-button.component.spec.ts           |    2 -
 .../dropdown-button.component.ts                |   55 +-
 .../dropdown-list/dropdown-list.component.html  |    2 +-
 .../dropdown-list.component.spec.ts             |    6 +-
 .../filter-button.component.spec.ts             |    2 -
 .../filter-button/filter-button.component.ts    |   35 +-
 .../filter-dropdown.component.spec.ts           |   14 +-
 .../filter-dropdown.component.ts                |   22 +-
 .../filters-panel/filters-panel.component.html  |    6 +-
 .../filters-panel.component.spec.ts             |    6 +-
 .../filters-panel/filters-panel.component.ts    |   18 +-
 .../log-context/log-context.component.spec.ts   |    4 +-
 .../log-level/log-level.component.html          |   18 +
 .../log-level/log-level.component.spec.ts       |   73 +
 .../components/log-level/log-level.component.ts |   52 +
 .../log-message/log-message.component.html      |   24 +
 .../log-message/log-message.component.less      |   69 +
 .../log-message/log-message.component.spec.ts   |   64 +
 .../log-message/log-message.component.ts        |  129 +
 .../logs-container.component.html               |   58 +-
 .../logs-container.component.less               |    3 +
 .../logs-container.component.spec.ts            |    2 -
 .../logs-container/logs-container.component.ts  |   26 +-
 .../logs-list/logs-list.component.html          |   95 +-
 .../logs-list/logs-list.component.less          |  130 +-
 .../logs-list/logs-list.component.spec.ts       |   21 +-
 .../components/logs-list/logs-list.component.ts |   10 +-
 .../main-container.component.html               |    2 +-
 .../menu-button/menu-button.component.html      |   17 +-
 .../menu-button/menu-button.component.less      |   22 +-
 .../menu-button/menu-button.component.spec.ts   |    2 -
 .../menu-button/menu-button.component.ts        |  146 +-
 .../src/app/components/mixins.less              |    5 +
 .../pagination-controls.component.html          |   15 +-
 .../pagination-controls.component.spec.ts       |  101 +
 .../pagination-controls.component.ts            |   76 +-
 .../pagination/pagination.component.html        |    2 +-
 .../pagination/pagination.component.spec.ts     |    9 +-
 .../pagination/pagination.component.ts          |   10 +-
 .../search-box/search-box.component.ts          |   12 +-
 .../time-range-picker.component.html            |    3 +-
 .../time-range-picker.component.spec.ts         |   29 +-
 .../time-range-picker.component.ts              |   47 +-
 .../timezone-picker.component.spec.ts           |    2 -
 .../components/top-menu/top-menu.component.html |   10 +-
 .../components/top-menu/top-menu.component.less |    1 +
 .../components/top-menu/top-menu.component.ts   |   83 +-
 .../src/app/components/variables.less           |    3 +
 .../services/component-actions.service.spec.ts  |    2 -
 .../app/services/component-actions.service.ts   |   24 +-
 .../component-generator.service.spec.ts         |    2 -
 .../src/app/services/filtering.service.spec.ts  |   97 -
 .../src/app/services/filtering.service.ts       |  253 -
 .../app/services/logs-container.service.spec.ts |   31 +-
 .../src/app/services/logs-container.service.ts  |  678 +-
 .../src/app/services/utils.service.spec.ts      |  285 +-
 .../src/app/services/utils.service.ts           |   65 +-
 .../ambari-logsearch-web/webpack.config.js      |   15 +-
 ambari-logsearch/docker/Dockerfile              |    6 -
 ambari-logsearch/docker/docker-compose.yml      |    4 +-
 ambari-logsearch/docker/logsearch-docker.sh     |    1 +
 .../docs/security/kerberos/kerberos_service.md  |   22 +-
 ambari-server/pom.xml                           |   12 +
 .../ambari/server/agent/ExecutionCommand.java   |   34 +-
 .../ambari/server/agent/HeartbeatProcessor.java |   72 +-
 .../ambari/server/checks/CheckDescription.java  |    9 +
 .../apache/ambari/server/checks/LZOCheck.java   |   76 +
 .../AmbariCustomCommandExecutionHelper.java     |   23 +-
 .../AmbariManagementControllerImpl.java         |   60 +-
 .../controller/DeleteIdentityHandler.java       |    3 +-
 .../server/controller/KerberosHelper.java       |   21 +-
 .../server/controller/KerberosHelperImpl.java   |  138 +-
 .../ClusterStackVersionResourceProvider.java    |   41 +-
 .../HostKerberosIdentityResourceProvider.java   |   16 +-
 .../HostStackVersionResourceProvider.java       |    2 +-
 .../internal/UpgradeResourceProvider.java       |   12 +-
 .../ServiceComponentUninstalledEvent.java       |   11 +-
 .../server/orm/dao/KerberosKeytabDAO.java       |  110 +
 .../server/orm/dao/KerberosPrincipalDAO.java    |    7 +
 .../orm/dao/KerberosPrincipalHostDAO.java       |   40 +-
 .../orm/entities/KerberosKeytabEntity.java      |   86 +
 .../entities/KerberosPrincipalHostEntity.java   |   57 +-
 .../entities/KerberosPrincipalHostEntityPK.java |   19 +-
 .../serveraction/ServerActionExecutor.java      |  147 +-
 .../kerberos/ADKerberosOperationHandler.java    |   22 +-
 .../AbstractPrepareKerberosServerAction.java    |   29 +-
 .../kerberos/CleanupServerAction.java           |   14 +-
 .../server/serveraction/kerberos/Component.java |   13 +-
 .../ConfigureAmbariIdentitiesServerAction.java  |   31 +-
 .../kerberos/CreateKeytabFilesServerAction.java |   65 +-
 .../kerberos/CreatePrincipalsServerAction.java  |   52 +-
 .../kerberos/DestroyPrincipalsServerAction.java |    3 +-
 .../kerberos/IPAKerberosOperationHandler.java   | 1067 +--
 .../kerberos/KDCKerberosOperationHandler.java   |  391 +
 .../kerberos/KerberosIdentityDataFile.java      |    2 -
 .../KerberosIdentityDataFileWriter.java         |    9 +-
 .../kerberos/KerberosOperationHandler.java      |   64 +-
 .../kerberos/KerberosServerAction.java          |   27 +-
 .../kerberos/MITKerberosOperationHandler.java   |  406 +-
 .../PrepareDisableKerberosServerAction.java     |    2 +-
 .../PrepareEnableKerberosServerAction.java      |    2 +-
 .../PrepareKerberosIdentitiesServerAction.java  |    3 +-
 .../stageutils/ResolvedKerberosKeytab.java      |  257 +
 .../upgrades/PreconfigureKerberosAction.java    |   48 +-
 .../ambari/server/stack/ServiceDirectory.java   |   29 +
 .../ambari/server/stack/ServiceModule.java      |    8 +
 .../apache/ambari/server/state/ServiceImpl.java |    2 +-
 .../apache/ambari/server/state/ServiceInfo.java |   14 +
 .../state/repository/ClusterVersionSummary.java |    3 +
 .../state/repository/ServiceVersionSummary.java |   11 +-
 .../state/repository/VersionDefinitionXml.java  |   25 +-
 .../stack/upgrade/RepositoryVersionHelper.java  |   28 +-
 .../svccomphost/ServiceComponentHostImpl.java   |    2 +-
 .../server/upgrade/UpgradeCatalog300.java       |   30 +-
 .../ambari/server/utils/VersionUtils.java       |   46 +-
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |   15 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |   13 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |   13 +-
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |   11 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |   13 +-
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |   13 +-
 .../src/main/resources/META-INF/persistence.xml |    1 +
 .../ATLAS/0.1.0.2.3/package/scripts/params.py   |    2 +-
 .../ATLAS/0.7.0.3.0/package/scripts/params.py   |    2 +-
 .../DRUID/0.10.1/package/scripts/druid.py       |    3 +-
 .../DRUID/0.10.1/package/scripts/params.py      |    3 +-
 .../FALCON/0.5.0.2.1/package/scripts/falcon.py  |   11 +-
 .../HBASE/2.0.0.3.0/service_advisor.py          |   12 +-
 .../common-services/HDFS/2.1.0.2.0/metainfo.xml |   30 -
 .../HDFS/2.1.0.2.0/package/scripts/datanode.py  |    1 -
 .../HDFS/2.1.0.2.0/package/scripts/hdfs.py      |    7 -
 .../2.1.0.2.0/package/scripts/hdfs_client.py    |    1 -
 .../2.1.0.2.0/package/scripts/install_params.py |    1 +
 .../2.1.0.2.0/package/scripts/journalnode.py    |    1 -
 .../HDFS/2.1.0.2.0/package/scripts/namenode.py  |    1 -
 .../common-services/HDFS/3.0.0.3.0/metainfo.xml |   30 -
 .../HDFS/3.0.0.3.0/package/scripts/hdfs.py      |    7 -
 .../HIVE/0.12.0.2.0/configuration/hive-site.xml |   38 +
 .../HIVE/0.12.0.2.0/metainfo.xml                |    5 -
 .../package/alerts/alert_hive_thrift_port.py    |    3 +-
 .../0.12.0.2.0/package/files/startMetastore.sh  |    4 +-
 .../0.12.0.2.0/package/scripts/hive_service.py  |   10 +-
 .../package/scripts/hive_service_interactive.py |    5 +-
 .../0.12.0.2.0/package/scripts/params_linux.py  |    3 +-
 .../0.12.0.2.0/package/scripts/service_check.py |    6 +-
 .../package/scripts/webhcat_service.py          |   19 +-
 .../common-services/HIVE/2.1.0.3.0/metainfo.xml |   10 -
 .../2.1.0.3.0/package/files/startMetastore.sh   |    4 +-
 .../2.1.0.3.0/package/scripts/hive_service.py   |    8 +-
 .../package/scripts/hive_service_interactive.py |    5 +-
 .../2.1.0.3.0/package/scripts/params_linux.py   |   10 +-
 .../2.1.0.3.0/package/scripts/service_check.py  |    6 +-
 .../package/scripts/webhcat_service.py          |   19 +-
 .../1.10.3-10/configuration/kerberos-env.xml    |   36 +-
 .../package/scripts/kerberos_common.py          |    7 +-
 .../1.10.3-30/configuration/kerberos-env.xml    |   36 +-
 .../package/scripts/kerberos_common.py          |    7 +-
 .../LOGSEARCH/0.5.0/metainfo.xml                |    6 +-
 .../1.0.0.2.3/package/scripts/service_check.py  |    3 +-
 .../OOZIE/4.0.0.2.0/package/scripts/oozie.py    |    6 +-
 .../package/scripts/oozie_server_upgrade.py     |    7 +-
 .../4.0.0.2.0/package/scripts/params_linux.py   |    1 +
 .../OOZIE/4.2.0.2.3/metainfo.xml                |    5 -
 .../OOZIE/4.2.0.3.0/metainfo.xml                |    5 -
 .../OOZIE/4.2.0.3.0/package/scripts/oozie.py    |    4 -
 .../package/scripts/oozie_server_upgrade.py     |    5 +
 .../scripts/alerts/alert_spark_thrift_port.py   |    8 +-
 .../SPARK/1.2.1/package/scripts/setup_spark.py  |    3 +-
 .../scripts/alerts/alert_spark2_thrift_port.py  |    8 +-
 .../SPARK2/2.0.0/package/scripts/setup_spark.py |    3 +-
 .../SQOOP/1.4.4.2.0/metainfo.xml                |    5 -
 .../1.4.4.2.0/package/scripts/params_linux.py   |    4 +-
 .../SQOOP/1.4.4.3.0/metainfo.xml                |   10 -
 .../1.4.4.3.0/package/scripts/params_linux.py   |    4 +-
 .../0.4.0.2.1/package/scripts/params_linux.py   |    2 +-
 .../TEZ/0.4.0.2.1/package/scripts/tez_client.py |   32 -
 .../TEZ/0.9.0.3.0/configuration/tez-site.xml    |    2 +-
 .../0.9.0.3.0/package/scripts/params_linux.py   |    2 +-
 .../TEZ/0.9.0.3.0/package/scripts/tez_client.py |   26 -
 .../configuration-mapred/mapred-site.xml        |    2 +-
 .../2.1.0.2.0/package/scripts/params_linux.py   |    2 +-
 .../configuration-mapred/mapred-site.xml        |    2 +-
 .../3.0.0.3.0/package/scripts/params_linux.py   |    2 +-
 .../ZEPPELIN/0.7.0/package/scripts/master.py    |   11 +-
 .../custom_actions/scripts/install_packages.py  |   12 +-
 .../custom_actions/scripts/remove_bits.py       |    2 +-
 .../BIGTOP/0.8/services/HDFS/metainfo.xml       |   16 -
 .../0.8/services/HDFS/package/scripts/params.py |    6 +-
 .../BIGTOP/0.8/services/HIVE/metainfo.xml       |    4 -
 .../BIGTOP/0.8/services/OOZIE/metainfo.xml      |    4 -
 .../2.0.6.GlusterFS/services/HIVE/metainfo.xml  |    4 -
 .../2.0.6.GlusterFS/services/OOZIE/metainfo.xml |    4 -
 .../HDP/2.0.6/properties/stack_features.json    |    5 +
 .../HDP/2.0.6/properties/stack_packages.json    |  104 +-
 .../2.1.GlusterFS/services/HIVE/metainfo.xml    |    4 -
 .../2.1.GlusterFS/services/OOZIE/metainfo.xml   |    4 -
 .../stacks/HDP/2.1/services/HIVE/metainfo.xml   |    5 -
 .../stacks/HDP/2.2/services/HDFS/metainfo.xml   |   35 -
 .../stacks/HDP/2.2/services/HIVE/metainfo.xml   |   10 -
 .../stacks/HDP/2.2/services/OOZIE/metainfo.xml  |    5 -
 .../stacks/HDP/2.2/services/SQOOP/metainfo.xml  |   10 -
 .../2.2/services/TEZ/configuration/tez-site.xml |    4 +-
 .../YARN/configuration-mapred/mapred-site.xml   |    2 +-
 .../2.3.GlusterFS/services/HDFS/metainfo.xml    |   10 -
 .../2.3.GlusterFS/services/HIVE/metainfo.xml    |    9 -
 .../2.3.GlusterFS/services/SQOOP/metainfo.xml   |    9 -
 .../main/resources/stacks/HDP/2.3/metainfo.xml  |    2 +-
 .../stacks/HDP/2.3/services/HDFS/metainfo.xml   |   30 -
 .../stacks/HDP/2.3/services/HIVE/metainfo.xml   |   10 -
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml |    1 +
 .../stacks/HDP/2.3/upgrades/upgrade-2.6.xml     |    1 +
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml |    1 +
 .../stacks/HDP/2.4/upgrades/upgrade-2.6.xml     |    1 +
 .../stacks/HDP/2.5/services/FALCON/metainfo.xml |    4 +-
 .../stacks/HDP/2.5/services/HIVE/metainfo.xml   |   10 -
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml |    1 +
 .../stacks/HDP/2.5/upgrades/upgrade-2.6.xml     |    1 +
 .../resources/stacks/HDP/2.6/repos/repoinfo.xml |    2 +-
 .../stacks/HDP/2.6/upgrades/config-upgrade.xml  |   23 +
 .../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml |   10 +
 .../stacks/HDP/2.6/upgrades/upgrade-2.6.xml     |    5 +
 .../HDP/3.0/properties/stack_packages.json      |  108 +-
 .../stacks/HDP/3.0/services/HDFS/metainfo.xml   |   30 -
 .../YARN/configuration-mapred/mapred-site.xml   |    2 +-
 .../resources/stacks/PERF/1.0/hdp_urlinfo.json  |   12 +
 .../stacks/PERF/1.0/repos/repoinfo.xml          |    1 +
 .../KERBEROS/configuration/kerberos-env.xml     |   36 +-
 .../src/main/resources/stacks/PERF/1.0/vdf.xml  |   73 +
 .../resources/stacks/PERF/2.0/hdp_urlinfo.json  |   12 +
 .../stacks/PERF/2.0/repos/repoinfo.xml          |    1 +
 .../src/main/resources/stacks/PERF/2.0/vdf.xml  |   74 +
 .../server/agent/TestHeartbeatHandler.java      |    2 +-
 .../ambari/server/checks/LZOCheckTest.java      |  145 +
 .../AmbariManagementControllerImplTest.java     |    2 +-
 .../server/controller/KerberosHelperTest.java   |   12 +-
 ...ClusterStackVersionResourceProviderTest.java |  239 +
 ...ostKerberosIdentityResourceProviderTest.java |   12 +-
 .../internal/UpgradeResourceProviderTest.java   |    8 +
 .../utilities/KerberosIdentityCleanerTest.java  |   10 +-
 .../HostVersionOutOfSyncListenerTest.java       |    2 +-
 .../ADKerberosOperationHandlerTest.java         |  261 +-
 ...AbstractPrepareKerberosServerActionTest.java |   11 +-
 ...nfigureAmbariIdentitiesServerActionTest.java |   11 +-
 .../FinalizeKerberosServerActionTest.java       |    5 +
 .../IPAKerberosOperationHandlerTest.java        |  147 +-
 .../KDCKerberosOperationHandlerTest.java        |  168 +
 .../kerberos/KerberosIdentityDataFileTest.java  |    8 +-
 .../kerberos/KerberosOperationHandlerTest.java  |  152 +-
 .../kerberos/KerberosServerActionTest.java      |  137 +-
 .../MITKerberosOperationHandlerTest.java        |  633 +-
 .../PreconfigureKerberosActionTest.java         |   10 +
 .../ambari/server/stack/ServiceModuleTest.java  |   30 +
 .../server/stack/StackManagerExtensionTest.java |    6 +
 .../state/repository/VersionDefinitionTest.java |   42 +
 .../server/upgrade/UpgradeCatalog300Test.java   |  152 +-
 .../ambari/server/utils/TestVersionUtils.java   |    4 +
 .../python/custom_actions/TestRemoveBits.py     |    5 +-
 .../stacks/2.0.6/HIVE/test_hive_metastore.py    |    8 +-
 .../stacks/2.0.6/HIVE/test_hive_server.py       |   18 +-
 .../2.0.6/HIVE/test_hive_service_check.py       |    2 +-
 .../stacks/2.0.6/HIVE/test_webhcat_server.py    |    4 -
 .../stacks/2.1/FALCON/test_falcon_server.py     |   10 +-
 .../stacks/2.1/HIVE/test_hive_metastore.py      |    9 +-
 .../python/stacks/2.1/TEZ/test_tez_client.py    |    2 +-
 .../stacks/2.2/SPARK/test_job_history_server.py |   12 +-
 .../stacks/2.2/SPARK/test_spark_client.py       |   12 +-
 .../stacks/2.2/common/test_conf_select.py       |   14 +-
 .../2.3/MAHOUT/test_mahout_service_check.py     |    4 +-
 .../2.3/SPARK/test_spark_thrift_server.py       |    6 +-
 .../stacks/2.5/HIVE/test_hive_server_int.py     |   15 +-
 .../2.5/configs/ranger-admin-secured.json       |    2 -
 .../stacks/2.5/configs/ranger-kms-secured.json  |    2 -
 .../2.6/configs/ranger-admin-secured.json       |    2 -
 .../PreconfigureActionTest_cluster_config.json  |    4 +-
 ambari-web/app/config.js                        |    1 -
 .../app/controllers/global/update_controller.js |    2 +-
 .../main/admin/kerberos/step1_controller.js     |   52 +-
 .../main/admin/kerberos/step2_controller.js     |    2 +-
 .../main/host/bulk_operations_controller.js     |   14 +-
 ambari-web/app/controllers/main/service/item.js |   13 +-
 .../app/mappers/components_state_mapper.js      |    1 +
 ambari-web/app/messages.js                      |    3 +-
 ambari-web/app/models/client_component.js       |    1 +
 .../app/styles/theme/bootstrap-ambari.css       |   35 +-
 .../admin/kerberos/step1_controller_test.js     |   17 -
 .../admin/kerberos/step2_controller_test.js     |    2 +-
 .../test/controllers/main/service/item_test.js  |   49 +-
 .../vendor/scripts/theme/bootstrap-ambari.js    |    7 -
 .../stacks/ODPi/2.0/services/HIVE/metainfo.xml  |   10 -
 378 files changed, 18632 insertions(+), 7207 deletions(-)
----------------------------------------------------------------------



[12/51] [abbrv] ambari git commit: AMBARI-22292. PU: Could not install version when only build changes (ncole)

Posted by nc...@apache.org.
AMBARI-22292. PU: Could not install version when only build changes (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 65ea560d712df357722d811984069cad2f3540e0
Parents: 68bc38e
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 3 10:10:26 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 3 10:10:26 2017 -0400

----------------------------------------------------------------------
 .../ClusterStackVersionResourceProvider.java    | 38 +----------------
 .../state/repository/VersionDefinitionXml.java  | 15 +++++--
 .../ambari/server/utils/VersionUtils.java       | 44 ++++++++++++++++++++
 .../state/repository/VersionDefinitionTest.java | 34 +++++++++++++++
 .../ambari/server/utils/TestVersionUtils.java   |  3 ++
 5 files changed, 95 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
index 1a75559..969fca1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterStackVersionResourceProvider.java
@@ -88,7 +88,6 @@ import org.apache.ambari.server.utils.StageUtils;
 import org.apache.ambari.server.utils.VersionUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.NumberUtils;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
@@ -258,7 +257,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
       Collections.sort(entities, new Comparator<RepositoryVersionEntity>() {
         @Override
         public int compare(RepositoryVersionEntity o1, RepositoryVersionEntity o2) {
-          return compareVersions(o1.getVersion(), o2.getVersion());
+          return VersionUtils.compareVersionsWithBuild(o1.getVersion(), o2.getVersion(), 4);
         }
       });
 
@@ -502,7 +501,7 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
           continue;
         }
 
-        int compare = compareVersions(hostRepoVersion.getVersion(), desiredRepoVersion);
+        int compare = VersionUtils.compareVersionsWithBuild(hostRepoVersion.getVersion(), desiredRepoVersion, 4);
 
         // ignore earlier versions
         if (compare <= 0) {
@@ -806,39 +805,6 @@ public class ClusterStackVersionResourceProvider extends AbstractControllerResou
   }
 
   /**
-   * Additional check over {@link VersionUtils#compareVersions(String, String)} that
-   * compares build numbers
-   */
-  private static int compareVersions(String version1, String version2) {
-    version1 = (null == version1) ? "0" : version1;
-    version2 = (null == version2) ? "0" : version2;
-
-    // check _exact_ equality
-    if (StringUtils.equals(version1, version2)) {
-      return 0;
-    }
-
-    int compare = VersionUtils.compareVersions(version1, version2);
-    if (0 != compare) {
-      return compare;
-    }
-
-    int v1 = 0;
-    int v2 = 0;
-    if (version1.indexOf('-') > -1) {
-      v1 = NumberUtils.toInt(version1.substring(version1.indexOf('-')), 0);
-    }
-
-    if (version2.indexOf('-') > -1) {
-      v2 = NumberUtils.toInt(version2.substring(version2.indexOf('-')), 0);
-    }
-
-    compare = v2 - v1;
-
-    return Integer.compare(compare, 0);
-  }
-
-  /**
    * Ensures that the stack tools and stack features are set on
    * {@link ConfigHelper#CLUSTER_ENV} for the stack of the repository being
    * distributed. This step ensures that the new repository can be distributed

http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 1dda0b1..634ab04 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -308,12 +308,21 @@ public class VersionDefinitionXml {
       // !!! currently only one version is supported (unique service names)
       ManifestService manifest = manifests.get(serviceName);
 
-      summary.setVersions(manifest.version, StringUtils.isEmpty(manifest.releaseVersion) ?
-          release.version : manifest.releaseVersion);
+      final String versionToCompare;
+      final String summaryReleaseVersion;
+      if (StringUtils.isEmpty(manifest.releaseVersion)) {
+        versionToCompare = release.getFullVersion();
+        summaryReleaseVersion = release.version;
+      } else {
+        versionToCompare = manifest.releaseVersion;
+        summaryReleaseVersion = manifest.releaseVersion;
+      }
+
+      summary.setVersions(manifest.version, summaryReleaseVersion);
 
       // !!! installed service already meets the release version, then nothing to upgrade
       // !!! TODO should this be using the release compatible-with field?
-      if (VersionUtils.compareVersions(summary.getReleaseVersion(), serviceVersion, 4) > 0) {
+      if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
         summary.setUpgrade(true);
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
index 08948e1..6a3d81c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/VersionUtils.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.ambari.server.bootstrap.BootStrapImpl;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
 
 /**
  * Provides various utility functions to be used for version handling.
@@ -212,4 +213,47 @@ public class VersionUtils {
 
     return versionParts[0] + "." + versionParts[1] + "." + versionParts[2];
   }
+
+  /**
+   * Compares versions, using a build number using a dash separator, if one exists.
+   * This is is useful when comparing repository versions with one another that include
+   * build number
+   * @param version1
+   *          the first version
+   * @param version2
+   *          the second version
+   * @param places
+   *          the number of decimal-separated places to compare
+   * @return
+   */
+  public static int compareVersionsWithBuild(String version1, String version2, int places) {
+    version1 = (null == version1) ? "0" : version1;
+    version2 = (null == version2) ? "0" : version2;
+
+    // check _exact_ equality
+    if (StringUtils.equals(version1, version2)) {
+      return 0;
+    }
+
+    int compare = VersionUtils.compareVersions(version1, version2, places);
+    if (0 != compare) {
+      return compare;
+    }
+
+    int v1 = 0;
+    int v2 = 0;
+    if (version1.indexOf('-') > -1) {
+      v1 = NumberUtils.toInt(version1.substring(version1.indexOf('-')), 0);
+    }
+
+    if (version2.indexOf('-') > -1) {
+      v2 = NumberUtils.toInt(version2.substring(version2.indexOf('-')), 0);
+    }
+
+    compare = v2 - v1;
+
+    return Integer.compare(compare, 0);
+
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
index 8433518..370a14f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
@@ -429,7 +429,41 @@ public class VersionDefinitionTest {
     xml = VersionDefinitionXml.load(f.toURI().toURL());
     summary = xml.getClusterSummary(cluster);
     assertEquals(1, summary.getAvailableServiceNames().size());
+  }
+
+  @Test
+  public void testAvailableBuildVersion() throws Exception {
+
+    Cluster cluster = createNiceMock(Cluster.class);
+    RepositoryVersionEntity repositoryVersion = createNiceMock(RepositoryVersionEntity.class);
+    expect(repositoryVersion.getVersion()).andReturn("2.3.4.1-1").atLeastOnce();
 
+    Service serviceHdfs = createNiceMock(Service.class);
+    expect(serviceHdfs.getName()).andReturn("HDFS").atLeastOnce();
+    expect(serviceHdfs.getDisplayName()).andReturn("HDFS").atLeastOnce();
+    expect(serviceHdfs.getDesiredRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
+
+    Service serviceHBase = createNiceMock(Service.class);
+    expect(serviceHBase.getName()).andReturn("HBASE").atLeastOnce();
+    expect(serviceHBase.getDisplayName()).andReturn("HBase").atLeastOnce();
+    expect(serviceHBase.getDesiredRepositoryVersion()).andReturn(repositoryVersion).atLeastOnce();
+
+    // !!! should never be accessed as it's not in any VDF
+    Service serviceAMS = createNiceMock(Service.class);
+
+    expect(cluster.getServices()).andReturn(ImmutableMap.<String, Service>builder()
+        .put("HDFS", serviceHdfs)
+        .put("HBASE", serviceHBase)
+        .put("AMBARI_METRICS", serviceAMS).build()).atLeastOnce();
+
+    replay(cluster, repositoryVersion, serviceHdfs, serviceHBase);
+
+    File f = new File("src/test/resources/version_definition_test_maint_partial.xml");
+    VersionDefinitionXml xml = VersionDefinitionXml.load(f.toURI().toURL());
+    xml.release.version = "2.3.4.1";
+    xml.release.build = "2";
+    ClusterVersionSummary summary = xml.getClusterSummary(cluster);
+    assertEquals(1, summary.getAvailableServiceNames().size());
   }
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/65ea560d/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
index 6ad4e26..42d321a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestVersionUtils.java
@@ -48,6 +48,9 @@ public class TestVersionUtils {
     Assert.assertEquals(0, VersionUtils.compareVersions("2.2", "2.2.VER"));
     Assert.assertEquals(0, VersionUtils.compareVersions("2.2.VAR", "2.2.VER"));
     Assert.assertEquals(0, VersionUtils.compareVersions("2.2.3", "2.2.3.VER1.V"));
+
+    Assert.assertEquals(0, VersionUtils.compareVersions("2.2.0.1-200", "2.2.0.1-100"));
+    Assert.assertEquals(1, VersionUtils.compareVersionsWithBuild("2.2.0.1-200", "2.2.0.1-100", 4));
   }
 
   @Test


[27/51] [abbrv] ambari git commit: AMBARI-22266. Log Search server does not handle proxies properly (oleewere)

Posted by nc...@apache.org.
AMBARI-22266. Log Search server does not handle proxies properly (oleewere)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 30a43c9f3e376343ebeb087e57acb0c6a5211d5a
Parents: b8004df
Author: Oliver Szabo <ol...@gmail.com>
Authored: Wed Nov 8 11:54:46 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Wed Nov 8 11:55:04 2017 +0100

----------------------------------------------------------------------
 .../ambari/logsearch/conf/AuthPropsConfig.java    | 18 ++++++++++++++++++
 .../ambari/logsearch/conf/SecurityConfig.java     |  6 ++++--
 .../LogsearchAuthenticationEntryPoint.java        |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
index 2bcdebc..06673b3 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/AuthPropsConfig.java
@@ -167,6 +167,16 @@ public class AuthPropsConfig {
   )
   private List<String> allowedRoles;
 
+  @Value("${logsearch.auth.redirect.forward:false}")
+  @LogSearchPropertyDescription(
+    name = "logsearch.auth.redirect.forward",
+    description = "Forward redirects for HTTP calls. (useful in case of proxies)",
+    examples = {"true"},
+    defaultValue = "false",
+    sources = {LOGSEARCH_PROPERTIES_FILE}
+  )
+  private boolean redirectForward;
+
   public boolean isAuthFileEnabled() {
     return authFileEnabled;
   }
@@ -278,4 +288,12 @@ public class AuthPropsConfig {
   public void setAllowedRoles(List<String> allowedRoles) {
     this.allowedRoles = allowedRoles;
   }
+
+  public boolean isRedirectForward() {
+    return redirectForward;
+  }
+
+  public void setRedirectForward(boolean redirectForward) {
+    this.redirectForward = redirectForward;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
index cb8124e..6f8d7ba 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/conf/SecurityConfig.java
@@ -44,6 +44,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
 import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
 import org.springframework.security.web.util.matcher.OrRequestMatcher;
 import org.springframework.security.web.util.matcher.RequestMatcher;
@@ -105,8 +106,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
       .httpBasic()
         .authenticationEntryPoint(logsearchAuthenticationEntryPoint())
       .and()
-      .addFilterBefore(logsearchUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
-      .addFilterBefore(logsearchKRBAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
+      .addFilterBefore(logsearchKRBAuthenticationFilter(), BasicAuthenticationFilter.class)
+      .addFilterBefore(logsearchUsernamePasswordAuthenticationFilter(), LogsearchKRBAuthenticationFilter.class)
       .addFilterAfter(securityContextFormationFilter(), FilterSecurityInterceptor.class)
       .addFilterAfter(logsearchEventHistoryFilter(), LogsearchSecurityContextFormationFilter.class)
       .addFilterAfter(logsearchAuditLogFilter(), LogsearchSecurityContextFormationFilter.class)
@@ -153,6 +154,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
   public LogsearchAuthenticationEntryPoint logsearchAuthenticationEntryPoint() {
     LogsearchAuthenticationEntryPoint entryPoint = new LogsearchAuthenticationEntryPoint("/login");
     entryPoint.setForceHttps(false);
+    entryPoint.setUseForward(authPropsConfig.isRedirectForward());
     return entryPoint;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/30a43c9f/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
index 1831697..2fe5f7b 100644
--- a/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/java/org/apache/ambari/logsearch/web/filters/LogsearchAuthenticationEntryPoint.java
@@ -44,7 +44,7 @@ public class LogsearchAuthenticationEntryPoint extends LoginUrlAuthenticationEnt
       response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Session Timeout");
     } else {
       logger.debug("Redirecting to login page :" + this.getLoginFormUrl());
-      response.sendRedirect(this.getLoginFormUrl() + ((request.getQueryString() != null) ? "?" + request.getQueryString() : ""));
+      super.commence(request, response, authException);
     }
   }
 }


[42/51] [abbrv] ambari git commit: AMBARI-22346. Beeline connection hangs for longer time when connection to HS2 with metastore DB down (aonishuk)

Posted by nc...@apache.org.
AMBARI-22346. Beeline connection hangs for longer time when connection to HS2 with metastore DB down (aonishuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 98915a114769c7ddd590854ccf0ab33beabddcf3
Parents: 46ad6c6
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Fri Nov 10 13:28:27 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Fri Nov 10 13:28:27 2017 +0200

----------------------------------------------------------------------
 .../HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py | 3 ++-
 .../1.2.1/package/scripts/alerts/alert_spark_thrift_port.py  | 8 +++++++-
 .../2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py | 8 +++++++-
 3 files changed, 16 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
index 3560bf8..6db92b0 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/alerts/alert_hive_thrift_port.py
@@ -28,6 +28,7 @@ from resource_management.libraries.functions import format
 from resource_management.libraries.functions import get_kinit_path
 from ambari_commons.os_check import OSConst
 from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
+from resource_management.core.signal_utils import TerminateStrategy
 
 OK_MESSAGE = "TCP OK - {0:.3f}s response on port {1}"
 CRITICAL_MESSAGE = "Connection failed on host {0}:{1} ({2})"
@@ -271,7 +272,7 @@ def execute(configurations={}, parameters={}, host_name=None):
 
     start_time = time.time()
     try:
-      Execute(cmd, user=hiveuser, timeout=30)
+      Execute(cmd, user=hiveuser, timeout=30, timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE)
       total_time = time.time() - start_time
       result_code = 'OK'
       label = OK_MESSAGE.format(total_time, port)

http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
index 3f80fd9..6874cb4 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/alerts/alert_spark_thrift_port.py
@@ -27,6 +27,7 @@ from resource_management.libraries.script.script import Script
 from resource_management.libraries.functions import get_kinit_path
 from resource_management.core.resources import Execute
 from resource_management.core import global_lock
+from resource_management.core.signal_utils import TerminateStrategy
 
 stack_root = Script.get_stack_root()
 
@@ -140,7 +141,12 @@ def execute(configurations={}, parameters={}, host_name=None):
 
         start_time = time.time()
         try:
-            Execute(cmd, user=hiveruser, path=[beeline_cmd], timeout=CHECK_COMMAND_TIMEOUT_DEFAULT)
+            Execute(cmd,
+                    user=hiveruser,
+                    path=[beeline_cmd],
+                    timeout=CHECK_COMMAND_TIMEOUT_DEFAULT,
+                    timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE,
+            )
             total_time = time.time() - start_time
             result_code = 'OK'
             label = OK_MESSAGE.format(total_time, port)

http://git-wip-us.apache.org/repos/asf/ambari/blob/98915a11/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
index 9e1afea..d3660de 100644
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/alerts/alert_spark2_thrift_port.py
@@ -27,6 +27,7 @@ from resource_management.libraries.script.script import Script
 from resource_management.libraries.functions import get_kinit_path
 from resource_management.core.resources import Execute
 from resource_management.core import global_lock
+from resource_management.core.signal_utils import TerminateStrategy
 
 
 stack_root = Script.get_stack_root()
@@ -141,7 +142,12 @@ def execute(configurations={}, parameters={}, host_name=None):
 
         start_time = time.time()
         try:
-            Execute(cmd, user=hiveruser, path=[beeline_cmd], timeout=CHECK_COMMAND_TIMEOUT_DEFAULT)
+            Execute(cmd,
+                    user=hiveruser,
+                    path=[beeline_cmd],
+                    timeout=CHECK_COMMAND_TIMEOUT_DEFAULT,
+                    timeout_kill_strategy=TerminateStrategy.KILL_PROCESS_TREE
+            )
             total_time = time.time() - start_time
             result_code = 'OK'
             label = OK_MESSAGE.format(total_time, port)


[11/51] [abbrv] ambari git commit: AMBARI-22357. Log Search server should be able to run locally with dockerized dev env by default (oleewere)

Posted by nc...@apache.org.
AMBARI-22357. Log Search server should be able to run locally with dockerized dev env by default (oleewere)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 68bc38eb241b9f8bd3a31b81f8db0ada5e5229f7
Parents: 1b020cd
Author: Oliver Szabo <ol...@gmail.com>
Authored: Fri Nov 3 14:33:29 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Fri Nov 3 14:36:06 2017 +0100

----------------------------------------------------------------------
 ambari-logsearch/README.md                      |  4 ++
 .../ambari-logsearch-server/.gitignore          |  1 +
 .../ambari-logsearch-server/README.md           | 44 +++++-----------
 ambari-logsearch/ambari-logsearch-server/run.sh |  2 +-
 .../src/main/resources/logsearch.properties     | 54 ++++++--------------
 5 files changed, 36 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/README.md b/ambari-logsearch/README.md
index 43878f2..33952a2 100644
--- a/ambari-logsearch/README.md
+++ b/ambari-logsearch/README.md
@@ -31,6 +31,10 @@ docker exec -it logsearch bash
 ```
 In case if you started the containers separately and if you would like to access Solr locally with through your external ZooKeeper container, then point `solr` to `localhost` in your `/etc/hosts` file.
 
+### Run applications from IDE / maven
+
+- [Start Log Search locally](ambari-logsearch-server/README.md)
+
 ## Package build process
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/.gitignore
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/.gitignore b/ambari-logsearch/ambari-logsearch-server/.gitignore
index 07e0389..7ea6a1f 100644
--- a/ambari-logsearch/ambari-logsearch-server/.gitignore
+++ b/ambari-logsearch/ambari-logsearch-server/.gitignore
@@ -6,4 +6,5 @@ target
 node_modules/
 logs/
 node/
+*.pid
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/README.md b/ambari-logsearch/ambari-logsearch-server/README.md
index 126f651..26b1f73 100644
--- a/ambari-logsearch/ambari-logsearch-server/README.md
+++ b/ambari-logsearch/ambari-logsearch-server/README.md
@@ -17,39 +17,23 @@ limitations under the License.
 {% endcomment %}
 -->
 
-#Compilation
-mvn clean compile package
+# Log Search Server
 
-#Deploy
-##Copy to remote
-copy target/logsearch-portal.tar.gz to host machine
-##Setup environment
-```bash
-mkdir /opt/logsearch
-cd /opt/logsearch
-tar xfz ~/logsearch-portal.tar.gz 
-```
-#Create Solr Collection
-*Edit for log retention days (default is 7 days)*
-```bash
-vi solr_configsets/hadoop_logs/conf/solrconfig.xml
-```
-```
-    <processor class="solr.DefaultValueUpdateProcessorFactory">
-        <str name="fieldName">_ttl_</str>
-        <str name="value">+7DAYS</str>
-    </processor>
-```
-```bash
-./create_collections.sh $SOLR_HOME $NUM_SHARDS $NUM_OF_REPLICATIONS `pwd`/solr_configsets
-```
+## Start locally from maven / IDE
+
+Other services (like zookeeper, solr, logfeeder) can be started with `docker-compose`
 ```bash
-vi classes/logsearch.properties
-```
-```
-solr.zkhosts=$ZK1:2181,$ZK2:2181,$ZK3:2181/solr
+cd ambari/ambari-logsearch/docker
+docker-compose up -d zookeeper solr logfeeder
 ```
-*This script will stop logsearch if it is running and restart it*
+
+Then you can start Log Search server from maven 
+
 ```bash
+cd ambari/ambari-logsearch/ambari-logsearch-server
 ./run.sh
+# or
+mvn clean spring-boot:run
 ```
+
+You can also start Log Search server from an IDE as well. One thing is important: the config set location that the server tries to upload to ZooKeeper. By default config sets are located at `${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets` in `logsearch.properties`. Based or from where you run `LogSearch.java`, you need to set `LOGSEARCH_SERVER_RELATIVE_LOCATION` env variable properly. 

http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/run.sh
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/run.sh b/ambari-logsearch/ambari-logsearch-server/run.sh
index 765fe6c..f245930 100755
--- a/ambari-logsearch/ambari-logsearch-server/run.sh
+++ b/ambari-logsearch/ambari-logsearch-server/run.sh
@@ -17,4 +17,4 @@ echo "
 ███████╗╚██████╔╝╚██████╔╝    ███████║███████╗██║  ██║██║  ██║╚██████╗██║  ██║
 ╚══════╝ ╚═════╝  ╚═════╝     ╚══════╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝
 "
-mvn spring-boot:run
+mvn clean spring-boot:run

http://git-wip-us.apache.org/repos/asf/ambari/blob/68bc38eb/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties b/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
index db8a0a2..3a0f460 100755
--- a/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
+++ b/ambari-logsearch/ambari-logsearch-server/src/main/resources/logsearch.properties
@@ -12,49 +12,27 @@
 # 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.
-
-#logsearch.solr.url=http://host:port/solr
-logsearch.solr.url=
-
-#Solr Core
+logsearch.solr.zk_connect_string=localhost:2181
 logsearch.solr.collection.service.logs=hadoop_logs
-#logsearch.solr.collection.service.logs=ranger_audits
+logsearch.service.logs.split.interval.mins=15
+logsearch.collection.service.logs.numshards=3
+logsearch.collection.service.logs.replication.factor=2
+logsearch.solr.audit.logs.zk_connect_string=localhost:2181
+logsearch.solr.collection.audit.logs=audit_logs
+logsearch.audit.logs.split.interval.mins=15
+logsearch.collection.audit.logs.numshards=2
+logsearch.collection.audit.logs.replication.factor=2
+logsearch.solr.config_set.folder=${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets
+logsearch.solr.audit.logs.config_set.folder=${LOGSEARCH_SERVER_RELATIVE_LOCATION:}src/main/configsets
 logsearch.solr.collection.history=history
-logsearch.service.logs.split.interval.mins=none
-logsearch.collection.service.logs.numshards=1
-logsearch.collection.service.logs.replication.factor=1
-	
-#If set, metrics will be sent to Ambari
-#logsearch.solr.metrics.collector.hosts=example.com
-logsearch.solr.metrics.collector.hosts=
-logsearch.solr.audit.logs.url=
-#logsearch.solr.collection.audit.logs=collection_name
-logsearch.solr.collection.audit.logs=ranger_audits
-logsearch.audit.logs.split.interval.mins=none
-logsearch.collection.audit.logs.numshards=1
-logsearch.collection.audit.logs.replication.factor=1
-
-#Authentication settings
-#Note: Simple will be supported only if file ,ldap and external_auth all three are disabled.
+logsearch.solr.history.config.name=history
+logsearch.collection.history.replication.factor=1
 logsearch.auth.file.enable=true
+logsearch.login.credentials.file=user_pass.json
+
 logsearch.auth.ldap.enable=false
 logsearch.auth.simple.enable=false
 logsearch.auth.external_auth.enable=false
-logsearch.auth.external_auth.host_url=http://ip:port
-logsearch.auth.external_auth.login_url=/api/v1/users/$USERNAME/privileges?fields=*
-#Note: Use comma(,) for separation of multiple roles
-logsearch.roles.allowed=AMBARI.ADMINISTRATOR
 
-
-logsearch.http.port=61888
-logsearch.https.port=61889
 logsearch.protocol=http
-
-logsearch.solr.kerberos.enable=false
-logsearch.solr.jaas.file=/usr/lib/ambari-logsearch-portal/logsearch_solr_jaas.conf
-
-#portal Kerberos 
-logsearch.spnego.kerberos.enabled=false
-logsearch.spnego.kerberos.keytab=
-logsearch.spnego.kerberos.principal=
-logsearch.spnego.kerberos.host=
\ No newline at end of file
+logsearch.config.zk_connect_string=localhost:2181
\ No newline at end of file


[36/51] [abbrv] ambari git commit: AMBARI-22370 - Remove HADOOP_HOME From Environment For Daemons (jonathanhurley)

Posted by nc...@apache.org.
AMBARI-22370 - Remove HADOOP_HOME From Environment For Daemons (jonathanhurley)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 780e91e6124f39fcd67e58369ed2a42da2a6f247
Parents: 444718a
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Nov 6 16:05:56 2017 -0500
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Nov 9 08:23:15 2017 -0500

----------------------------------------------------------------------
 .../libraries/functions/stack_select.py          |  3 ++-
 .../ATLAS/0.1.0.2.3/package/scripts/params.py    |  2 +-
 .../ATLAS/0.7.0.3.0/package/scripts/params.py    |  2 +-
 .../FALCON/0.5.0.2.1/package/scripts/falcon.py   | 11 +----------
 .../package/scripts/hive_service_interactive.py  |  5 ++---
 .../package/scripts/webhcat_service.py           | 19 ++++---------------
 .../package/scripts/hive_service_interactive.py  |  5 ++---
 .../2.1.0.3.0/package/scripts/params_linux.py    |  7 +++----
 .../2.1.0.3.0/package/scripts/webhcat_service.py | 19 ++++---------------
 .../1.0.0.2.3/package/scripts/service_check.py   |  3 +--
 .../1.4.4.2.0/package/scripts/params_linux.py    |  4 ++--
 .../1.4.4.3.0/package/scripts/params_linux.py    |  4 ++--
 .../0.4.0.2.1/package/scripts/params_linux.py    |  2 +-
 .../0.9.0.3.0/package/scripts/params_linux.py    |  2 +-
 .../2.1.0.2.0/package/scripts/params_linux.py    |  2 +-
 .../3.0.0.3.0/package/scripts/params_linux.py    |  2 +-
 .../stacks/2.0.6/HIVE/test_webhcat_server.py     |  4 ----
 .../stacks/2.1/FALCON/test_falcon_server.py      | 10 ++--------
 .../python/stacks/2.1/TEZ/test_tez_client.py     |  2 +-
 .../2.3/MAHOUT/test_mahout_service_check.py      |  4 +---
 .../stacks/2.5/HIVE/test_hive_server_int.py      | 15 +++++----------
 21 files changed, 38 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
index 9b7d0eb..b741a33 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
@@ -71,7 +71,8 @@ HADOOP_DIR_DEFAULTS = {
   "libexec": "/usr/lib/hadoop/libexec",
   "sbin": "/usr/lib/hadoop/sbin",
   "bin": "/usr/bin",
-  "lib": "/usr/lib/hadoop/lib"
+  "lib": "/usr/lib/hadoop/lib",
+  "conf": "/etc/hadoop/conf"
 }
 
 PACKAGE_SCOPE_INSTALL = "INSTALL"

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
index 968ceed..31a866e 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.1.0.2.3/package/scripts/params.py
@@ -118,7 +118,7 @@ metadata_stop_script = format("{metadata_bin}/atlas_stop.py")
 log_dir = config['configurations']['atlas-env']['metadata_log_dir']
 
 # service locations
-hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else '/etc/hadoop/conf'
+hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else format('{stack_root}/current/hadoop-client/conf')
 
 # some commands may need to supply the JAAS location when running as atlas
 atlas_jaas_file = format("{conf_dir}/atlas_jaas.conf")

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
index b01884c..7c1249a 100644
--- a/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/ATLAS/0.7.0.3.0/package/scripts/params.py
@@ -116,7 +116,7 @@ metadata_stop_script = format("{metadata_bin}/atlas_stop.py")
 log_dir = config['configurations']['atlas-env']['metadata_log_dir']
 
 # service locations
-hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else '/etc/hadoop/conf'
+hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else format('{stack_root}/current/hadoop-client/conf')
 
 # some commands may need to supply the JAAS location when running as atlas
 atlas_jaas_file = format("{conf_dir}/atlas_jaas.conf")

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
index 933515b..7d8fa13 100644
--- a/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
+++ b/ambari-server/src/main/resources/common-services/FALCON/0.5.0.2.1/package/scripts/falcon.py
@@ -209,12 +209,6 @@ def falcon(type, action = None, upgrade_type=None):
           owner = params.falcon_user,
           create_parents = True)
 
-    # although Falcon's falcon-config.sh will use 'which hadoop' to figure
-    # this out, in an upgraded cluster, it's possible that 'which hadoop'
-    # still points to older binaries; it's safer to just pass in the
-    # hadoop home directory to use
-    environment_dictionary = { "HADOOP_HOME" : params.hadoop_home_dir }
-
     pid = get_user_call_output.get_user_call_output(format("cat {server_pid_file}"), user=params.falcon_user, is_checked_call=False)[1]
     process_exists = format("ls {server_pid_file} && ps -p {pid}")
 
@@ -223,7 +217,6 @@ def falcon(type, action = None, upgrade_type=None):
         Execute(format('{falcon_home}/bin/falcon-config.sh server falcon'),
           user = params.falcon_user,
           path = params.hadoop_bin_dir,
-          environment=environment_dictionary,
           not_if = process_exists,
         )
       except:
@@ -253,7 +246,6 @@ in the Falcon documentation.
         Execute(format('{falcon_home}/bin/falcon-start -port {falcon_port}'),
           user = params.falcon_user,
           path = params.hadoop_bin_dir,
-          environment=environment_dictionary,
           not_if = process_exists,
         )
       except:
@@ -264,8 +256,7 @@ in the Falcon documentation.
       try:
         Execute(format('{falcon_home}/bin/falcon-stop'),
           user = params.falcon_user,
-          path = params.hadoop_bin_dir,
-          environment=environment_dictionary)
+          path = params.hadoop_bin_dir)
       except:
         show_logs(params.falcon_log_dir, params.falcon_user)
         raise

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
index 703d104..71c22d7 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service_interactive.py
@@ -52,12 +52,11 @@ def hive_service_interactive(name, action='start', upgrade_type=None):
   if action == 'start':
     check_fs_root(params.hive_server_interactive_conf_dir, params.execute_path_hive_interactive)
     daemon_cmd = cmd
-    hadoop_home = params.hadoop_home
-    hive_interactive_bin = "hive2"
+    hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin/hive2")
 
     Execute(daemon_cmd,
             user = params.hive_user,
-            environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
+            environment = { 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
             path = params.execute_path,
             not_if = process_id_exists_command)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
index cb4aafd..bddb5b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/webhcat_service.py
@@ -40,30 +40,22 @@ def webhcat_service(action='start', rolling_restart=False):
 def webhcat_service(action='start', upgrade_type=None):
   import params
 
-  environ = {
-    'HADOOP_HOME': params.hadoop_home
-  }
-
   cmd = format('{webhcat_bin_dir}/webhcat_server.sh')
 
   if action == 'start':
-    if upgrade_type is not None and params.version and params.stack_root:
-      environ['HADOOP_HOME'] = format("{stack_root}/{version}/hadoop")
-
     daemon_cmd = format('cd {hcat_pid_dir} ; {cmd} start')
     no_op_test = format('ls {webhcat_pid_file} >/dev/null 2>&1 && ps -p `cat {webhcat_pid_file}` >/dev/null 2>&1')
     try:
       Execute(daemon_cmd,
               user=params.webhcat_user,
-              not_if=no_op_test,
-              environment = environ)
+              not_if=no_op_test)
     except:
       show_logs(params.hcat_log_dir, params.webhcat_user)
       raise
   elif action == 'stop':
     try:
       # try stopping WebHCat using its own script
-      graceful_stop(cmd, environ)
+      graceful_stop(cmd)
     except Fail:
       show_logs(params.hcat_log_dir, params.webhcat_user)
       Logger.info(traceback.format_exc())
@@ -95,17 +87,14 @@ def webhcat_service(action='start', upgrade_type=None):
 
     File(params.webhcat_pid_file, action="delete")
 
-def graceful_stop(cmd, environ):
+def graceful_stop(cmd):
   """
   Attemps to stop WebHCat using its own shell script. On some versions this may not correctly
   stop the daemon.
   :param cmd: the command to run to stop the daemon
-  :param environ: the environment variables to execute the command with
   :return:
   """
   import params
   daemon_cmd = format('{cmd} stop')
 
-  Execute(daemon_cmd,
-          user = params.webhcat_user,
-          environment = environ)
+  Execute(daemon_cmd, user = params.webhcat_user)

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
index 703d104..71c22d7 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/hive_service_interactive.py
@@ -52,12 +52,11 @@ def hive_service_interactive(name, action='start', upgrade_type=None):
   if action == 'start':
     check_fs_root(params.hive_server_interactive_conf_dir, params.execute_path_hive_interactive)
     daemon_cmd = cmd
-    hadoop_home = params.hadoop_home
-    hive_interactive_bin = "hive2"
+    hive_interactive_bin = format("{stack_root}/current/hive-server2-hive2/bin/hive2")
 
     Execute(daemon_cmd,
             user = params.hive_user,
-            environment = { 'HADOOP_HOME': hadoop_home, 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
+            environment = { 'JAVA_HOME': params.java64_home, 'HIVE_BIN': hive_interactive_bin },
             path = params.execute_path,
             not_if = process_id_exists_command)
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
index 1bd6a1a..088a540 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/params_linux.py
@@ -36,19 +36,17 @@ from resource_management.libraries.functions import get_kinit_path
 from resource_management.libraries.functions.get_not_managed_resources import get_not_managed_resources
 from resource_management.libraries.script.script import Script
 from resource_management.libraries.functions import StackFeature
+from resource_management.libraries.functions import stack_select
 from resource_management.libraries.functions.stack_features import check_stack_feature
 from resource_management.libraries.functions.stack_features import get_stack_feature_version
 from resource_management.libraries.functions import upgrade_summary
 from resource_management.libraries.functions.get_port_from_url import get_port_from_url
 from resource_management.libraries.functions.expect import expect
 from resource_management.libraries import functions
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
-from ambari_commons.ambari_metrics_helper import select_metric_collector_hosts_from_hostnames
 from resource_management.libraries.functions.setup_ranger_plugin_xml import get_audit_configs, generate_ranger_service_config
 from resource_management.libraries.functions.get_architecture import get_architecture
 
 from resource_management.core.utils import PasswordString
-from resource_management.core.shell import checked_call
 from resource_management.core.exceptions import Fail
 from ambari_commons.credential_store_helper import get_password_from_credential_store
 
@@ -107,7 +105,8 @@ stack_supports_hive_interactive_ga = check_stack_feature(StackFeature.HIVE_INTER
 component_directory = status_params.component_directory
 component_directory_interactive = status_params.component_directory_interactive
 
-hadoop_home = format('{stack_root}/current/hadoop-client')
+hadoop_home = stack_select.get_hadoop_dir("home")
+
 hive_bin = format('{stack_root}/current/{component_directory}/bin')
 hive_cmd = os.path.join(hive_bin, "hive")
 hive_schematool_ver_bin = format('{stack_root}/{version}/hive/bin')

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
index cb4aafd..bddb5b2 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/2.1.0.3.0/package/scripts/webhcat_service.py
@@ -40,30 +40,22 @@ def webhcat_service(action='start', rolling_restart=False):
 def webhcat_service(action='start', upgrade_type=None):
   import params
 
-  environ = {
-    'HADOOP_HOME': params.hadoop_home
-  }
-
   cmd = format('{webhcat_bin_dir}/webhcat_server.sh')
 
   if action == 'start':
-    if upgrade_type is not None and params.version and params.stack_root:
-      environ['HADOOP_HOME'] = format("{stack_root}/{version}/hadoop")
-
     daemon_cmd = format('cd {hcat_pid_dir} ; {cmd} start')
     no_op_test = format('ls {webhcat_pid_file} >/dev/null 2>&1 && ps -p `cat {webhcat_pid_file}` >/dev/null 2>&1')
     try:
       Execute(daemon_cmd,
               user=params.webhcat_user,
-              not_if=no_op_test,
-              environment = environ)
+              not_if=no_op_test)
     except:
       show_logs(params.hcat_log_dir, params.webhcat_user)
       raise
   elif action == 'stop':
     try:
       # try stopping WebHCat using its own script
-      graceful_stop(cmd, environ)
+      graceful_stop(cmd)
     except Fail:
       show_logs(params.hcat_log_dir, params.webhcat_user)
       Logger.info(traceback.format_exc())
@@ -95,17 +87,14 @@ def webhcat_service(action='start', upgrade_type=None):
 
     File(params.webhcat_pid_file, action="delete")
 
-def graceful_stop(cmd, environ):
+def graceful_stop(cmd):
   """
   Attemps to stop WebHCat using its own shell script. On some versions this may not correctly
   stop the daemon.
   :param cmd: the command to run to stop the daemon
-  :param environ: the environment variables to execute the command with
   :return:
   """
   import params
   daemon_cmd = format('{cmd} stop')
 
-  Execute(daemon_cmd,
-          user = params.webhcat_user,
-          environment = environ)
+  Execute(daemon_cmd, user = params.webhcat_user)

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py b/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
index c1151fc..b15d158 100644
--- a/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
+++ b/ambari-server/src/main/resources/common-services/MAHOUT/1.0.0.2.3/package/scripts/service_check.py
@@ -71,8 +71,7 @@ class MahoutServiceCheck(Script):
     Execute( mahout_command,
              tries = 3,
              try_sleep = 5,
-             environment={'HADOOP_HOME': params.hadoop_home,'HADOOP_CONF_DIR': params.hadoop_conf_dir,
-                          'MAHOUT_HOME': params.mahout_home,'JAVA_HOME': params.java64_home},
+             environment={'MAHOUT_HOME': params.mahout_home,'JAVA_HOME': params.java64_home},
              path = format('/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin'),
              user = params.smokeuser
     )

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
index 400c87c..eaf1ee4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.2.0/package/scripts/params_linux.py
@@ -23,11 +23,11 @@ from resource_management.libraries.functions.version import format_stack_version
 from resource_management.libraries.functions.default import default
 from resource_management.libraries.functions.get_kinit_path import get_kinit_path
 from resource_management.libraries.script import Script
+from resource_management.libraries.functions import stack_select
 from resource_management.libraries.functions.format import format
 from resource_management.libraries.functions import StackFeature
 from resource_management.libraries.functions.stack_features import check_stack_feature
 from resource_management.libraries.functions.expect import expect
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
 from resource_management.core.exceptions import Fail
 
 
@@ -71,7 +71,7 @@ zoo_conf_dir = "/etc/zookeeper"
 if stack_version_formatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_formatted):
   sqoop_conf_dir = format("{stack_root}/current/sqoop-client/conf")
   sqoop_lib = format("{stack_root}/current/sqoop-client/lib")
-  hadoop_home = format("{stack_root}/current/hadoop-client")
+  hadoop_home = stack_select.get_hadoop_dir("home")
   hbase_home = format("{stack_root}/current/hbase-client")
   hive_home = format("{stack_root}/current/hive-client")
   sqoop_bin_dir = format("{stack_root}/current/sqoop-client/bin/")

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
index 400c87c..eaf1ee4 100644
--- a/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/SQOOP/1.4.4.3.0/package/scripts/params_linux.py
@@ -23,11 +23,11 @@ from resource_management.libraries.functions.version import format_stack_version
 from resource_management.libraries.functions.default import default
 from resource_management.libraries.functions.get_kinit_path import get_kinit_path
 from resource_management.libraries.script import Script
+from resource_management.libraries.functions import stack_select
 from resource_management.libraries.functions.format import format
 from resource_management.libraries.functions import StackFeature
 from resource_management.libraries.functions.stack_features import check_stack_feature
 from resource_management.libraries.functions.expect import expect
-from resource_management.libraries.functions.setup_atlas_hook import has_atlas_in_cluster
 from resource_management.core.exceptions import Fail
 
 
@@ -71,7 +71,7 @@ zoo_conf_dir = "/etc/zookeeper"
 if stack_version_formatted and check_stack_feature(StackFeature.ROLLING_UPGRADE, stack_version_formatted):
   sqoop_conf_dir = format("{stack_root}/current/sqoop-client/conf")
   sqoop_lib = format("{stack_root}/current/sqoop-client/lib")
-  hadoop_home = format("{stack_root}/current/hadoop-client")
+  hadoop_home = stack_select.get_hadoop_dir("home")
   hbase_home = format("{stack_root}/current/hbase-client")
   hive_home = format("{stack_root}/current/hive-client")
   sqoop_bin_dir = format("{stack_root}/current/sqoop-client/bin/")

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
index 4d63685..cef709b 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.4.0.2.1/package/scripts/params_linux.py
@@ -50,7 +50,7 @@ version = default("/commandParams/version", None)
 hadoop_lib_home = stack_select.get_hadoop_dir("lib")
 
 # default hadoop parameters
-hadoop_home = '/usr'
+hadoop_home = stack_select.get_hadoop_dir("home")
 hadoop_bin_dir = stack_select.get_hadoop_dir("bin")
 hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
 tez_etc_dir = "/etc/tez"

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
index 5a028bd..2b3fa38 100644
--- a/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/TEZ/0.9.0.3.0/package/scripts/params_linux.py
@@ -48,7 +48,7 @@ stack_version_formatted = format_stack_version(stack_version_unformatted)
 version = default("/commandParams/version", None)
 
 # default hadoop parameters
-hadoop_home = '/usr'
+hadoop_home = stack_select.get_hadoop_dir("home")
 hadoop_bin_dir = stack_select.get_hadoop_dir("bin")
 hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
 tez_etc_dir = "/etc/tez"

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
index 620408b..3e4504d 100644
--- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py
@@ -65,7 +65,7 @@ stack_name = status_params.stack_name
 stack_root = Script.get_stack_root()
 tarball_map = default("/configurations/cluster-env/tarball_map", None)
 
-config_path = os.path.join(stack_root, "current/hadoop-client/conf")
+config_path = stack_select.get_hadoop_dir("conf")
 config_dir = os.path.realpath(config_path)
 
 # get the correct version to use for checking stack features

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
index e4dbe2c..617dc3b 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/package/scripts/params_linux.py
@@ -65,7 +65,7 @@ stack_name = status_params.stack_name
 stack_root = Script.get_stack_root()
 tarball_map = default("/configurations/cluster-env/tarball_map", None)
 
-config_path = os.path.join(stack_root, "current/hadoop-client/conf")
+config_path = stack_select.get_hadoop_dir("conf")
 config_dir = os.path.realpath(config_path)
 
 # get the correct version to use for checking stack features

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
index f9480ee..b4652ac 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/HIVE/test_webhcat_server.py
@@ -65,7 +65,6 @@ class TestWebHCatServer(RMFTestCase):
 
     self.assert_configure_default()
     self.assertResourceCalled('Execute', 'cd /var/run/webhcat ; /usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh start',
-        environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client'},
         not_if = "ls /var/run/webhcat/webhcat.pid >/dev/null 2>&1 && ps -p `cat /var/run/webhcat/webhcat.pid` >/dev/null 2>&1",
         user = 'hcat',
     )
@@ -82,7 +81,6 @@ class TestWebHCatServer(RMFTestCase):
 
     self.assertResourceCalled('Execute', '/usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh stop',
                               user = 'hcat',
-                              environment = {'HADOOP_HOME': '/usr/hdp/current/hadoop-client' }
                               )
 
     self.assertResourceCalled('Execute', 'ambari-sudo.sh kill -9 `cat /var/run/webhcat/webhcat.pid`',
@@ -148,7 +146,6 @@ class TestWebHCatServer(RMFTestCase):
 
     self.assert_configure_secured()
     self.assertResourceCalled('Execute', 'cd /var/run/webhcat ; /usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh start',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop'},
         not_if = "ls /var/run/webhcat/webhcat.pid >/dev/null 2>&1 && ps -p `cat /var/run/webhcat/webhcat.pid` >/dev/null 2>&1",
         user = 'hcat',
     )
@@ -165,7 +162,6 @@ class TestWebHCatServer(RMFTestCase):
 
     self.assertResourceCalled('Execute', '/usr/hdp/current/hive-webhcat/sbin/webhcat_server.sh stop',
                               user = 'hcat',
-                              environment = {'HADOOP_HOME': '/usr/hdp/2.1.0.0-1234/hadoop' }
                               )
 
     self.assertResourceCalled('Execute', 'ambari-sudo.sh kill -9 `cat /var/run/webhcat/webhcat.pid`',

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py b/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
index 7f2ed46..8c48347 100644
--- a/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
+++ b/ambari-server/src/test/python/stacks/2.1/FALCON/test_falcon_server.py
@@ -49,7 +49,6 @@ class TestFalconServer(RMFTestCase):
     self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-config.sh server falcon',
       path = ['/usr/bin'],
       user = 'falcon',
-      environment = {'HADOOP_HOME': '/usr/lib/hadoop'},
       not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
     )
 
@@ -61,7 +60,6 @@ class TestFalconServer(RMFTestCase):
     self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-start -port 15000',
       path = ['/usr/bin'],
       user = 'falcon',
-      environment = {'HADOOP_HOME': '/usr/lib/hadoop'},
       not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
     )
 
@@ -78,8 +76,7 @@ class TestFalconServer(RMFTestCase):
 
     self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-stop',
       path = ['/usr/bin'],
-      user = 'falcon',
-      environment = {'HADOOP_HOME': '/usr/lib/hadoop'})
+      user = 'falcon')
 
     self.assertResourceCalled('File', '/var/run/falcon/falcon.pid',
       action = ['delete'])
@@ -236,8 +233,7 @@ class TestFalconServer(RMFTestCase):
 
     self.assertResourceCalled('Execute',
       '/usr/hdp/current/falcon-server/bin/falcon-stop',
-      path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'], user='falcon',
-      environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'})
+      path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'], user='falcon')
 
     self.assertResourceCalled('File', '/var/run/falcon/falcon.pid',
       action = ['delete'])
@@ -406,14 +402,12 @@ class TestFalconServer(RMFTestCase):
     )
 
     self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-config.sh server falcon',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'},
         path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'],
         user = 'falcon',
         not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',
     )
 
     self.assertResourceCalled('Execute', '/usr/hdp/current/falcon-server/bin/falcon-start -port 15000',
-        environment = {'HADOOP_HOME': '/usr/hdp/2.2.1.0-2135/hadoop'},
         path = ['/usr/hdp/2.2.1.0-2135/hadoop/bin'],
         user = 'falcon',
         not_if = 'ls /var/run/falcon/falcon.pid && ps -p ',

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py b/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
index fad99f6..59b2166 100644
--- a/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
+++ b/ambari-server/src/test/python/stacks/2.1/TEZ/test_tez_client.py
@@ -130,6 +130,6 @@ class TestTezClient(RMFTestCase):
                        config_dict = json_content,
                        stack_version = self.STACK_VERSION,
                        target = RMFTestCase.TARGET_COMMON_SERVICES,
-                       call_mocks = [(0, None, ''), (0, None)],
+                       call_mocks = [(0, None, ''),(0, None, ''), (0, None)],
                        mocks_dict = mocks_dict)
     # for now, it's enough to know the method didn't fail
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py b/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
index b80476c..8695653 100644
--- a/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
+++ b/ambari-server/src/test/python/stacks/2.3/MAHOUT/test_mahout_service_check.py
@@ -109,9 +109,7 @@ class TestMahoutClient(RMFTestCase):
     self.assertResourceCalled('Execute', 'mahout seqdirectory --input /user/ambari-qa/mahoutsmokeinput/'
                                          'sample-mahout-test.txt --output /user/ambari-qa/mahoutsmokeoutput/ '
                                          '--charset utf-8',
-                              environment = {'HADOOP_CONF_DIR': '/usr/hdp/2.2.1.0-2067/hadoop/conf',
-                                             'HADOOP_HOME': '/usr/hdp/2.2.1.0-2067/hadoop',
-                                             'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45',
+                              environment = {'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45',
                                              'MAHOUT_HOME': '/usr/hdp/current/mahout-client'},
                               path = ['/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin'],
                               tries = 3,

http://git-wip-us.apache.org/repos/asf/ambari/blob/780e91e6/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
index 4951c7e..cf79ec7 100644
--- a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
@@ -115,8 +115,7 @@ class TestHiveServerInteractive(RMFTestCase):
     )
     self.assertResourceCalled('Execute',
                               '/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
-                              environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-                                           'HIVE_BIN': 'hive2',
+                              environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
                                            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user='hive',
@@ -178,8 +177,7 @@ class TestHiveServerInteractive(RMFTestCase):
     )
     self.assertResourceCalled('Execute',
                               '/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
-                              environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-                                           'HIVE_BIN': 'hive2',
+                              environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
                                            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user='hive',
@@ -227,8 +225,7 @@ class TestHiveServerInteractive(RMFTestCase):
     )
     self.assertResourceCalled('Execute',
                               '/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
-                              environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-                                           'HIVE_BIN': 'hive2',
+                              environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
                                            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user='hive',
@@ -305,8 +302,7 @@ class TestHiveServerInteractive(RMFTestCase):
     )
     self.assertResourceCalled('Execute',
                               '/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
-                              environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-                                           'HIVE_BIN': 'hive2',
+                              environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
                                            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user='hive',
@@ -364,8 +360,7 @@ class TestHiveServerInteractive(RMFTestCase):
                               )
     self.assertResourceCalled('Execute',
                               '/tmp/start_hiveserver2_interactive_script /var/run/hive/hive-server2-interactive.out /var/log/hive/hive-server2-interactive.err /var/run/hive/hive-interactive.pid /usr/hdp/current/hive-server2-hive2/conf/conf.server /var/log/hive',
-                              environment={'HADOOP_HOME': '/usr/hdp/current/hadoop-client',
-                                           'HIVE_BIN': 'hive2',
+                              environment={'HIVE_BIN': '/usr/hdp/current/hive-server2-hive2/bin/hive2',
                                            'JAVA_HOME': u'/usr/jdk64/jdk1.7.0_45'},
                               not_if="ls /var/run/hive/hive-interactive.pid >/dev/null 2>&1 && ps -p 123 >/dev/null 2>&1",
                               user='hive',


[24/51] [abbrv] ambari git commit: AMBARI-22377 Ambari 3.0: Implement new design for Admin View: Views page. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
new file mode 100644
index 0000000..7aa25ab
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/viewsList.html
@@ -0,0 +1,134 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<div id="views-table">
+
+    <div class="clearfix">
+        <div class="pull-right">
+            <button ng-disabled="views.length === 0" ng-click="createInstance(views[0]);" class="btn btn-default">
+                {{'views.create' | translate}}
+            </button>
+        </div>
+    </div>
+
+    <table class="table table-striped table-hover">
+        <thead>
+        <tr class="fix-bottom">
+            <th class="fix-bottom col-md-2">
+                <span>{{'common.name' | translate}}</span>
+            </th>
+            <th class="fix-bottom col-md-3">
+                <span>{{'urls.url' | translate}}</span>
+            </th>
+            <th class="fix-bottom col-md-2">
+                <span>{{'views.table.viewType' | translate}}</span>
+            </th>
+            <th class="fix-bottom col-md-2">
+                <span>{{'urls.viewInstance' | translate}}</span>
+            </th>
+            <th class="fix-bottom col-md-2 view-instance-actions">
+                <span>{{'common.actions' | translate}}</span>
+            </th>
+        </tr>
+        <tr>
+            <th class="fix-top">
+                <div class="search-container">
+                    <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
+                           ng-model="instanceNameFilter" ng-change="filterInstances()">
+                    <button type="button" class="close clearfilter" ng-show="instanceNameFilter"
+                            ng-click="instanceNameFilter=''; filterInstances()">
+                        <span aria-hidden="true">&times;</span>
+                        <span class="sr-only">{{'common.controls.close' | translate}}</span>
+                    </button>
+                </div>
+            </th>
+            <th class="fix-top">
+                <div class="search-container">
+                    <input type="text" class="form-control" placeholder="{{'common.any' | translate}}"
+                           ng-model="instanceUrlFilter" ng-change="filterInstances()">
+                    <button type="button" class="close clearfilter" ng-show="instanceUrlFilter"
+                            ng-click="instanceUrlFilter=''; filterInstances()">
+                        <span aria-hidden="true">&times;</span>
+                        <span class="sr-only">{{'common.controls.close' | translate}}</span>
+                    </button>
+                </div>
+            </th>
+            <th class="fix-top">
+                <select class="form-control typefilter v-small-input"
+                        ng-model="instanceTypeFilter"
+                        ng-options="item.label for item in typeFilterOptions"
+                        ng-change="filterInstances()">
+                </select>
+            </th>
+            <th class="fix-top">
+            </th>
+            <th class="fix-top">
+            </th>
+        </tr>
+        </thead>
+
+        <tbody>
+        <tr ng-repeat="instance in instances | filter : { isShowed: true }">
+            <td>
+                <span>{{instance.short_url_name}}</span>
+            </td>
+            <td>
+                <a target="_blank"
+                   href="{{fromSiteRoot('/#/main/view/' + instance.view_name + '/' + instance.short_url)}}">/main/view/{{instance.view_name}}/{{instance.short_url}}
+                    &nbsp;<i class="fa fa-external-link" aria-hidden="true"></i></a>
+            </td>
+            <td>
+                <span>{{instance.view_name}} {{"{"+instance.version+"}"}} </span>
+            </td>
+            <td>
+                <span>{{instance.instance_name}}</span>
+            </td>
+            <td class="view-instance-actions">
+                <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/edit">
+                    <i class="fa fa-pencil"></i>
+                </a>
+                <a href="#/views/{{instance.view_name}}/versions/{{instance.version}}/instances/{{instance.instance_name}}/clone">
+                    <i class="fa fa-copy"></i>
+                </a>
+                <a href ng-click="deleteInstance(instance)">
+                    <i class="fa fa-trash-o"></i>
+                </a>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+    <div ng-if="isLoading" class="spinner-container">
+      <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i>
+    </div>
+    <div class="alert empty-table-alert col-sm-12" ng-show="!tableInfo.filtered && !isLoading">
+        {{'views.emptyTable'| translate}}
+    </div>
+    <div class="col-sm-12 table-bar" ng-show="instances.length >= minInstanceForPagination">
+        <div class="pull-left filtered-info">
+            <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.filtered, term: urs.urls}'}}</span>
+            <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span>
+        </div>
+        <div class="pull-right left-margin">
+            <pagination class="paginator" total-items="tableInfo.filtered" max-size="maxVisiblePages" items-per-page="instancesPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+        </div>
+        <div class="pull-right">
+            <select class="form-control" ng-model="instancesPerPage" ng-change="resetPagination()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select>
+        </div>
+    </div>
+
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
index 0c9e1b9..c625475 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html
@@ -25,9 +25,9 @@
 
             <form class="form-horizontal create-user-form" role="form" novalidate name="formHolder.form" autocomplete="off">
                 <div class="form-group" ng-class="{'has-error' : formHolder.form.url_name.$error.required  && formHolder.form.submitted}">
-                    <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label>
+                    <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label>
                     <div class="col-sm-10">
-                        <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.urlName" required autocomplete="off">
+                        <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.urlName" required autocomplete="off">
                         <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.required  && formHolder.form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
                         <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.minlength   && formHolder.form.submitted">{{'common.alerts.minimumTwoChars' | translate}}</div>
                         <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.maxlength   && formHolder.form.submitted">{{'common.alerts.maxTwentyFiveChars' | translate}}</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
index 9198818..dd5f65a 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
+++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html
@@ -27,9 +27,9 @@
 
 <form  class="form-horizontal create-user-form" role="form" novalidate name="url_form" autocomplete="off">
   <div class="form-group" ng-class="{'has-error' : url_form.url_name.$error.required  && url_form.submitted}">
-    <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label>
+    <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label>
     <div class="col-sm-10">
-      <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.url_name" required autocomplete="off">
+      <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.url_name" required autocomplete="off">
       <div class="alert alert-danger top-margin" ng-show="url_form.url_name.$error.required  && url_form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div>
     </div>
   </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
new file mode 100644
index 0000000..f78333a
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CloneViewInstanceCtrl.js
@@ -0,0 +1,135 @@
+/**
+ * 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.
+ */
+
+describe('#CloneViewInstanceCtrl', function () {
+  var scope, ctrl, $httpBackend, View;
+
+  beforeEach(module('ambariAdminConsole', function($provide){
+    $provide.value('$routeParams', {viewId: 'TestView'});
+  }));
+
+  afterEach(function() {
+    $httpBackend.verifyNoOutstandingExpectation();
+    $httpBackend.verifyNoOutstandingRequest();
+  });
+
+  beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, _View_, $q) {
+    View = _View_;
+    spyOn(View, 'createInstance').andReturn($q.defer().promise);
+    spyOn(View, 'getInstance').andReturn($q.defer().promise);
+
+    $httpBackend = _$httpBackend_;
+    $httpBackend.whenGET(/\/api\/v1\/views\/TestView\?.+/).respond(200, {
+      "versions": [{"ViewVersionInfo": {}}]
+    });
+    $httpBackend.whenGET(/\/api\/v1\/views\/TestView\/versions\/1\.0\.0/).respond(200, {
+      "ViewVersionInfo": {"parameters": [{"name": "n", "defaultValue": "d"}]}
+    });
+    $httpBackend.whenGET('template/modal/backdrop.html').respond(200, '<div></div>');
+    $httpBackend.whenGET('template/modal/window.html').respond(200, '<div></div>');
+    scope = $rootScope.$new();
+    ctrl = $controller('CloneViewInstanceCtrl', {$scope: scope});
+  }));
+
+  it('it should invoke View.createInstance on save', function () {
+    scope.form = {
+      instanceCreateForm: {
+        submitted: false,
+        $valid: true
+      }
+    };
+    $httpBackend.flush();
+    scope.instance = {};
+    scope.save();
+    expect(View.createInstance).toHaveBeenCalled();
+  });
+
+  it('should set default property value before creating view instance', function () {
+    scope.form = {
+      instanceCreateForm: {
+        $dirty: true
+      }
+    };
+    scope.instance = {};
+    scope.version = '1.0.0';
+    scope.isClone=false;
+    $httpBackend.expectGET('template/modal/backdrop.html');
+    $httpBackend.expectGET('template/modal/window.html');
+    $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
+      "items" : [
+        {
+          "Clusters" : {
+            "cluster_name" : "c1",
+            "version" : "HDP-2.2"
+          }
+        }
+      ]
+    });
+    $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
+      "items" : [
+         {
+           "ClusterInfo" : {
+            "name" : "c1",
+            "services" : ["HDFS"]
+          }
+        }
+      ]
+    });
+    scope.$digest();
+    $httpBackend.flush();
+    chai.expect(scope.view.ViewVersionInfo.parameters[0].value).to.equal('d');
+    expect(View.getInstance).not.toHaveBeenCalled();
+  });
+
+  it('before cloning view instance confirm that View.getInstance is called', function () {
+    scope.form = {
+      instanceCreateForm: {
+        $dirty: true
+      }
+    };
+    scope.instance = {};
+    scope.version = '1.0.0';
+    scope.isClone=true;
+    $httpBackend.expectGET('template/modal/backdrop.html');
+    $httpBackend.expectGET('template/modal/window.html');
+    $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
+      "items" : [
+        {
+          "Clusters" : {
+            "cluster_name" : "c1",
+            "version" : "HDP-2.2"
+          }
+        }
+      ]
+    });
+    $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
+      "items" : [
+         {
+           "ClusterInfo" : {
+            "name" : "c1",
+            "services" : ["HDFS"]
+          }
+        }
+      ]
+    });
+    scope.$digest();
+    $httpBackend.flush();
+    expect(View.getInstance).toHaveBeenCalled(); 
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd0421a2/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
deleted file mode 100644
index f8ccc24..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/CreateViewInstanceCtrl.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * 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.
- */
-
-describe('#CreateViewInstanceCtrl', function () {
-  var scope, ctrl, $httpBackend, View;
-
-  beforeEach(module('ambariAdminConsole', function($provide){
-    $provide.value('$routeParams', {viewId: 'TestView'});
-  }));
-
-  afterEach(function() {
-    $httpBackend.verifyNoOutstandingExpectation();
-    $httpBackend.verifyNoOutstandingRequest();
-  });
-
-  beforeEach(inject(function (_$httpBackend_, $rootScope, $controller, _View_, $q) {
-    View = _View_;
-    spyOn(View, 'createInstance').andReturn($q.defer().promise);
-    spyOn(View, 'getInstance').andReturn($q.defer().promise);
-
-    $httpBackend = _$httpBackend_;
-    $httpBackend.whenGET(/\/api\/v1\/views\/TestView\?.+/).respond(200, {
-      "versions": [{"ViewVersionInfo": {}}]
-    });
-    $httpBackend.whenGET(/\/api\/v1\/views\/TestView\/versions\/1\.0\.0/).respond(200, {
-      "ViewVersionInfo": {"parameters": [{"name": "n", "defaultValue": "d"}]}
-    });
-    $httpBackend.whenGET('template/modal/backdrop.html').respond(200, '<div></div>');
-    $httpBackend.whenGET('template/modal/window.html').respond(200, '<div></div>');
-    scope = $rootScope.$new();
-    ctrl = $controller('CreateViewInstanceCtrl', {$scope: scope});
-  }));
-
-  it('it should invoke View.createInstance on save', function () {
-    scope.form = {
-      instanceCreateForm: {
-        submitted: false,
-        $valid: true
-      }
-    };
-    $httpBackend.flush();
-    scope.instance = {};
-    scope.save();
-    expect(View.createInstance).toHaveBeenCalled();
-  });
-
-  it('should set default property value before creating view instance', function () {
-    scope.form = {
-      instanceCreateForm: {
-        $dirty: true
-      }
-    };
-    scope.instance = {};
-    scope.version = '1.0.0';
-    scope.isClone=false;
-    $httpBackend.expectGET('template/modal/backdrop.html');
-    $httpBackend.expectGET('template/modal/window.html');
-    $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
-      "items" : [
-        {
-          "Clusters" : {
-            "cluster_name" : "c1",
-            "version" : "HDP-2.2"
-          }
-        }
-      ]
-    });
-    $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
-      "items" : [
-         {
-           "ClusterInfo" : {
-            "name" : "c1",
-            "services" : ["HDFS"]
-          }
-        }
-      ]
-    });
-    scope.$digest();
-    $httpBackend.flush();
-    chai.expect(scope.view.ViewVersionInfo.parameters[0].value).to.equal('d');
-    expect(View.getInstance).not.toHaveBeenCalled();
-  });
-
-  it('before cloning view instance confirm that View.getInstance is called', function () {
-    scope.form = {
-      instanceCreateForm: {
-        $dirty: true
-      }
-    };
-    scope.instance = {};
-    scope.version = '1.0.0';
-    scope.isClone=true;
-    $httpBackend.expectGET('template/modal/backdrop.html');
-    $httpBackend.expectGET('template/modal/window.html');
-    $httpBackend.whenGET(/\/api\/v1\/clusters\?fields=Clusters\/cluster_id&_=\d+/).respond(200, {
-      "items" : [
-        {
-          "Clusters" : {
-            "cluster_name" : "c1",
-            "version" : "HDP-2.2"
-          }
-        }
-      ]
-    });
-    $httpBackend.whenGET(/\/api\/v1\/remoteclusters\?fields=ClusterInfo\/services,ClusterInfo\/cluster_id&_=\d+/).respond(200, {
-      "items" : [
-         {
-           "ClusterInfo" : {
-            "name" : "c1",
-            "services" : ["HDFS"]
-          }
-        }
-      ]
-    });
-    scope.$digest();
-    $httpBackend.flush();
-    expect(View.getInstance).toHaveBeenCalled(); 
-  });
-
-});


[33/51] [abbrv] ambari git commit: AMBARI-22373.Disable auto config of interpreter.json at the time of installation(Prabhjyot Singh via Venkata Sairam)

Posted by nc...@apache.org.
AMBARI-22373.Disable auto config of interpreter.json at the time of installation(Prabhjyot Singh via Venkata Sairam)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 5f714cee399a1671f73abd8d405049a45d4c743c
Parents: 7074e6e
Author: Venkata Sairam <ve...@gmail.com>
Authored: Thu Nov 9 11:50:06 2017 +0530
Committer: Venkata Sairam <ve...@gmail.com>
Committed: Thu Nov 9 11:50:06 2017 +0530

----------------------------------------------------------------------
 .../ZEPPELIN/0.7.0/package/scripts/master.py             | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5f714cee/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
index 6ccdfba..5efc277 100644
--- a/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
+++ b/ambari-server/src/main/resources/common-services/ZEPPELIN/0.7.0/package/scripts/master.py
@@ -257,7 +257,6 @@ class Master(Script):
     if not glob.glob(params.conf_dir + "/interpreter.json") and \
       not os.path.exists(params.conf_dir + "/interpreter.json"):
       self.create_interpreter_json()
-      self.update_zeppelin_interpreter()
 
     if params.zeppelin_interpreter_config_upgrade == True:
       self.reset_interpreter_settings()
@@ -599,6 +598,16 @@ class Master(Script):
          group=params.zeppelin_group,
          mode=0664)
 
+    if params.conf_stored_in_hdfs:
+      params.HdfsResource(self.get_zeppelin_conf_FS(params),
+                          type="file",
+                          action="create_on_execute",
+                          source=format("{params.conf_dir}/interpreter.json"),
+                          owner=params.zeppelin_user,
+                          recursive_chown=True,
+                          recursive_chmod=True,
+                          replace_existing_files=True)
+
   def get_zeppelin_spark_dependencies(self):
     import params
     return glob.glob(params.zeppelin_dir + '/interpreter/spark/dep/zeppelin-spark-dependencies*.jar')


[15/51] [abbrv] ambari git commit: AMBARI-22320. Some pre-upgrade checks do not work when upgrading from IOP to HDP-2.6.3 (ncole)

Posted by nc...@apache.org.
AMBARI-22320. Some pre-upgrade checks do not work when upgrading from IOP to HDP-2.6.3 (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 1fefbbacedaefe342577246f1bbb7bf3fe9c2bc1
Parents: 0c6cf81
Author: Nate Cole <nc...@hortonworks.com>
Authored: Sat Nov 4 07:25:31 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Sat Nov 4 07:25:31 2017 -0400

----------------------------------------------------------------------
 .../server/state/repository/VersionDefinitionXml.java     | 10 +++++++---
 .../server/state/repository/VersionDefinitionTest.java    |  8 ++++++++
 2 files changed, 15 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1fefbbac/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
index 634ab04..62f78de 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/repository/VersionDefinitionXml.java
@@ -320,10 +320,14 @@ public class VersionDefinitionXml {
 
       summary.setVersions(manifest.version, summaryReleaseVersion);
 
-      // !!! installed service already meets the release version, then nothing to upgrade
-      // !!! TODO should this be using the release compatible-with field?
-      if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
+      if (RepositoryType.STANDARD == release.repositoryType) {
         summary.setUpgrade(true);
+      } else {
+        // !!! installed service already meets the release version, then nothing to upgrade
+        // !!! TODO should this be using the release compatible-with field?
+        if (VersionUtils.compareVersionsWithBuild(versionToCompare, serviceVersion, 4) > 0) {
+          summary.setUpgrade(true);
+        }
       }
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fefbbac/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
index 370a14f..6f33c7e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/repository/VersionDefinitionTest.java
@@ -28,6 +28,7 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.lang.reflect.Field;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -425,6 +426,13 @@ public class VersionDefinitionTest {
     summary = xml.getClusterSummary(cluster);
     assertEquals(0, summary.getAvailableServiceNames().size());
 
+    f = new File("src/test/resources/version_definition_test_maint.xml");
+    xml = VersionDefinitionXml.load(f.toURI().toURL());
+    xml.release.repositoryType = RepositoryType.STANDARD;
+    xml.availableServices = Collections.emptyList();
+    summary = xml.getClusterSummary(cluster);
+    assertEquals(2, summary.getAvailableServiceNames().size());
+
     f = new File("src/test/resources/version_definition_test_maint_partial.xml");
     xml = VersionDefinitionXml.load(f.toURI().toURL());
     summary = xml.getClusterSummary(cluster);


[41/51] [abbrv] ambari git commit: AMBARI-22303. Spark history server is stopped (with umask 027 and custom spark log/pid dir) (aonishuk)

Posted by nc...@apache.org.
AMBARI-22303. Spark history server is stopped (with umask 027 and custom spark log/pid dir) (aonishuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 46ad6c6878b00f7791845ecf7c2b3fef7244faad
Parents: feccebc
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Fri Nov 10 12:53:06 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Fri Nov 10 12:53:06 2017 +0200

----------------------------------------------------------------------
 .../SPARK/1.2.1/package/scripts/setup_spark.py          |  3 ++-
 .../SPARK2/2.0.0/package/scripts/setup_spark.py         |  3 ++-
 .../python/stacks/2.2/SPARK/test_job_history_server.py  | 12 ++++++++----
 .../test/python/stacks/2.2/SPARK/test_spark_client.py   | 12 ++++++++----
 .../python/stacks/2.3/SPARK/test_spark_thrift_server.py |  6 ++++--
 5 files changed, 24 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
index 53c8f9e..6a29efb 100644
--- a/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
+++ b/ambari-server/src/main/resources/common-services/SPARK/1.2.1/package/scripts/setup_spark.py
@@ -52,7 +52,8 @@ def setup_spark(env, type, upgrade_type=None, action=None, config_dir=None):
             owner=params.spark_user,
             group=params.user_group,
             mode=0775,
-            create_parents = True
+            create_parents = True,
+            cd_access = 'a',
   )
   if type == 'server' and action == 'config':
     params.HdfsResource(params.spark_hdfs_user_dir,

http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
index a7b8459..792b2a1 100755
--- a/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
+++ b/ambari-server/src/main/resources/common-services/SPARK2/2.0.0/package/scripts/setup_spark.py
@@ -42,7 +42,8 @@ def setup_spark(env, type, upgrade_type = None, action = None):
             owner=params.spark_user,
             group=params.user_group,
             mode=0775,
-            create_parents = True
+            create_parents = True,
+            cd_access = 'a',
   )
   if type == 'server' and action == 'config':
     params.HdfsResource(params.spark_hdfs_user_dir,

http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py b/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
index 922ace2..8801746 100644
--- a/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
+++ b/ambari-server/src/test/python/stacks/2.2/SPARK/test_job_history_server.py
@@ -165,13 +165,15 @@ class TestJobHistoryServer(RMFTestCase):
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('Directory', '/var/log/spark',
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('HdfsResource', '/user/spark',
         immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,
@@ -246,13 +248,15 @@ class TestJobHistoryServer(RMFTestCase):
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('Directory', '/var/log/spark',
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('HdfsResource', '/user/spark',
         immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,

http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py b/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
index b4535cd..e15d5a4 100644
--- a/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
+++ b/ambari-server/src/test/python/stacks/2.2/SPARK/test_spark_client.py
@@ -58,13 +58,15 @@ class TestSparkClient(RMFTestCase):
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('Directory', '/var/log/spark',
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('PropertiesFile', '/usr/hdp/current/spark-client/conf/spark-defaults.conf',
         owner = 'spark',
@@ -108,13 +110,15 @@ class TestSparkClient(RMFTestCase):
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('Directory', '/var/log/spark',
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('PropertiesFile', '/usr/hdp/current/spark-client/conf/spark-defaults.conf',
         owner = 'spark',

http://git-wip-us.apache.org/repos/asf/ambari/blob/46ad6c68/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py b/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
index fbe5403..78d45cf 100644
--- a/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
+++ b/ambari-server/src/test/python/stacks/2.3/SPARK/test_spark_thrift_server.py
@@ -85,13 +85,15 @@ class TestSparkThriftServer(RMFTestCase):
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('Directory', '/var/log/spark',
         owner = 'spark',
         group = 'hadoop',
         create_parents = True,
-        mode = 0775
+        mode = 0775,
+        cd_access = 'a',
     )
     self.assertResourceCalled('HdfsResource', '/user/spark',
         immutable_paths = self.DEFAULT_IMMUTABLE_PATHS,


[23/51] [abbrv] ambari git commit: AMBARI-22364. Log Feeder should be able to run locally with dockerized dev env by default (oleewere)

Posted by nc...@apache.org.
AMBARI-22364. Log Feeder should be able to run locally with dockerized dev env by default (oleewere)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 654404dc8c545f47bafd8a446b99ecb251d83982
Parents: 063ba36
Author: Oliver Szabo <ol...@gmail.com>
Authored: Tue Nov 7 14:22:38 2017 +0100
Committer: Oliver Szabo <ol...@gmail.com>
Committed: Tue Nov 7 17:08:04 2017 +0100

----------------------------------------------------------------------
 .../ambari-logsearch-logfeeder/README.md        | 17 +++++-----
 .../ambari-logsearch-logfeeder/pom.xml          |  4 ++-
 .../src/main/resources/log-samples/.gitignore   |  4 +++
 .../log-samples/logs/service_sample.txt         |  3 ++
 .../log-samples/shipper-conf/global.config.json | 10 ++++++
 .../shipper-conf/input.config-sample.json       | 31 ++++++++++++++++++
 .../shipper-conf/output.config-sample.json      | 34 ++++++++++++++++++++
 .../src/main/resources/log4j.xml                |  4 +--
 .../src/main/resources/logfeeder.properties     | 31 ++++++++++--------
 9 files changed, 113 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/README.md b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
index 5a64daf..d2e55f0 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/README.md
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/README.md
@@ -22,19 +22,18 @@ limitations under the License.
 Log Feeder is a component of the Log Search service that reads logs, parses them and stores them in Apache Solr for the purpose
 of later analysis.
 
-# Compilation
+## Start locally from maven / IDE
+
+First you need to start every required service (except logfeeder), go to `ambari-logsearch/docker` folder and run:
 ```bash
-mvn clean compile package
+docker-compose up -d zookeeper solr logsearch
 ```
-# Deploy
-## Copy to remote
-copy target/logsearch-logfeeder.tgz to host machine
 
-## Setup environment
+Secondly, if you are planning to run Log Feeder from an IDE, for running the LogFeeder main methoud, you will need to set the working directory to `ambari/ambari-logsearch/ambari-logsearch-logfeeder` and use `--monitor` as a command line argument.
+With Maven, you won't need these steps, just run this command from the ambari-logsearch-logfeeder folder:
+
 ```bash
-mkdir /opt/logfeeder
-cd /opt/logfeeder
-tar xfz ~/logsearch-logfeeder.tar.gz 
+mvn clean package -DskipTests exec:java
 ```
 
 # Input Configuration

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
index b1b6ece..6b7d94f 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml
@@ -220,7 +220,9 @@
         </executions>
         <configuration>
           <mainClass>org.apache.ambari.logfeeder.LogFeeder</mainClass>
-          <!-- <arguments> <argument></argument> </arguments> -->
+          <arguments>
+            <argument>--monitor</argument>
+          </arguments>
         </configuration>
       </plugin>
       <!-- copy-dependencies -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
new file mode 100644
index 0000000..dfb10d6
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/.gitignore
@@ -0,0 +1,4 @@
+logs/*.log
+shipper-conf/input.config-*.json
+!shipper-conf/input.config-sample.json
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
new file mode 100644
index 0000000..21048ac
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/logs/service_sample.txt
@@ -0,0 +1,3 @@
+2016-07-13 10:45:49,640 [WARN] Sample log line 1 - warn level
+2016-07-13 10:45:49,640 [ERROR] Sample log line 2 - error level
+2016-07-13 10:45:50,351 [INFO] Sample log line 3 - info level
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
new file mode 100644
index 0000000..6b8602c
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/global.config.json
@@ -0,0 +1,10 @@
+{
+  "global":{
+    "add_fields":{
+      "cluster":"cl1"
+    },
+    "source":"file",
+    "tail":"true",
+    "gen_event_md5":"true"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
new file mode 100644
index 0000000..4ab2eb2
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/input.config-sample.json
@@ -0,0 +1,31 @@
+{
+  "input": [
+    {
+      "type": "service_sample",
+      "rowtype": "service",
+      "path": "target/classes/log-samples/logs/service_sample.txt"
+    }
+  ],
+  "filter": [
+    {
+      "filter": "grok",
+      "conditions": {
+        "fields": {
+          "type": [
+            "service_sample"
+          ]
+        }
+      },
+      "log4j_format": "",
+      "multiline_pattern": "^(%{TIMESTAMP_ISO8601:logtime})",
+      "message_pattern": "(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}\\[%{LOGLEVEL:level}\\]%{SPACE}%{GREEDYDATA:log_message}",
+      "post_map_values": {
+        "logtime": {
+          "map_date": {
+            "date_pattern": "yyyy-MM-dd HH:mm:ss,SSS"
+          }
+        }
+      }
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
new file mode 100644
index 0000000..94b44da
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log-samples/shipper-conf/output.config-sample.json
@@ -0,0 +1,34 @@
+{
+  "output": [
+    {
+      "is_enabled": "true",
+      "comment": "Output to solr for service logs",
+      "destination": "solr",
+      "zk_connect_string": "localhost:2181",
+      "type": "service",
+      "skip_logtime": "true",
+      "conditions": {
+        "fields": {
+          "rowtype": [
+            "service"
+          ]
+        }
+      }
+    },
+    {
+      "comment": "Output to solr for audit records",
+      "is_enabled": "true",
+      "destination": "solr",
+      "zk_connect_string": "localhost:2181",
+      "type": "audit",
+      "skip_logtime": "true",
+      "conditions": {
+        "fields": {
+          "rowtype": [
+            "audit"
+          ]
+        }
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
index 8d5174e..eb20665 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/log4j.xml
@@ -28,7 +28,7 @@
   </appender>
 
   <appender name="daily_rolling_file" class="org.apache.log4j.DailyRollingFileAppender"> 
-    <param name="file" value="logs/logsearch-logfeeder.log" /> 
+    <param name="file" value="target/logs/logsearch-logfeeder.log" />
     <param name="datePattern"  value="'.'yyyy-MM-dd" /> 
     <param name="append" value="true" /> 
     <layout class="org.apache.log4j.PatternLayout"> 
@@ -38,7 +38,7 @@
 
   <appender name="rolling_file_json"
     class="org.apache.ambari.logsearch.appender.LogsearchRollingFileAppender">
-    <param name="file" value="logs/logsearch-logfeeder.json" />
+    <param name="file" value="target/logs/logsearch-logfeeder.json" />
     <param name="append" value="true" />
     <param name="maxFileSize" value="10MB" />
     <param name="maxBackupIndex" value="10" />

http://git-wip-us.apache.org/repos/asf/ambari/blob/654404dc/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
index 74ea0ef..115778b 100644
--- a/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
+++ b/ambari-logsearch/ambari-logsearch-logfeeder/src/main/resources/logfeeder.properties
@@ -13,19 +13,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-logfeeder.checkpoint.folder=
+cluster.name=cl1
+logfeeder.checkpoint.folder=target/checkpoints
 logfeeder.metrics.collector.hosts=
-
-#filter config
-logfeeder.log.filter.enable=false
+logfeeder.config.dir=target/classes/log-samples/shipper-conf/
+logfeeder.config.files=target/classes/log-samples/shipper-conf/global.config.json,\
+ target/classes/log-samples/shipper-conf/input.config-sample.json,\
+  target/classes/log-samples/shipper-conf/output.config-sample.json
+logfeeder.log.filter.enable=true
 logfeeder.solr.config.interval=5
-logfeeder.solr.zk_connect_string=
-logfeeder.solr.url=
-
-logfeeder.solr.kerberos.enable=false
-logfeeder.solr.jaas.file=/usr/lib/ambari-logsearch-logfeeder/logsearch_solr_jaas.conf
-
-#logfeeder tmp dir 
-logfeeder.tmp.dir=/tmp/$username/logfeeder/
-
 logfeeder.solr.core.config.name=history
+logfeeder.solr.zk_connect_string=localhost:2181
+logfeeder.cache.enabled=true
+logfeeder.cache.size=100
+logfeeder.cache.key.field=log_message
+logfeeder.cache.dedup.interval=1000
+logfeeder.cache.last.dedup.enabled=true
+logsearch.config.zk_connect_string=localhost:2181
+logfeeder.include.default.level=FATAL,ERROR,WARN,INFO,DEBUG,TRACE,UNKNOWN
+
+#logfeeder tmp dir
+logfeeder.tmp.dir=target/tmp


[43/51] [abbrv] ambari git commit: AMBARI-22412. Remove IPA integration from experimental status (rlevas)

Posted by nc...@apache.org.
AMBARI-22412. Remove IPA integration from experimental status (rlevas)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 22b2d55f646ebd965834e43536056c5f229e236e
Parents: 98915a1
Author: Robert Levas <rl...@hortonworks.com>
Authored: Fri Nov 10 10:46:01 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Fri Nov 10 10:46:01 2017 -0500

----------------------------------------------------------------------
 ambari-web/app/config.js                        |  1 -
 .../main/admin/kerberos/step1_controller.js     | 52 +++++++++-----------
 ambari-web/app/messages.js                      |  2 +-
 .../admin/kerberos/step1_controller_test.js     | 17 -------
 4 files changed, 23 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index 0963f70..8dbbde3 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -82,7 +82,6 @@ App.supports = {
   serviceAutoStart: true,
   logSearch: true,
   redhatSatellite: false,
-  enableIpa: false,
   addingNewRepository: false,
   kerberosStackAdvisor: true,
   logCountVizualization: false,

http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
index 2e41e3d..9c864a8 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
@@ -25,29 +25,6 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
 
   isSubmitDisabled: Em.computed.someBy('selectedOption.preConditions', 'checked', false),
 
-  ipaOption: Em.Object.create({
-    displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
-    value: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
-    preConditions: [
-      Em.Object.create({
-        displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.1'),
-        checked: false
-      }),
-      Em.Object.create({
-        displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.2'),
-        checked: false
-      }),
-      Em.Object.create({
-        displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.3'),
-        checked: false
-      }),
-      Em.Object.create({
-        displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.4'),
-        checked: false
-      })
-    ]
-  }),
-
   options: Em.A([
     Em.Object.create({
       displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
@@ -94,6 +71,28 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
       ]
     }),
     Em.Object.create({
+      displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
+      value: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
+      preConditions: [
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.1'),
+          checked: false
+        }),
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.2'),
+          checked: false
+        }),
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.3'),
+          checked: false
+        }),
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa.condition.4'),
+          checked: false
+        })
+      ]
+    }),
+    Em.Object.create({
       displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.manual'),
       value: Em.I18n.t('admin.kerberos.wizard.step1.option.manual'),
       preConditions: [
@@ -135,13 +134,6 @@ App.KerberosWizardStep1Controller = Em.Controller.extend({
 
 
   loadStep: function () {
-    if (App.get('supports.enableIpa')) {
-      var ipaOption = this.get('ipaOption');
-      var options = this.get('options');
-      if (options.indexOf(ipaOption) === -1){
-        options.pushObject(ipaOption);
-      }
-    }
   },
 
   submit: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index bee581a..390f803 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1273,7 +1273,7 @@ Em.I18n.translations = {
   'admin.kerberos.wizard.step1.option.ad.condition.5': 'The Java Cryptography Extensions (JCE) have been setup on the Ambari Server host and all hosts in the cluster.',
   'admin.kerberos.wizard.step1.option.ipa': 'Existing IPA',
   'admin.kerberos.wizard.step1.option.ipa.condition.1': 'Cluster hosts are joined to the IPA domain and hosts are registered in DNS',
-  'admin.kerberos.wizard.step1.option.ipa.condition.2': 'A password policy in place that sets no expiry for created principals or krbPasswordExpiry attribute is writable',
+  'admin.kerberos.wizard.step1.option.ipa.condition.2': 'A password policy in place that sets no expiry for created principals',
   'admin.kerberos.wizard.step1.option.ipa.condition.3': 'The ipa managed krb5.conf sets default_ccache_name = /tmp/krb5cc_%{uid}',
   'admin.kerberos.wizard.step1.option.ipa.condition.4': 'The Java Cryptography Extensions (JCE) have been setup on the Ambari Server host and all hosts in the cluster.',
   'admin.kerberos.wizard.step1.prerequisites.label': 'Following prerequisites needs to be checked to progress ahead in the wizard.',

http://git-wip-us.apache.org/repos/asf/ambari/blob/22b2d55f/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
index ca80341..e5a185e 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step1_controller_test.js
@@ -46,23 +46,6 @@ describe('App.KerberosWizardStep1Controller', function() {
       controller.set('options', []);
     });
 
-    it("enableIpa is true", function() {
-      App.set('supports.enableIpa', true);
-      controller.loadStep();
-      expect(controller.get('selectedItem')).to.be.equal(Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
-      expect(controller.get('options')).to.not.be.empty;
-      controller.loadStep();
-      var options = controller.get('options');
-      expect(options.length).to.be.equal(1);
-    });
-
-    it("enableIpa is false", function() {
-      App.set('supports.enableIpa', false);
-      controller.loadStep();
-      expect(controller.get('selectedItem')).to.be.equal(Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
-      expect(controller.get('options')).to.be.empty;
-    });
-    
     it("on load selected item should not change", function() {
       controller.set('selectedItem',Em.I18n.t('admin.kerberos.wizard.step3.option.kdc'));	
       controller.loadStep();


[05/51] [abbrv] ambari git commit: AMBARI-22352 Ambari 3.0: Implement new design for Admin View. (atkach)

Posted by nc...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
deleted file mode 100644
index f03dcb5..0000000
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/mainCtrl_test.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * 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.
- */
-
-describe('#MainCtrl', function () {
-
-  var scope, ctrl, $httpBackend, $window, clusterService, deferred;
-
-  beforeEach(function () {
-    module('ambariAdminConsole', function ($provide) {
-      $provide.value('$window', {
-        location: {
-          pathname: 'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/'
-        },
-        localStorage: {
-          getItem: function () {
-            return null;
-          },
-          setItem: angular.noop
-        }
-      });
-      localStorage.ambari = JSON.stringify({
-        app: {
-          authenticated: true,
-          loginName: 'admin',
-          user: 'user'
-        }
-      });
-    });
-    inject(function (_$httpBackend_, $rootScope, $controller, _$window_, _Cluster_, _$q_) {
-      clusterService = _Cluster_;
-      deferred = _$q_.defer();
-      spyOn(clusterService, 'getStatus').andReturn(deferred.promise);
-      deferred.resolve({
-        Clusters: {
-          provisioning_state: 'INIT'
-        }
-      });
-      $window = _$window_;
-      $httpBackend = _$httpBackend_;
-      $httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200, {
-        RootServiceComponents: {
-          component_version: 2.2,
-          properties: {
-            'user.inactivity.timeout.default': 20
-          }
-        }
-      });
-      $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
-          "href": "http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true",
-          "items": [
-            {
-              "ViewInfo": {
-                "view_name": "SLIDER"
-              },
-              "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER",
-              "versions": [
-                {
-                  "ViewVersionInfo": {
-                    "system": false,
-                    "version": "1.0.0",
-                    "view_name": "SLIDER"
-                  },
-                  "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0",
-                  "instances": [
-                    {
-                      "ViewInstanceInfo": {
-                        "context_path": "/views/SLIDER/1.0.0/VisibleInstance",
-                        "description": "VisibleInstance",
-                        "icon64_path": null,
-                        "icon_path": null,
-                        "instance_data": {},
-                        "instance_name": "VisibleInstance",
-                        "label": "VisibleInstance",
-                        "properties": {
-                          "ambari.server.password": "123",
-                          "ambari.server.url": "123",
-                          "ambari.server.username": "123",
-                          "slider.user": null,
-                          "view.kerberos.principal": null,
-                          "view.kerberos.principal.keytab": null
-                        },
-                        "static": false,
-                        "version": "1.0.0",
-                        "view_name": "SLIDER",
-                        "visible": true
-                      },
-                      "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance"
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        });
-      $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {
-        data: {
-          data: {
-            addingNewRepository: true
-          }
-        }
-      });
-      scope = $rootScope.$new();
-      scope.$apply();
-      ctrl = $controller('MainCtrl', {
-        $scope: scope
-      });
-    });
-  });
-
-  afterEach(function() {
-    $httpBackend.verifyNoOutstandingExpectation();
-    $httpBackend.verifyNoOutstandingRequest();
-  });
-
-  describe('signout', function () {
-
-    beforeEach(function () {
-      $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{
-        message: "successfully logged out"
-      });
-      $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
-        items: [
-          {
-            AuthorizationInfo: {
-              authorization_id: "AMBARI.RENAME_CLUSTER"
-            }
-          }
-        ]
-      });
-    });
-
-    it('should reset window.location and ambari localstorage', function () {
-      scope.signOut();
-
-      runs(function() {
-        chai.expect($window.location.pathname).to.equal('/');
-      });
-
-      var data = JSON.parse(localStorage.ambari);
-      chai.expect(data.app.authenticated).to.equal(undefined);
-      chai.expect(data.app.loginName).to.equal(undefined);
-      chai.expect(data.app.user).to.equal(undefined);
-      $httpBackend.flush();
-    });
-
-    it('should get visible view instances and show them in top nav menu', function() {
-      $httpBackend.flush();
-
-      chai.expect(scope.viewInstances.length).to.equal(1);
-      chai.expect(scope.viewInstances[0].instance_name).to.equal('VisibleInstance');
-    });
-  });
-
-  describe('roles loading', function () {
-
-    var mock = {
-        callback: angular.noop
-      },
-      cases = [
-        {
-          canPersistData: true,
-          items: [
-            {
-              AuthorizationInfo: {
-                authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA'
-              }
-            }
-          ],
-          title: 'user can persist data'
-        },
-        {
-          canPersistData: false,
-          items: [],
-          title: 'user can\'t persist data'
-        }
-      ];
-
-    angular.forEach(cases, function (item) {
-
-      describe(item.title, function () {
-
-        beforeEach(function () {
-          $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, {
-            items: item.items
-          });
-          spyOn(mock, 'callback');
-          scope.authDataLoad.promise.then(mock.callback);
-          $httpBackend.flush();
-        });
-
-        it('authDataLoad should be resolved with the correct argument', function () {
-          expect(mock.callback).toHaveBeenCalledWith(item.canPersistData);
-        });
-
-      });
-
-    });
-
-  });
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8f7369b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
----------------------------------------------------------------------
diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
index 6b0b17f..d17747b 100644
--- a/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
+++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/services/Utility_test.js
@@ -39,7 +39,7 @@ describe('Utility Service', function () {
       });
       scope = $rootScope.$new();
       scope.$apply();
-      ctrl = $controller('MainCtrl', {
+      ctrl = $controller('AppCtrl', {
         $scope: scope
       });
       httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, {});
@@ -54,6 +54,7 @@ describe('Utility Service', function () {
       httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, {
         items: []
       });
+      httpBackend.whenGET("views/main.html").respond(200, {});
     });
   });
 


[17/51] [abbrv] ambari git commit: AMBARI-22368 Log Search UI: move top menu down. (Istvan Tobias via ababiichuk)

Posted by nc...@apache.org.
AMBARI-22368 Log Search UI: move top menu down. (Istvan Tobias via ababiichuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 976153f96bc333ad6f50196edba0ce2edb8e9078
Parents: 1afee60
Author: Istvan Tobias <to...@gmail.com>
Authored: Mon Nov 6 19:14:42 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Mon Nov 6 19:19:15 2017 +0200

----------------------------------------------------------------------
 .../ambari-logsearch-web/src/app/app.module.ts  |   2 +
 .../action-menu/action-menu.component.html      |  20 ++++
 .../action-menu/action-menu.component.less      |  27 +++++
 .../action-menu/action-menu.component.spec.ts   |  47 +++++++++
 .../action-menu/action-menu.component.ts        | 105 +++++++++++++++++++
 .../src/app/components/app.component.html       |   4 +-
 .../src/app/components/app.component.less       |   5 +-
 .../logs-container.component.html               |  58 +++++-----
 .../logs-container.component.less               |   3 +
 .../main-container.component.html               |   2 +-
 .../src/app/components/mixins.less              |   5 +
 .../components/top-menu/top-menu.component.html |  10 +-
 .../components/top-menu/top-menu.component.less |   1 +
 .../components/top-menu/top-menu.component.ts   |  83 +--------------
 .../src/app/components/variables.less           |   3 +
 15 files changed, 261 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index 37cd869..488437e 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -73,6 +73,7 @@ import {PaginationComponent} from '@app/components/pagination/pagination.compone
 import {PaginationControlsComponent} from '@app/components/pagination-controls/pagination-controls.component';
 import {TimeHistogramComponent} from '@app/components/time-histogram/time-histogram.component';
 import {LogsContainerComponent} from '@app/components/logs-container/logs-container.component';
+import {ActionMenuComponent} from "@app/components/action-menu/action-menu.component";
 import {ModalComponent} from '@app/components/modal/modal.component';
 import {TimeZonePickerComponent} from '@app/components/timezone-picker/timezone-picker.component';
 import {NodeBarComponent} from '@app/components/node-bar/node-bar.component';
@@ -125,6 +126,7 @@ export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSR
     PaginationControlsComponent,
     TimeHistogramComponent,
     LogsContainerComponent,
+    ActionMenuComponent,
     ModalComponent,
     TimeZonePickerComponent,
     NodeBarComponent,

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
new file mode 100644
index 0000000..ab6326a
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.html
@@ -0,0 +1,20 @@
+<!--
+  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.
+-->
+<menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
+             [iconClass]="item.iconClass" [labelClass]="item.labelClass" [subItems]="item.subItems"
+             [hideCaret]="item.hideCaret" [badge]="item.badge" [isRightAlign]="item.isRightAlign">
+</menu-button>

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
new file mode 100644
index 0000000..880a97b
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.less
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+
+@import '../variables';
+
+:host {
+  display: block;
+  margin-left: auto;
+  menu-button {
+    margin: 0 1em;
+    color: @table-border-color;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
new file mode 100644
index 0000000..081304e
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.spec.ts
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+
+import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {TranslationModules} from '@app/test-config.spec';
+
+import {ActionMenuComponent} from './action-menu.component';
+
+describe('ActionMenuComponent', () => {
+  let component: ActionMenuComponent;
+  let fixture: ComponentFixture<ActionMenuComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      imports: TranslationModules,
+      declarations: [ActionMenuComponent],
+      schemas: [CUSTOM_ELEMENTS_SCHEMA]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ActionMenuComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create component', () => {
+    expect(component).toBeTruthy();
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
new file mode 100644
index 0000000..58e0025
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/action-menu/action-menu.component.ts
@@ -0,0 +1,105 @@
+/**
+ * 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.
+ */
+
+import {Component} from '@angular/core';
+
+@Component({
+  selector: 'action-menu',
+  templateUrl: './action-menu.component.html',
+  styleUrls: ['./action-menu.component.less']
+})
+export class ActionMenuComponent {
+
+  //TODO implement loading of real data into subItems
+  readonly items = [
+    {
+      iconClass: 'fa fa-arrow-left',
+      label: 'topMenu.undo',
+      labelClass: 'unstyled-link',
+      action: 'undo',
+      subItems: [
+        {
+          label: 'Apply \'Last week\' filter'
+        },
+        {
+          label: 'Clear all filters'
+        },
+        {
+          label: 'Apply \'HDFS\' filter'
+        },
+        {
+          label: 'Apply \'Errors\' filter'
+        }
+      ]
+    },
+    {
+      iconClass: 'fa fa-arrow-right',
+      label: 'topMenu.redo',
+      labelClass: 'unstyled-link',
+      action: 'redo',
+      subItems: [
+        {
+          label: 'Apply \'Warnings\' filter'
+        },
+        {
+          label: 'Switch to graph mode'
+        },
+        {
+          label: 'Apply \'Custom Date\' filter'
+        }
+      ]
+    },
+    {
+      iconClass: 'fa fa-refresh',
+      label: 'topMenu.refresh',
+      labelClass: 'unstyled-link',
+      action: 'refresh'
+    },
+    {
+      iconClass: 'fa fa-history',
+      label: 'topMenu.history',
+      labelClass: 'unstyled-link',
+      action: 'openHistory',
+      isRightAlign: true,
+      subItems: [
+        {
+          label: 'Apply \'Custom Date\' filter'
+        },
+        {
+          label: 'Switch to graph mode'
+        },
+        {
+          label: 'Apply \'Warnings\' filter'
+        },
+        {
+          label: 'Apply \'Last week\' filter'
+        },
+        {
+          label: 'Clear all filters'
+        },
+        {
+          label: 'Apply \'HDFS\' filter'
+        },
+        {
+          label: 'Apply \'Errors\' filter'
+        }
+      ]
+    }
+  ];
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
index a0444c9..833f43f 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.html
@@ -18,8 +18,8 @@
 <header>
   <nav class="navbar navbar-fixed-top">
     <div class="container-fluid">
-      <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'navbar-left': true}">{{'common.title' | translate}}</h1>
-      <top-menu *ngIf="isAuthorized" class="navbar-right"></top-menu>
+      <h1 [ngClass]="{'full-flex-width': !isAuthorized, 'pull-left': true}">{{'common.title' | translate}}</h1>
+      <top-menu *ngIf="isAuthorized"></top-menu>
     </div>
   </nav>
 </header>

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
index 8731582..f0fecfc 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/app.component.less
@@ -31,11 +31,10 @@
     color: #fff;
 
     .container-fluid {
-      .default-flex;
+      .stretch-flex;
     }
 
     h1 {
-      flex-basis: 70%;
       margin-bottom: @h1-vertical-margin;
       text-transform: uppercase;
 
@@ -45,7 +44,7 @@
     }
 
     /deep/ top-menu {
-      flex-basis: 30%;
+      margin-left: auto;
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
index 70150a5..2c3a3b9 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.html
@@ -15,30 +15,40 @@
   limitations under the License.
 -->
 
-<div class="tabs-container row">
-  <tabs class="col-md-12" [items]="tabs | async" (tabSwitched)="onSwitchTab($event)"
-        (tabClosed)="onCloseTab($event[0], $event[1])"></tabs>
+<div class="tabs-container container-fluid">
+  <div class="row">
+    <div class="col-md-12">
+      <tabs class="pull-left" [items]="tabs | async" (tabSwitched)="onSwitchTab($event)"
+            (tabClosed)="onCloseTab($event[0], $event[1])"></tabs>
+      <action-menu class="pull-right"></action-menu>
+    </div>
+  </div>
 </div>
-<filters-panel class="row" [filtersForm]="filtersForm"></filters-panel>
-<div *ngIf="autoRefreshRemainingSeconds" class="col-md-12">
-  <div class="auto-refresh-message pull-right">
-    {{'filter.capture.triggeringRefresh' | translate: autoRefreshMessageParams}}
+<div class="container-fluid">
+  <filters-panel class="row" [filtersForm]="filtersForm"></filters-panel>
+  <div class="row">
+    <div *ngIf="autoRefreshRemainingSeconds" class="col-md-12">
+      <div class="auto-refresh-message pull-right">
+        {{'filter.capture.triggeringRefresh' | translate: autoRefreshMessageParams}}
+      </div>
+    </div>
+
+    <!-- TODO use plugin for singular/plural -->
+    <div class="logs-header col-md-12">{{
+      (!totalEventsFoundMessageParams.totalCount ? 'logs.noEventFound' :
+        (totalEventsFoundMessageParams.totalCount === 1 ? 'logs.oneEventFound' : 'logs.totalEventFound'))
+            | translate: totalEventsFoundMessageParams
+    }}</div>
   </div>
+  <collapsible-panel openTitle="logs.hideGraph" collapsedTitle="logs.showGraph">
+    <time-histogram [data]="histogramData" [customOptions]="histogramOptions" svgId="service-logs-histogram"
+                    (selectArea)="setCustomTimeRange($event[0], $event[1])"></time-histogram>
+  </collapsible-panel>
+  <dropdown-button *ngIf="!isServiceLogsFileView" class="pull-right" label="logs.columns"
+                   [options]="availableColumns | async" [isRightAlign]="true" [isMultipleChoice]="true"
+                   action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
+  <logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"
+             [isServiceLogsFileView]="isServiceLogsFileView" [filtersForm]="filtersForm"></logs-list>
+  <log-context *ngIf="isServiceLogContextView" [hostName]="activeLog.host_name" [componentName]="activeLog.component_name"
+               [id]="activeLog.id"></log-context>
 </div>
-<!-- TODO use plugin for singular/plural -->
-<div class="logs-header">{{
-  (!totalEventsFoundMessageParams.totalCount ? 'logs.noEventFound' :
-    (totalEventsFoundMessageParams.totalCount === 1 ? 'logs.oneEventFound' : 'logs.totalEventFound'))
-        | translate: totalEventsFoundMessageParams
-}}</div>
-<collapsible-panel openTitle="logs.hideGraph" collapsedTitle="logs.showGraph">
-  <time-histogram [data]="histogramData" [customOptions]="histogramOptions" svgId="service-logs-histogram"
-                  (selectArea)="setCustomTimeRange($event[0], $event[1])"></time-histogram>
-</collapsible-panel>
-<dropdown-button *ngIf="!isServiceLogsFileView" class="pull-right" label="logs.columns"
-                 [options]="availableColumns | async" [isRightAlign]="true" [isMultipleChoice]="true"
-                 action="updateSelectedColumns" [additionalArgs]="logsTypeMapObject.fieldsModel"></dropdown-button>
-<logs-list [logs]="logs | async" [totalCount]="totalCount" [displayedColumns]="displayedColumns"
-           [isServiceLogsFileView]="isServiceLogsFileView" [filtersForm]="filtersForm"></logs-list>
-<log-context *ngIf="isServiceLogContextView" [hostName]="activeLog.host_name" [componentName]="activeLog.component_name"
-             [id]="activeLog.id"></log-context>

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
index 23d5f92..9902b79 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/logs-container/logs-container.component.less
@@ -25,6 +25,9 @@
   .tabs-container, .auto-refresh-message {
     background-color: @filters-panel-background-color;
   }
+  .tabs-container {
+    border-bottom: 1px solid @table-border-color;
+  }
 
   filters-panel {
     margin-bottom: @block-margin-top;

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
index 2061582..95dd238 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/main-container/main-container.component.html
@@ -20,4 +20,4 @@
   <span class="fa fa-spinner fa-spin"></span>
 </div>
 <login-form *ngIf="!isInitialLoading && !isAuthorized"></login-form>
-<logs-container *ngIf="isAuthorized" class="col-md-12"></logs-container>
+<logs-container *ngIf="isAuthorized"></logs-container>

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
index 2e46213..5fa265b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/mixins.less
@@ -28,6 +28,11 @@
   justify-content: space-between;
 }
 
+.stretch-flex {
+  align-items: stretch;
+  display: flex;
+}
+
 .common-hexagon(@side, @color) {
   display: block;
   position: absolute;

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
index a7858a5..369ddd4 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.html
@@ -15,7 +15,9 @@
   limitations under the License.
 -->
 
-<menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
-             [iconClass]="item.iconClass" [labelClass]="item.labelClass"
-             [subItems]="item.subItems" [hideCaret]="item.hideCaret" [badge]="item.badge">
-</menu-button>
+<div class="pull-right">
+  <menu-button *ngFor="let item of items" label="{{item.label | translate}}" [action]="item.action"
+               [iconClass]="item.iconClass" [labelClass]="item.labelClass" [subItems]="item.subItems"
+               [hideCaret]="item.hideCaret" [badge]="item.badge"  [isRightAlign]="item.isRightAlign">
+  </menu-button>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
index 4fe899a..32d1beb 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.less
@@ -19,4 +19,5 @@
 
 :host {
   .default-flex;
+  margin-right: 0;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
index 73b6131..05c1a62 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/top-menu/top-menu.component.ts
@@ -16,98 +16,21 @@
  * limitations under the License.
  */
 
-import {Component, OnInit} from '@angular/core';
+import {Component} from '@angular/core';
 
 @Component({
   selector: 'top-menu',
   templateUrl: './top-menu.component.html',
   styleUrls: ['./top-menu.component.less']
 })
-export class TopMenuComponent implements OnInit {
-
-  constructor() {
-  }
-
-  ngOnInit() {
-  }
+export class TopMenuComponent {
 
   //TODO implement loading of real data into subItems
   readonly items = [
     {
-      iconClass: 'fa fa-arrow-left',
-      label: 'topMenu.undo',
-      labelClass: 'unstyled-link',
-      action: 'undo',
-      subItems: [
-        {
-          label: 'Apply \'Last week\' filter'
-        },
-        {
-          label: 'Clear all filters'
-        },
-        {
-          label: 'Apply \'HDFS\' filter'
-        },
-        {
-          label: 'Apply \'Errors\' filter'
-        }
-      ]
-    },
-    {
-      iconClass: 'fa fa-arrow-right',
-      label: 'topMenu.redo',
-      labelClass: 'unstyled-link',
-      action: 'redo',
-      subItems: [
-        {
-          label: 'Apply \'Warnings\' filter'
-        },
-        {
-          label: 'Switch to graph mode'
-        },
-        {
-          label: 'Apply \'Custom Date\' filter'
-        }
-      ]
-    },
-    {
-      iconClass: 'fa fa-refresh',
-      label: 'topMenu.refresh',
-      labelClass: 'unstyled-link',
-      action: 'refresh'
-    },
-    {
-      iconClass: 'fa fa-history',
-      label: 'topMenu.history',
-      labelClass: 'unstyled-link',
-      action: 'openHistory',
-      subItems: [
-        {
-          label: 'Apply \'Custom Date\' filter'
-        },
-        {
-          label: 'Switch to graph mode'
-        },
-        {
-          label: 'Apply \'Warnings\' filter'
-        },
-        {
-          label: 'Apply \'Last week\' filter'
-        },
-        {
-          label: 'Clear all filters'
-        },
-        {
-          label: 'Apply \'HDFS\' filter'
-        },
-        {
-          label: 'Apply \'Errors\' filter'
-        }
-      ]
-    },
-    {
       iconClass: 'fa fa-user unstyled-link',
       hideCaret: true,
+      isRightAlign: true,
       subItems: [
         {
           label: 'Options'

http://git-wip-us.apache.org/repos/asf/ambari/blob/976153f9/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
index 150ac56..7b7fcae 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/variables.less
@@ -61,3 +61,6 @@
 
 // Icon
 @icon-padding: 5px;
+
+// Table
+@table-border-color: #EEEEEE;


[37/51] [abbrv] ambari git commit: AMBARI-22398. Upstart is not able to stop the ambari-agent (aonishuk)

Posted by nc...@apache.org.
AMBARI-22398. Upstart is not able to stop the ambari-agent (aonishuk)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: e968b12186848edd7b4e8b7103e8283b61f59c50
Parents: 780e91e
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Thu Nov 9 16:37:58 2017 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Thu Nov 9 16:37:58 2017 +0200

----------------------------------------------------------------------
 ambari-agent/src/main/python/ambari_agent/AmbariAgent.py | 3 ---
 1 file changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e968b121/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py b/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
index 28b9528..aeb200c 100644
--- a/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
+++ b/ambari-agent/src/main/python/ambari_agent/AmbariAgent.py
@@ -49,9 +49,6 @@ def main():
 
   mergedArgs = [PYTHON, AGENT_SCRIPT] + args
 
-  # Become a parent for all subprocesses
-  os.setpgrp()
-
   try:
     while status == AGENT_AUTO_RESTART_EXIT_CODE:
       mainProcess = subprocess.Popen(mergedArgs)


[49/51] [abbrv] ambari git commit: AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO (dlysnichenko)

Posted by nc...@apache.org.
AMBARI-22387. Create a Pre-Upgrade Check Warning About LZO (dlysnichenko)


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

Branch: refs/heads/branch-feature-AMBARI-21674
Commit: 76349ac20d8955b3f25383b6f4f209a690b38bef
Parents: 5122671
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Mon Nov 13 13:29:52 2017 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Mon Nov 13 13:30:26 2017 +0200

----------------------------------------------------------------------
 .../ambari/server/checks/CheckDescription.java  |   9 ++
 .../apache/ambari/server/checks/LZOCheck.java   |  77 ++++++++++
 .../HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml |   1 +
 .../stacks/HDP/2.3/upgrades/upgrade-2.6.xml     |   1 +
 .../HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml |   1 +
 .../stacks/HDP/2.4/upgrades/upgrade-2.6.xml     |   1 +
 .../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml |   1 +
 .../stacks/HDP/2.5/upgrades/upgrade-2.6.xml     |   1 +
 .../HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml |   1 +
 .../stacks/HDP/2.6/upgrades/upgrade-2.6.xml     |   1 +
 .../ambari/server/checks/LZOCheckTest.java      | 145 +++++++++++++++++++
 11 files changed, 239 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
index 3caac14..20bb1b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java
@@ -327,6 +327,15 @@ public class CheckDescription {
         "As Ranger is SSL enabled, Ranger SSL configurations will need to be changed from default value of /etc/ranger/*/conf folder to /etc/ranger/security. " +
         "Since the certificates/keystores/truststores in this path may affect the upgrade/downgrade process, it is recommended to manually move the certificates/keystores/truststores out of the conf folders and change the appropriate config values before proceeding.").build());
 
+  public static CheckDescription LZO_CONFIG_CHECK = new CheckDescription("LZO_CONFIG_CHECK",
+      PrereqCheckType.CLUSTER,
+      "LZO Codec Check",
+      new ImmutableMap.Builder<String, String>()
+          .put(AbstractCheckDescriptor.DEFAULT,
+              "You have LZO codec enabled in the core-site config of your cluster. LZO is no longer installed automatically. " +
+                  "If any hosts require LZO, it should be installed before starting the upgrade. " +
+                  "Consult Ambari documentation for instructions on how to do this.").build());
+
   public static CheckDescription JAVA_VERSION = new CheckDescription("JAVA_VERSION",
       PrereqCheckType.CLUSTER,
       "Verify Java version requirement",

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
new file mode 100644
index 0000000..3000b79
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/LZOCheck.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+package org.apache.ambari.server.checks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrereqCheckRequest;
+import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link LZOCheck}
+ * is used to check that the LZO codec enabled in the core-site config fnd warning if any hosts require LZO, it should be installed before starting the upgrade.
+ */
+@Singleton
+@UpgradeCheck(group = UpgradeCheckGroup.INFORMATIONAL_WARNING)
+public class LZOCheck extends AbstractCheckDescriptor {
+
+  final static String IO_COMPRESSION_CODECS = "io.compression.codecs";
+  final static String LZO_ENABLE_KEY = "io.compression.codec.lzo.class";
+  final static String LZO_ENABLE_VALUE = "com.hadoop.compression.lzo.LzoCodec";
+
+  /**
+   * Constructor.
+   */
+  public LZOCheck() {
+    super(CheckDescription.LZO_CONFIG_CHECK);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
+    List<String> errorMessages = new ArrayList<>();
+    PrereqCheckStatus checkStatus = PrereqCheckStatus.WARNING;
+
+    String codecs = getProperty(request, "core-site", IO_COMPRESSION_CODECS);
+    if (codecs!= null && codecs.contains(LZO_ENABLE_VALUE)) {
+      errorMessages.add(getFailReason(IO_COMPRESSION_CODECS, prerequisiteCheck, request));
+    }
+    String classValue = getProperty(request, "core-site", LZO_ENABLE_KEY);
+
+    if (LZO_ENABLE_VALUE.equals(classValue)) {
+      errorMessages.add(getFailReason(LZO_ENABLE_KEY, prerequisiteCheck, request));
+    }
+
+    if (!errorMessages.isEmpty()) {
+      prerequisiteCheck.setFailReason(StringUtils.join(errorMessages, "You have LZO codec enabled in the core-site config of your cluster. LZO is no longer installed automatically. " +
+          "If any hosts require LZO, it should be installed before starting the upgrade. " +
+          "Consult Ambari documentation for instructions on how to do this."));
+      prerequisiteCheck.getFailedOn().add("LZO");
+      prerequisiteCheck.setStatus(checkStatus);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
index 907626d..bb22c1e 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/nonrolling-upgrade-2.6.xml
@@ -24,6 +24,7 @@
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
     <check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->
       <check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
index 567e6e1..faf8cbc 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/upgrades/upgrade-2.6.xml
@@ -36,6 +36,7 @@
     <check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
 
     <!-- Specific to HDP 2.5, Storm is not rolling -->
     <check>org.apache.ambari.server.checks.StormShutdownWarning</check>

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
index faf5b76..97824f2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/nonrolling-upgrade-2.6.xml
@@ -24,6 +24,7 @@
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
     <check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
 
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
index 572a259..9e56d97 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.4/upgrades/upgrade-2.6.xml
@@ -37,6 +37,7 @@
     <check>org.apache.ambari.server.checks.ServicePresenceCheck</check>
     <check>org.apache.ambari.server.checks.RangerAuditDbCheck</check>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
 
     <!-- Specific to HDP 2.5, Storm is not rolling -->
     <check>org.apache.ambari.server.checks.StormShutdownWarning</check>

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
index 8012c90..ace9542 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
@@ -22,6 +22,7 @@
   <type>NON_ROLLING</type>
   <prerequisite-checks>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->
       <check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
index 7c43948..df11ae1 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
@@ -35,6 +35,7 @@
     <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
     <check>org.apache.ambari.server.checks.RangerSSLConfigCheck</check>
     <check>org.apache.ambari.server.checks.DruidHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
 
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
index ae2a855..0355362 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/nonrolling-upgrade-2.6.xml
@@ -21,6 +21,7 @@
   <target-stack>HDP-2.6</target-stack>
   <type>NON_ROLLING</type>
   <prerequisite-checks>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->
       <check-properties name="org.apache.ambari.server.checks.HiveDynamicServiceDiscoveryCheck">

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
index 37847a2..5aa2d20 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/upgrades/upgrade-2.6.xml
@@ -34,6 +34,7 @@
     <check>org.apache.ambari.server.checks.YarnRMHighAvailabilityCheck</check>
     <check>org.apache.ambari.server.checks.YarnTimelineServerStatePreservingCheck</check>
     <check>org.apache.ambari.server.checks.DruidHighAvailabilityCheck</check>
+    <check>org.apache.ambari.server.checks.LZOCheck</check>
 
     <configuration>
       <!-- Configuration properties for all pre-reqs including required pre-reqs -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/76349ac2/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
new file mode 100644
index 0000000..e50e936
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/LZOCheckTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+package org.apache.ambari.server.checks;
+
+    import java.util.HashMap;
+    import java.util.Map;
+
+    import org.apache.ambari.server.configuration.Configuration;
+    import org.apache.ambari.server.controller.PrereqCheckRequest;
+    import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+    import org.apache.ambari.server.state.Cluster;
+    import org.apache.ambari.server.state.Clusters;
+    import org.apache.ambari.server.state.Config;
+    import org.apache.ambari.server.state.DesiredConfig;
+    import org.apache.ambari.server.state.RepositoryType;
+    import org.apache.ambari.server.state.Service;
+    import org.apache.ambari.server.state.repository.ClusterVersionSummary;
+    import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+    import org.apache.ambari.server.state.stack.PrereqCheckStatus;
+    import org.apache.ambari.server.state.stack.PrerequisiteCheck;
+    import org.junit.Assert;
+    import org.junit.Before;
+    import org.junit.Test;
+    import org.junit.runner.RunWith;
+    import org.mockito.Mock;
+    import org.mockito.Mockito;
+    import org.mockito.runners.MockitoJUnitRunner;
+
+    import com.google.inject.Provider;
+
+
+/* Test for LZOCheck */
+@RunWith(MockitoJUnitRunner.class)
+public class LZOCheckTest {
+
+  private final Clusters clusters = Mockito.mock(Clusters.class);
+  private final LZOCheck lZOCheck = new LZOCheck();
+
+  @Mock
+  private ClusterVersionSummary m_clusterVersionSummary;
+
+  @Mock
+  private VersionDefinitionXml m_vdfXml;
+
+  @Mock
+  private RepositoryVersionEntity m_repositoryVersion;
+
+  final Map<String, Service> m_services = new HashMap<>();
+
+  @Before
+  public void setup() throws Exception {
+    lZOCheck.clustersProvider = new Provider<Clusters>() {
+      @Override
+      public Clusters get() {
+        return clusters;
+      }
+    };
+    Configuration config = Mockito.mock(Configuration.class);
+    lZOCheck.config = config;
+
+    m_services.clear();
+
+    Mockito.when(m_repositoryVersion.getType()).thenReturn(RepositoryType.STANDARD);
+    Mockito.when(m_repositoryVersion.getRepositoryXml()).thenReturn(m_vdfXml);
+    Mockito.when(m_vdfXml.getClusterSummary(Mockito.any(Cluster.class))).thenReturn(m_clusterVersionSummary);
+    Mockito.when(m_clusterVersionSummary.getAvailableServiceNames()).thenReturn(m_services.keySet());
+  }
+
+  @Test
+  public void testIsApplicable() throws Exception {
+    final Cluster cluster = Mockito.mock(Cluster.class);
+
+    Mockito.when(cluster.getServices()).thenReturn(m_services);
+    Mockito.when(cluster.getClusterId()).thenReturn(1L);
+    Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
+
+    PrereqCheckRequest request = new PrereqCheckRequest("cluster");
+    request.setTargetRepositoryVersion(m_repositoryVersion);
+
+    Assert.assertTrue(lZOCheck.isApplicable(request));
+  }
+
+  @Test
+  public void testPerform() throws Exception {
+    final Cluster cluster = Mockito.mock(Cluster.class);
+    final Map<String, Service> services = new HashMap<>();
+    final Service service = Mockito.mock(Service.class);
+
+    Mockito.when(cluster.getServices()).thenReturn(services);
+    Mockito.when(cluster.getClusterId()).thenReturn(1L);
+    Mockito.when(clusters.getCluster("cluster")).thenReturn(cluster);
+
+    final DesiredConfig desiredConfig = Mockito.mock(DesiredConfig.class);
+    Mockito.when(desiredConfig.getTag()).thenReturn("tag");
+    Map<String, DesiredConfig> configMap = new HashMap<>();
+    configMap.put("core-site", desiredConfig);
+
+    Mockito.when(cluster.getDesiredConfigs()).thenReturn(configMap);
+    final Config config = Mockito.mock(Config.class);
+    Mockito.when(cluster.getConfig(Mockito.anyString(), Mockito.anyString())).thenReturn(config);
+    final Map<String, String> properties = new HashMap<>();
+    Mockito.when(config.getProperties()).thenReturn(properties);
+
+    PrerequisiteCheck check = new PrerequisiteCheck(null, null);
+    lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+    Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+
+    properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test," + LZOCheck.LZO_ENABLE_VALUE);
+    check = new PrerequisiteCheck(null, null);
+    lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+    Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+
+    properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test");
+    check = new PrerequisiteCheck(null, null);
+    lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+    Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus());
+
+    properties.put(LZOCheck.LZO_ENABLE_KEY, LZOCheck.LZO_ENABLE_VALUE);
+    check = new PrerequisiteCheck(null, null);
+    lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+    Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+
+    properties.put(LZOCheck.LZO_ENABLE_KEY, LZOCheck.LZO_ENABLE_VALUE);
+    properties.put(LZOCheck.IO_COMPRESSION_CODECS,"test," + LZOCheck.LZO_ENABLE_VALUE);
+    check = new PrerequisiteCheck(null, null);
+    lZOCheck.perform(check, new PrereqCheckRequest("cluster"));
+    Assert.assertEquals(PrereqCheckStatus.WARNING, check.getStatus());
+  }
+}