You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2015/01/28 05:26:06 UTC

[1/2] ambari git commit: AMBARI-9364. Handle hosts/services/components being added to a kerberized cluster.

Repository: ambari
Updated Branches:
  refs/heads/trunk c242beeac -> 5e930e44c


AMBARI-9364. Handle hosts/services/components being added to a kerberized cluster.


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

Branch: refs/heads/trunk
Commit: 1dd3ad2178dc1b1a11511ce163a64aa78d3dfdd7
Parents: c242bee
Author: John Speidel <js...@hortonworks.com>
Authored: Tue Jan 27 18:44:59 2015 -0500
Committer: John Speidel <js...@hortonworks.com>
Committed: Tue Jan 27 19:37:16 2015 -0500

----------------------------------------------------------------------
 .../server/controller/KerberosHelper.java       | 115 ++++++++++++-
 .../internal/HostComponentResourceProvider.java |  47 +++++-
 .../server/controller/KerberosHelperTest.java   | 169 +++++++++++++++++--
 .../HostComponentResourceProviderTest.java      | 129 +++++++++++++-
 4 files changed, 436 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1dd3ad21/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index c537498..6bb9bf1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -29,8 +29,21 @@ import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.internal.ArtifactResourceProvider;
+import org.apache.ambari.server.controller.internal.RequestImpl;
 import org.apache.ambari.server.controller.internal.RequestResourceFilter;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.serveraction.ServerAction;
 import org.apache.ambari.server.serveraction.kerberos.*;
@@ -64,6 +77,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -76,6 +90,16 @@ public class KerberosHelper {
 
   private static final Logger LOG = LoggerFactory.getLogger(KerberosHelper.class);
 
+  /**
+   * config type which contains the property used to determine if keberos is enabled
+   */
+  private static final String SECURITY_ENABLED_CONFIG_TYPE = "cluster-env";
+
+  /**
+   * name of property which states whether kerberos is enabled
+   */
+  private static final String SECURITY_ENABLED_PROPERTY_NAME = "security_enabled";
+
   @Inject
   private AmbariCustomCommandExecutionHelper customCommandExecutionHelper;
 
@@ -107,6 +131,12 @@ public class KerberosHelper {
   private KerberosOperationHandlerFactory kerberosOperationHandlerFactory;
 
   /**
+   * Used to get kerberos descriptors associated with the cluster or stack.
+   * Currently not available via injection.
+   */
+  private static ClusterController clusterController = null;
+
+  /**
    * The Handler implementation that provides the logic to enable Kerberos
    */
   private Handler enableKerberosHandler = new EnableKerberosHandler();
@@ -159,6 +189,11 @@ public class KerberosHelper {
     // Update KerberosDetails with the new security type - the current one in the cluster is the "old" value
     kerberosDetails.setSecurityType(securityType);
 
+    //todo: modify call from cluster state transition to not include descriptor
+    if (kerberosDescriptor == null) {
+      kerberosDescriptor = getClusterDescriptor(cluster);
+    }
+
     if (securityType == SecurityType.KERBEROS) {
       LOG.info("Configuring Kerberos for realm {} on cluster, {}", kerberosDetails.getDefaultRealm(), cluster.getClusterName());
       requestStageContainer = handle(cluster, kerberosDescriptor, kerberosDetails, null, null, requestStageContainer, enableKerberosHandler);
@@ -497,12 +532,12 @@ public class KerberosHelper {
         }
 
         // Ensure the cluster-env/security_enabled flag is set properly
-        Map<String, String> clusterEnvProperties = kerberosConfigurations.get("cluster-env");
+        Map<String, String> clusterEnvProperties = kerberosConfigurations.get(SECURITY_ENABLED_CONFIG_TYPE);
         if (clusterEnvProperties == null) {
           clusterEnvProperties = new HashMap<String, String>();
-          kerberosConfigurations.put("cluster-env", clusterEnvProperties);
+          kerberosConfigurations.put(SECURITY_ENABLED_CONFIG_TYPE, clusterEnvProperties);
         }
-        clusterEnvProperties.put("security_enabled",
+        clusterEnvProperties.put(SECURITY_ENABLED_PROPERTY_NAME,
             (kerberosDetails.getSecurityType() == SecurityType.KERBEROS) ? "true" : "false");
 
         // Always set up the necessary stages to perform the tasks needed to complete the operation.
@@ -655,6 +690,69 @@ public class KerberosHelper {
   }
 
   /**
+   * Get the cluster kerberos descriptor that was registered to the
+   * cluster/:clusterName/artifacts/kerberos_descriptor endpoint if
+   * it exists.  If not, obtain the default cluster descriptor which
+   * is available from the endpoint
+   * stacks/:stackName/versions/:version/artifacts/kerberos_descriptor.
+   *
+   * @param cluster  cluster instance
+   *
+   * @return the kerberos descriptor associated with the specified cluster
+   * @throws AmbariException if unable to obtain the descriptor
+   */
+  private KerberosDescriptor getClusterDescriptor(Cluster cluster) throws AmbariException {
+    KerberosDescriptor descriptor;
+    PredicateBuilder pb = new PredicateBuilder();
+    Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals(cluster.getClusterName()).and().
+        property(ArtifactResourceProvider.ARTIFACT_NAME_PROPERTY).equals("kerberos_descriptor").
+        end().toPredicate();
+
+    synchronized (KerberosHelper.class) {
+      if (clusterController == null) {
+        clusterController = ClusterControllerHelper.getClusterController();
+      }
+    }
+
+    ResourceProvider artifactProvider =
+        clusterController.ensureResourceProvider(Resource.Type.Artifact);
+
+    Request request = new RequestImpl(Collections.<String>emptySet(),
+        Collections.<Map<String, Object>>emptySet(), Collections.<String, String>emptyMap(), null);
+
+    Set<Resource> response = null;
+    try {
+      response = artifactProvider.getResources(request, predicate);
+    } catch (SystemException e) {
+      e.printStackTrace();
+      throw new AmbariException("An unknown error occurred while trying to obtain the cluster kerberos descriptor", e);
+    } catch (UnsupportedPropertyException e) {
+      e.printStackTrace();
+      throw new AmbariException("An unknown error occurred while trying to obtain the cluster kerberos descriptor", e);
+    } catch (NoSuchParentResourceException e) {
+      // parent cluster doesn't exist.  shouldn't happen since we have the cluster instance
+      e.printStackTrace();
+      throw new AmbariException("An unknown error occurred while trying to obtain the cluster kerberos descriptor", e);
+    }  catch (NoSuchResourceException e) {
+      // no descriptor registered, use the default from the stack
+    }
+
+    if (response != null && ! response.isEmpty()) {
+      Resource descriptorResource = response.iterator().next();
+      String descriptor_data = (String) descriptorResource.getPropertyValue(
+          ArtifactResourceProvider.ARTIFACT_DATA_PROPERTY);
+
+      descriptor = KerberosDescriptor.fromJSON(descriptor_data);
+    } else {
+      // get default descriptor from stack
+      StackId stackId = cluster.getCurrentStackVersion();
+      descriptor = ambariMetaInfo.getKerberosDescriptor(stackId.getStackName(), stackId.getStackVersion());
+    }
+    return descriptor;
+  }
+
+
+  /**
    * Creates a temporary directory within the system temporary directory
    * <p/>
    * The resulting directory is to be removed by the caller when desired.
@@ -1064,6 +1162,15 @@ public class KerberosHelper {
     return new ArrayList<String>(hostNames);
   }
 
+  /**
+   * Determine if a cluster has kerberos enabled.
+   *
+   * @param cluster  cluster to test
+   * @return true if the provided cluster has kerberos enabled; false otherwise
+   */
+  public boolean isClusterKerberosEnabled(Cluster cluster) {
+    return cluster.getSecurityType() == SecurityType.KERBEROS;
+  }
 
   /**
    * Handler is an interface that needs to be implemented by toggle handler classes to do the
@@ -1429,7 +1536,7 @@ public class KerberosHelper {
       //  2) remove keytab files
       //  3) update configurations
       //  3) restart services
-      return -1;
+      return requestStageContainer == null ? -1 : requestStageContainer.getLastStageId();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1dd3ad21/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
index 7c7e280..b1e05cc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java
@@ -34,6 +34,7 @@ import com.google.inject.Injector;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
@@ -59,6 +60,7 @@ import com.google.inject.assistedinject.AssistedInject;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceComponentHostEvent;
@@ -122,6 +124,12 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
   @Inject
   private MaintenanceStateHelper maintenanceStateHelper;
 
+  /**
+   * kerberos helper
+   */
+  @Inject
+  private KerberosHelper kerberosHelper;
+
 
   // ----- Constructors ----------------------------------------------------
 
@@ -406,6 +414,9 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
     if (clusterName != null && !clusterName.isEmpty()) {
       clusterNames.add(clusterName);
     }
+
+    boolean addKerberosStages = false;
+
     for (ServiceComponentHostRequest request : requests) {
       validateServiceComponentHostRequest(request);
 
@@ -463,6 +474,11 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
       if (request.getDesiredState() != null) {
         // set desired state on host component
         newState = State.valueOf(request.getDesiredState());
+
+        // determine if this state transition will require that kerberos stages are added to request.
+        // once set to true will stay true
+        addKerberosStages = addKerberosStages || requiresKerberosStageAddition(oldState, newState, cluster);
+
         // throw exception if desired state isn't a valid desired state (static check)
         if (!newState.isValidDesiredState()) {
           throw new IllegalArgumentException("Invalid arguments, invalid"
@@ -547,8 +563,16 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
     // just getting the first cluster
     Cluster cluster = clusters.getCluster(clusterNames.iterator().next());
 
-    return getManagementController().addStages(stages, cluster, requestProperties, null, null, null,
+    RequestStageContainer requestStages = getManagementController().addStages(
+        stages, cluster, requestProperties, null, null, null,
         changedScHosts, ignoredScHosts, runSmokeTest, false);
+
+    if (addKerberosStages) {
+      // adds the necessary kerberos related stages to the request
+      kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, null, requestStages);
+    }
+
+    return requestStages;
   }
 
   @Override
@@ -607,6 +631,11 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
     Set<Resource> matchingResources = getResources(queryRequest, predicate);
 
     for (Resource queryResource : matchingResources) {
+      //todo: this was removed for BUG-28737 and the removal of this breaks
+      //todo: the new "add hosts" api.  BUG-4818 is the root cause and needs
+      //todo: to be addressed and then this predicate evaluation should be
+      //todo: uncommented to fix "add hosts".
+//    if (predicate.evaluate(queryResource)) {
       Map<String, Object> updateRequestProperties = new HashMap<String, Object>();
 
       // add props from query resource
@@ -618,6 +647,7 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
         updateRequestProperties.putAll(request.getProperties().iterator().next());
       }
       requests.add(getRequest(updateRequestProperties));
+//    }
     }
 
     RequestStageContainer requestStages = modifyResources(new Command<RequestStageContainer>() {
@@ -799,6 +829,21 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro
     }
   }
 
+  /**
+   * Determine if kerberos stages need to be added to the request as a result of a
+   * host component state change.
+   *
+   * @param current  current host component state
+   * @param target   target host component state
+   * @param cluster  associated cluster
+   * @return whether kerberos stages should be added to the request
+   */
+  public boolean requiresKerberosStageAddition(State current, State target, Cluster cluster) {
+    return current == State.INIT &&
+        target  == State.INSTALLED &&
+        kerberosHelper.isClusterKerberosEnabled(cluster);
+  }
+
 
   // ----- inner classes ---------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/1dd3ad21/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 758e741..e976d81 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
@@ -29,7 +29,13 @@ import org.apache.ambari.server.actionmanager.RequestFactory;
 import org.apache.ambari.server.actionmanager.Stage;
 import org.apache.ambari.server.actionmanager.StageFactory;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.internal.ArtifactResourceProvider;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.orm.DBAccessor;
 import org.apache.ambari.server.security.SecurityHelper;
@@ -62,14 +68,19 @@ import org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor;
 import org.apache.ambari.server.state.kerberos.KerberosPrincipalType;
 import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
 import org.apache.ambari.server.state.stack.OsFamily;
-import org.easymock.EasyMockSupport;
+import org.easymock.Capture;
 import org.easymock.IAnswer;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 import javax.persistence.EntityManager;
 
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -77,15 +88,40 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
-import static org.easymock.EasyMock.*;
-
-public class KerberosHelperTest extends EasyMockSupport {
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.createNiceMock;
+import static org.powermock.api.easymock.PowerMock.createStrictMock;
+import static org.powermock.api.easymock.PowerMock.expectLastCall;
+import static org.powermock.api.easymock.PowerMock.mockStatic;
+import static org.powermock.api.easymock.PowerMock.replay;
+import static org.powermock.api.easymock.PowerMock.replayAll;
+import static org.powermock.api.easymock.PowerMock.reset;
+import static org.powermock.api.easymock.PowerMock.verify;
+import static org.powermock.api.easymock.PowerMock.verifyAll;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(KerberosDescriptor.class)
+@PowerMockIgnore({"javax.crypto.*" })
+@SuppressWarnings("unchecked")
+public class KerberosHelperTest {
 
   private static Injector injector;
+  private final ClusterController clusterController = createStrictMock(ClusterController.class);
+  private final AmbariMetaInfo metaInfo = createNiceMock(AmbariMetaInfo.class);
 
   @Before
   public void setUp() throws Exception {
+    reset(clusterController);
+    reset(metaInfo);
+
     final KerberosOperationHandlerFactory kerberosOperationHandlerFactory = createNiceMock(KerberosOperationHandlerFactory.class);
 
     expect(kerberosOperationHandlerFactory.getKerberosOperationHandler(KDCType.MIT_KDC))
@@ -137,15 +173,19 @@ public class KerberosHelperTest extends EasyMockSupport {
         bind(AmbariCustomCommandExecutionHelper.class).toInstance(createNiceMock(AmbariCustomCommandExecutionHelper.class));
         bind(MaintenanceStateHelper.class).toInstance(createNiceMock(MaintenanceStateHelper.class));
         bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class));
-        bind(AmbariMetaInfo.class).toInstance(createNiceMock(AmbariMetaInfo.class));
+        bind(AmbariMetaInfo.class).toInstance(metaInfo);
         bind(ActionManager.class).toInstance(createNiceMock(ActionManager.class));
         bind(RequestFactory.class).toInstance(createNiceMock(RequestFactory.class));
         bind(StageFactory.class).toInstance(createNiceMock(StageFactory.class));
         bind(Clusters.class).toInstance(createNiceMock(ClustersImpl.class));
         bind(ConfigHelper.class).toInstance(createNiceMock(ConfigHelper.class));
         bind(KerberosOperationHandlerFactory.class).toInstance(kerberosOperationHandlerFactory);
+        bind(ClusterController.class).toInstance(clusterController);
       }
     });
+
+    //todo: currently don't bind ClusterController due to circular references so can't use @Inject
+    setClusterController();
   }
 
   @After
@@ -211,13 +251,13 @@ public class KerberosHelperTest extends EasyMockSupport {
 
   @Test
   public void testEnableKerberos() throws Exception {
-    testEnableKerberos(new KerberosCredential("principal", "password", "keytab"));
+    testEnableKerberos(new KerberosCredential("principal", "password", "keytab"), false, false);
   }
 
   @Test(expected = IllegalArgumentException.class)
   public void testEnableKerberosMissingCredentials() throws Exception {
     try {
-      testEnableKerberos(null);
+      testEnableKerberos(null, false, false);
     } catch (IllegalArgumentException e) {
       Assert.assertTrue(e.getMessage().startsWith("Missing KDC administrator credentials"));
       throw e;
@@ -227,7 +267,7 @@ public class KerberosHelperTest extends EasyMockSupport {
   @Test(expected = IllegalArgumentException.class)
   public void testEnableKerberosInvalidCredentials() throws Exception {
     try {
-      testEnableKerberos(new KerberosCredential("invalid_principal", "password", "keytab"));
+      testEnableKerberos(new KerberosCredential("invalid_principal", "password", "keytab"), false, false);
     } catch (IllegalArgumentException e) {
       Assert.assertTrue(e.getMessage().startsWith("Invalid KDC administrator credentials"));
       throw e;
@@ -235,6 +275,16 @@ public class KerberosHelperTest extends EasyMockSupport {
   }
 
   @Test
+  public void testEnableKerberos_GetKerberosDescriptorFromCluster() throws Exception {
+    testEnableKerberos(new KerberosCredential("principal", "password", "keytab"), true, false);
+  }
+
+  @Test
+  public void testEnableKerberos_GetKerberosDescriptorFromStack() throws Exception {
+    testEnableKerberos(new KerberosCredential("principal", "password", "keytab"), false, true);
+  }
+
+  @Test
   public void testEnsureIdentities() throws Exception {
     testEnsureIdentities(new KerberosCredential("principal", "password", "keytab"));
   }
@@ -259,7 +309,10 @@ public class KerberosHelperTest extends EasyMockSupport {
     }
   }
 
-  private void testEnableKerberos(final KerberosCredential kerberosCredential) throws Exception {
+  private void testEnableKerberos(final KerberosCredential kerberosCredential,
+                                  boolean getClusterDescriptor,
+                                  boolean getStackDescriptor) throws Exception {
+
     KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
 
     final ServiceComponentHost sch1 = createNiceMock(ServiceComponentHost.class);
@@ -430,6 +483,13 @@ public class KerberosHelperTest extends EasyMockSupport {
     expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).once();
     expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).once();
 
+    //todo: extract method?
+    if (getClusterDescriptor) {
+      // needed to mock the static method fromJson()
+      setupGetDescriptorFromCluster(kerberosDescriptor);
+    } else if (getStackDescriptor) {
+      setupGetDescriptorFromStack(kerberosDescriptor);
+    }
     final StageFactory stageFactory = injector.getInstance(StageFactory.class);
     expect(stageFactory.createNew(anyLong(), anyObject(String.class), anyObject(String.class),
         anyLong(), anyObject(String.class), anyObject(String.class), anyObject(String.class),
@@ -480,13 +540,64 @@ public class KerberosHelperTest extends EasyMockSupport {
     replayAll();
 
     // Needed by infrastructure
-    injector.getInstance(AmbariMetaInfo.class).init();
+    metaInfo.init();
 
-    kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, kerberosDescriptor, requestStageContainer);
+    kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, !(getClusterDescriptor || getStackDescriptor) ?
+        kerberosDescriptor : null, requestStageContainer);
 
     verifyAll();
   }
 
+  private void setupGetDescriptorFromCluster(KerberosDescriptor kerberosDescriptor) throws Exception {
+    mockStatic(KerberosDescriptor.class);
+    ResourceProvider resourceProvider = createStrictMock(ResourceProvider.class);
+    expect(clusterController.ensureResourceProvider(Resource.Type.Artifact)).andReturn(resourceProvider).once();
+
+    Resource resource = createStrictMock(Resource.class);
+    Set<Resource> result = Collections.singleton(resource);
+
+    Capture<Predicate> predicateCapture = new Capture<Predicate>();
+    Capture<Request> requestCapture = new Capture<Request>();
+
+    //todo: validate captures
+
+//      PredicateBuilder pb = new PredicateBuilder();
+//      Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals(cluster.getClusterName()).and().
+//          property(ArtifactResourceProvider.ARTIFACT_NAME_PROPERTY).equals("kerberos_descriptor").
+//          end().toPredicate();
+
+    expect(resourceProvider.getResources(capture(requestCapture),
+        capture(predicateCapture))).andReturn(result).once();
+
+    String artifactData = "kerberos descriptor json";
+    expect(resource.getPropertyValue(ArtifactResourceProvider.ARTIFACT_DATA_PROPERTY)).
+        andReturn(artifactData).once();
+
+    expect(KerberosDescriptor.fromJSON(artifactData)).andReturn(kerberosDescriptor).once();
+  }
+
+  private void setupGetDescriptorFromStack(KerberosDescriptor kerberosDescriptor) throws Exception {
+    mockStatic(KerberosDescriptor.class);
+    ResourceProvider resourceProvider = createStrictMock(ResourceProvider.class);
+    expect(clusterController.ensureResourceProvider(Resource.Type.Artifact)).andReturn(resourceProvider).once();
+
+    Capture<Predicate> predicateCapture = new Capture<Predicate>();
+    Capture<Request> requestCapture = new Capture<Request>();
+
+    //todo: validate captures
+
+//      PredicateBuilder pb = new PredicateBuilder();
+//      Predicate predicate = pb.begin().property("Artifacts/cluster_name").equals(cluster.getClusterName()).and().
+//          property(ArtifactResourceProvider.ARTIFACT_NAME_PROPERTY).equals("kerberos_descriptor").
+//          end().toPredicate();
+
+    expect(resourceProvider.getResources(capture(requestCapture),
+        capture(predicateCapture))).andReturn(null).once();
+
+    // cluster.getCurrentStackVersion expectation is already specified in main test method
+    expect(metaInfo.getKerberosDescriptor("HDP", "2.2")).andReturn(kerberosDescriptor).once();
+  }
+
   private void testEnsureIdentities(final KerberosCredential kerberosCredential) throws Exception {
     KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
 
@@ -726,4 +837,38 @@ public class KerberosHelperTest extends EasyMockSupport {
 
     verifyAll();
   }
+
+  @Test
+  public void testIsClusterKerberosEnabled_false() throws Exception {
+    KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
+    Cluster cluster = createStrictMock(Cluster.class);
+
+    expect(cluster.getSecurityType()).andReturn(SecurityType.NONE);
+
+    replay(cluster);
+    assertFalse(kerberosHelper.isClusterKerberosEnabled(cluster));
+    verify(cluster);
+  }
+
+  @Test
+  public void testIsClusterKerberosEnabled_true() throws Exception {
+    KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
+    Cluster cluster = createStrictMock(Cluster.class);
+
+    expect(cluster.getSecurityType()).andReturn(SecurityType.KERBEROS);
+
+    replay(cluster);
+    assertTrue(kerberosHelper.isClusterKerberosEnabled(cluster));
+    verify(cluster);
+  }
+
+  private void setClusterController() throws Exception {
+    KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
+
+    Class<?> c = kerberosHelper.getClass();
+
+    Field f = c.getDeclaredField("clusterController");
+    f.setAccessible(true);
+    f.set(kerberosHelper, clusterController);
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/1dd3ad21/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
index c6a89ed..337cc74 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostComponentResourceProviderTest.java
@@ -21,6 +21,7 @@ package org.apache.ambari.server.controller.internal;
 import com.google.inject.Injector;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.MaintenanceStateHelper;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
@@ -35,6 +36,7 @@ import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
@@ -59,6 +61,7 @@ import java.util.Set;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
@@ -302,7 +305,7 @@ public class HostComponentResourceProviderTest {
     HostComponentResourceProvider provider =
         new TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
             PropertyHelper.getKeyPropertyIds(type),
-            managementController, injector, maintenanceStateHelper);
+            managementController, injector, maintenanceStateHelper, null);
 
     expect(resourceProviderFactory.getHostComponentResourceProvider(anyObject(Set.class),
         anyObject(Map.class),
@@ -351,6 +354,8 @@ public class HostComponentResourceProviderTest {
     ServiceComponentHost componentHost = createNiceMock(ServiceComponentHost.class);
     RequestStageContainer stageContainer = createNiceMock(RequestStageContainer.class);
     MaintenanceStateHelper maintenanceStateHelper = createNiceMock(MaintenanceStateHelper.class);
+    // INIT->INSTALLED state transition causes check for kerverized cluster
+    KerberosHelper kerberosHelper = createStrictMock(KerberosHelper.class);
 
     Collection<String> hosts = new HashSet<String>();
     hosts.add("Host100");
@@ -379,7 +384,7 @@ public class HostComponentResourceProviderTest {
     expect(componentHost.getHostName()).andReturn("Host100").anyTimes();
     expect(componentHost.getServiceComponentName()).andReturn("Component100").anyTimes();
     expect(response.getMessage()).andReturn("response msg").anyTimes();
-    //expect(response.getRequestId()).andReturn(1000L);
+
 
     //Cluster is default type.  Maintenance mode is not being tested here so the default is returned.
     expect(maintenanceStateHelper.isOperationAllowed(Resource.Type.Cluster, componentHost)).andReturn(true).anyTimes();
@@ -413,16 +418,18 @@ public class HostComponentResourceProviderTest {
     HostComponentResourceProvider provider =
         new TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
             PropertyHelper.getKeyPropertyIds(type),
-            managementController, injector, maintenanceStateHelper);
+            managementController, injector, maintenanceStateHelper, kerberosHelper);
 
     expect(resourceProviderFactory.getHostComponentResourceProvider(anyObject(Set.class),
         anyObject(Map.class),
         eq(managementController))).
         andReturn(provider).anyTimes();
 
+    expect(kerberosHelper.isClusterKerberosEnabled(cluster)).andReturn(false).once();
+
     // replay
     replay(managementController, response, resourceProviderFactory, clusters, cluster, service,
-        component, componentHost, stageContainer, maintenanceStateHelper);
+        component, componentHost, stageContainer, maintenanceStateHelper, kerberosHelper);
 
     Map<String, Object> properties = new LinkedHashMap<String, Object>();
     properties.put(HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID, "STARTED");
@@ -431,7 +438,108 @@ public class HostComponentResourceProviderTest {
 
     assertSame(response, requestResponse);
     // verify
-    verify(managementController, response, resourceProviderFactory, stageContainer);
+    verify(managementController, response, resourceProviderFactory, stageContainer, kerberosHelper);
+  }
+
+  @Test
+  public void testInstallAndStart_kerberizedCluster() throws Exception {
+    Resource.Type type = Resource.Type.HostComponent;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+    ResourceProviderFactory resourceProviderFactory = createNiceMock(ResourceProviderFactory.class);
+    Injector injector = createNiceMock(Injector.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service = createNiceMock(Service.class);
+    ServiceComponent component = createNiceMock(ServiceComponent.class);
+    ServiceComponentHost componentHost = createNiceMock(ServiceComponentHost.class);
+    RequestStageContainer stageContainer = createNiceMock(RequestStageContainer.class);
+    MaintenanceStateHelper maintenanceStateHelper = createNiceMock(MaintenanceStateHelper.class);
+    KerberosHelper kerberosHelper = createStrictMock(KerberosHelper.class);
+
+    Collection<String> hosts = new HashSet<String>();
+    hosts.add("Host100");
+
+    Map<String, String> mapRequestProps = new HashMap<String, String>();
+    mapRequestProps.put("context", "Install and start components on added hosts");
+
+    Set<ServiceComponentHostResponse> nameResponse = new HashSet<ServiceComponentHostResponse>();
+    nameResponse.add(new ServiceComponentHostResponse(
+        "Cluster102", "Service100", "Component100", "Host100", "INIT", "", "INIT", "", null));
+    Set<ServiceComponentHostResponse> nameResponse2 = new HashSet<ServiceComponentHostResponse>();
+    nameResponse2.add(new ServiceComponentHostResponse(
+        "Cluster102", "Service100", "Component100", "Host100", "INIT", "", "INSTALLED", "", null));
+
+
+    // set expectations
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    expect(managementController.findServiceName(cluster, "Component100")).andReturn("Service100").anyTimes();
+    expect(clusters.getCluster("Cluster102")).andReturn(cluster).anyTimes();
+    expect(cluster.getService("Service100")).andReturn(service).anyTimes();
+    expect(service.getServiceComponent("Component100")).andReturn(component).anyTimes();
+    expect(component.getServiceComponentHost("Host100")).andReturn(componentHost).anyTimes();
+    expect(component.getName()).andReturn("Component100").anyTimes();
+    // actual state is always INIT until stages actually execute
+    expect(componentHost.getState()).andReturn(State.INIT).anyTimes();
+    expect(componentHost.getHostName()).andReturn("Host100").anyTimes();
+    expect(componentHost.getServiceComponentName()).andReturn("Component100").anyTimes();
+    expect(response.getMessage()).andReturn("response msg").anyTimes();
+
+    //Cluster is default type.  Maintenance mode is not being tested here so the default is returned.
+    expect(maintenanceStateHelper.isOperationAllowed(Resource.Type.Cluster, componentHost)).andReturn(true).anyTimes();
+
+    expect(managementController.getHostComponents(
+        EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse);
+    expect(managementController.getHostComponents(
+        EasyMock.<Set<ServiceComponentHostRequest>>anyObject())).andReturn(nameResponse2);
+
+    Map<String, Map<State, List<ServiceComponentHost>>> changedHosts =
+        new HashMap<String, Map<State, List<ServiceComponentHost>>>();
+    List<ServiceComponentHost> changedComponentHosts = Collections.singletonList(componentHost);
+    changedHosts.put("Component100", Collections.singletonMap(State.INSTALLED, changedComponentHosts));
+
+    Map<String, Map<State, List<ServiceComponentHost>>> changedHosts2 =
+        new HashMap<String, Map<State, List<ServiceComponentHost>>>();
+    List<ServiceComponentHost> changedComponentHosts2 = Collections.singletonList(componentHost);
+    changedHosts2.put("Component100", Collections.singletonMap(State.STARTED, changedComponentHosts2));
+
+    expect(managementController.addStages(null, cluster, mapRequestProps, null, null, null, changedHosts,
+        Collections.<ServiceComponentHost>emptyList(), false, false)).andReturn(stageContainer).once();
+
+    expect(managementController.addStages(stageContainer, cluster, mapRequestProps, null, null, null, changedHosts2,
+        Collections.<ServiceComponentHost>emptyList(), false, false)).andReturn(stageContainer).once();
+
+    stageContainer.persist();
+    expect(stageContainer.getProjectedState("Host100", "Component100")).andReturn(State.INSTALLED).once();
+    expect(stageContainer.getRequestStatusResponse()).andReturn(response).once();
+
+    HostComponentResourceProvider provider =
+        new TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
+            PropertyHelper.getKeyPropertyIds(type),
+            managementController, injector, maintenanceStateHelper, kerberosHelper);
+
+    expect(resourceProviderFactory.getHostComponentResourceProvider(anyObject(Set.class),
+        anyObject(Map.class),
+        eq(managementController))).
+        andReturn(provider).anyTimes();
+
+    expect(kerberosHelper.isClusterKerberosEnabled(cluster)).andReturn(true).once();
+    expect(kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, null, stageContainer)).
+        andReturn(stageContainer).once();
+
+    // replay
+    replay(managementController, response, resourceProviderFactory, clusters, cluster, service,
+        component, componentHost, stageContainer, maintenanceStateHelper, kerberosHelper);
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+    properties.put(HostComponentResourceProvider.HOST_COMPONENT_STATE_PROPERTY_ID, "STARTED");
+
+    RequestStatusResponse requestResponse = provider.installAndStart("Cluster102", hosts);
+
+    assertSame(response, requestResponse);
+    // verify
+    verify(managementController, response, resourceProviderFactory, stageContainer, kerberosHelper);
   }
 
   @Test
@@ -533,7 +641,8 @@ public class HostComponentResourceProviderTest {
     HostComponentResourceProvider provider =
         new TestHostComponentResourceProvider(PropertyHelper.getPropertyIds(type),
             PropertyHelper.getKeyPropertyIds(type),
-            controller, injector, injector.getInstance(MaintenanceStateHelper.class));
+            controller, injector, injector.getInstance(MaintenanceStateHelper.class),
+            injector.getInstance(KerberosHelper.class));
     RequestStageContainer requestStages = provider.updateHostComponents(null, requests, requestProperties, runSmokeTest);
     requestStages.persist();
     return requestStages.getRequestStatusResponse();
@@ -550,14 +659,20 @@ public class HostComponentResourceProviderTest {
      */
     public TestHostComponentResourceProvider(Set<String> propertyIds, Map<Resource.Type, String> keyPropertyIds,
                                              AmbariManagementController managementController, Injector injector,
-                                             MaintenanceStateHelper maintenanceStateHelper) throws Exception {
+                                             MaintenanceStateHelper maintenanceStateHelper,
+                                             KerberosHelper kerberosHelper) throws Exception {
 
       super(propertyIds, keyPropertyIds, managementController, injector);
 
       Class<?> c = getClass().getSuperclass();
+
       Field f = c.getDeclaredField("maintenanceStateHelper");
       f.setAccessible(true);
       f.set(this, maintenanceStateHelper);
+
+      f = c.getDeclaredField("kerberosHelper");
+      f.setAccessible(true);
+      f.set(this, kerberosHelper);
     }
   }
 }


[2/2] ambari git commit: AMBARI-9366. Fix create statement for artifact table in external Postgres DB script

Posted by js...@apache.org.
AMBARI-9366.  Fix create statement for artifact table in external Postgres DB script


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

Branch: refs/heads/trunk
Commit: 5e930e44c8412cab73554a8ab17c13b32f5bb630
Parents: 1dd3ad2
Author: John Speidel <js...@hortonworks.com>
Authored: Tue Jan 27 19:49:27 2015 -0500
Committer: John Speidel <js...@hortonworks.com>
Committed: Tue Jan 27 19:49:27 2015 -0500

----------------------------------------------------------------------
 ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5e930e44/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 64ffc4f..b589993 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -509,7 +509,7 @@ CREATE TABLE repo_version (
   PRIMARY KEY(repo_version_id)
 );
 
-CREATE TABLE ambari.artifact (
+CREATE TABLE artifact (
   artifact_name VARCHAR(255) NOT NULL,
   artifact_data TEXT NOT NULL,
   foreign_keys VARCHAR(255) NOT NULL,