You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2016/06/16 09:50:02 UTC

ambari git commit: AMBARI-16220. No INSTALL commands. (magyari_sandor)

Repository: ambari
Updated Branches:
  refs/heads/trunk 5f1c6a58d -> 62010bcf6


AMBARI-16220. No INSTALL commands. (magyari_sandor)


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

Branch: refs/heads/trunk
Commit: 62010bcf687f61e61bf84068e127535d353402cf
Parents: 5f1c6a5
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Fri Jun 10 09:46:30 2016 -0700
Committer: Sandor Magyari <sm...@hortonworks.com>
Committed: Thu Jun 16 11:47:32 2016 +0200

----------------------------------------------------------------------
 .../AmbariManagementControllerImpl.java         |  28 +-
 .../svccomphost/ServiceComponentHostImpl.java   |  23 +-
 .../ambari/server/topology/AmbariContext.java   |   8 +
 .../ambari/server/topology/HostRequest.java     |  19 +-
 .../ClusterDeployWithHostsSyspreppedTest.java   | 413 +++++++++++++++++++
 .../ClusterInstallWithoutStartTest.java         |  21 +-
 6 files changed, 494 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/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 d7427a7..8ecf63f 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
@@ -705,7 +705,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       return;
     }
     Set<String> needRestartServices = ambariMetaInfo.getRestartRequiredServicesNames(
-        stackId.getStackName(), stackId.getStackVersion());
+      stackId.getStackName(), stackId.getStackVersion());
 
     if(needRestartServices.contains(service.getName())) {
       Map<String, ServiceComponent> m = service.getServiceComponents();
@@ -2660,8 +2660,18 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
             Map<String, Map<String, String>> configTags =
                 findConfigurationTagsWithOverrides(cluster, host.getHostName());
 
-            createHostAction(cluster, stage, scHost, configurations, configurationAttributes, configTags,
-                             roleCommand, requestParameters, event);
+            // Skip INSTALL task in case SysPrepped hosts and in case of server components. In case of server component
+            // START task should run configuration script.
+            if (Boolean.parseBoolean(configs.areHostsSysPrepped()) &&
+                  "INITIAL_INSTALL".equals(requestProperties.get("phase")) &&
+                    newState == State.INSTALLED && !isClientComponent(cluster, scHost)) {
+              LOG.info("Skipping create of INSTALL task for {} on {} because host is sysprepped.", scHost
+                .getServiceComponentName(), scHost.getHostName());
+            } else {
+              createHostAction(cluster, stage, scHost, configurations, configurationAttributes, configTags,
+                roleCommand, requestParameters, event);
+            }
+
           }
         }
       }
@@ -2745,6 +2755,18 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
     return false;
   }
 
+
+  private boolean isClientComponent(Cluster cluster, ServiceComponentHost sch) throws AmbariException {
+    Service service = cluster.getService(sch.getServiceName());
+    if (service != null) {
+      ServiceComponent serviceComponent = service.getServiceComponent(sch.getServiceComponentName());
+      if (serviceComponent != null) {
+        return serviceComponent.isClientComponent();
+      }
+    }
+    return false;
+  }
+
   @Override
   public ExecutionCommand getExecutionCommand(Cluster cluster,
                                               ServiceComponentHost scHost,

http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 70af8ec..4f8fda6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -178,9 +178,9 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
       new ServiceComponentHostOpStartedTransition())
 
   .addTransition(State.INSTALLING,
-      State.INSTALLED,
-      ServiceComponentHostEventType.HOST_SVCCOMP_OP_SUCCEEDED,
-      new ServiceComponentHostOpCompletedTransition())
+    State.INSTALLED,
+    ServiceComponentHostEventType.HOST_SVCCOMP_OP_SUCCEEDED,
+    new ServiceComponentHostOpCompletedTransition())
 
   .addTransition(State.INSTALLING,
       State.INSTALLED,
@@ -219,19 +219,24 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
 
   // Allow transition on abort
   .addTransition(State.INSTALL_FAILED,
-      State.INSTALL_FAILED,
-      ServiceComponentHostEventType.HOST_SVCCOMP_OP_FAILED,
-      new ServiceComponentHostOpCompletedTransition())
+    State.INSTALL_FAILED,
+    ServiceComponentHostEventType.HOST_SVCCOMP_OP_FAILED,
+    new ServiceComponentHostOpCompletedTransition())
 
   .addTransition(State.INSTALLED,
+    State.STARTING,
+    ServiceComponentHostEventType.HOST_SVCCOMP_START,
+    new ServiceComponentHostOpStartedTransition())
+
+    .addTransition(State.INIT,
       State.STARTING,
       ServiceComponentHostEventType.HOST_SVCCOMP_START,
       new ServiceComponentHostOpStartedTransition())
 
   .addTransition(State.INSTALLED,
-      State.UNINSTALLING,
-      ServiceComponentHostEventType.HOST_SVCCOMP_UNINSTALL,
-      new ServiceComponentHostOpStartedTransition())
+    State.UNINSTALLING,
+    ServiceComponentHostEventType.HOST_SVCCOMP_UNINSTALL,
+    new ServiceComponentHostOpStartedTransition())
 
   .addTransition(State.INSTALLED,
       State.INSTALLING,

http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 849c696..641a522 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -91,6 +91,9 @@ public class AmbariContext {
   @Inject
   private PersistedState persistedState;
 
+  @Inject
+  private org.apache.ambari.server.configuration.Configuration configs;
+
   private static AmbariManagementController controller;
   private static ClusterController clusterController;
   //todo: task id's.  Use existing mechanism for getting next task id sequence
@@ -114,6 +117,11 @@ public class AmbariContext {
     return cluster.getSecurityType() == SecurityType.KERBEROS;
   }
 
+  public boolean areHostsSysPrepped() {
+    return Boolean.parseBoolean(configs.areHostsSysPrepped());
+  }
+
+
   //todo: change return type to a topology abstraction
   public HostRoleCommand createAmbariTask(long requestId, long stageId, String component, String host, TaskType type) {
     HostRoleCommand task = hostRoleCommandFactory.create(host, Role.valueOf(component), null, RoleCommand.valueOf(type.name()));

http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java
index 00ecb98..99d7eec 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/HostRequest.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.server.topology;
 
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.api.predicate.InvalidQueryException;
 import org.apache.ambari.server.api.predicate.PredicateCompiler;
 import org.apache.ambari.server.controller.RequestStatusResponse;
@@ -32,6 +33,9 @@ import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
 import org.apache.ambari.server.orm.entities.TopologyHostRequestEntity;
 import org.apache.ambari.server.orm.entities.TopologyHostTaskEntity;
 import org.apache.ambari.server.orm.entities.TopologyLogicalTaskEntity;
+import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.host.HostImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -205,12 +209,19 @@ public class HostRequest implements Comparable<HostRequest> {
           "PENDING HOST ASSIGNMENT : HOSTGROUP=" + getHostgroupName();
 
       AmbariContext context = topology.getAmbariContext();
-      HostRoleCommand logicalInstallTask = context.createAmbariTask(
+      Stack stack = hostGroup.getStack();
+
+      // Skip INSTALL task in case SysPrepped hosts and in case of server components. In case of server component
+      // START task should run configuration script.
+      if (context.areHostsSysPrepped() && stack != null && !stack.getComponentInfo(component).isClient()) {
+        LOG.info("Skipping create of INSTALL task for {} on {} because host is sysprepped.", component, hostName);
+      } else {
+        HostRoleCommand logicalInstallTask = context.createAmbariTask(
           getRequestId(), id, component, hostName, AmbariContext.TaskType.INSTALL);
-      logicalTasks.put(logicalInstallTask.getTaskId(), logicalInstallTask);
-      logicalTaskMap.get(installTask).put(component, logicalInstallTask.getTaskId());
+        logicalTasks.put(logicalInstallTask.getTaskId(), logicalInstallTask);
+        logicalTaskMap.get(installTask).put(component, logicalInstallTask.getTaskId());
+      }
 
-      Stack stack = hostGroup.getStack();
       // if component isn't a client, add a start task
       if (!skipStartTaskCreate && stack != null && !stack.getComponentInfo(component).isClient()) {
         HostRoleCommand logicalStartTask = context.createAmbariTask(

http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithHostsSyspreppedTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithHostsSyspreppedTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithHostsSyspreppedTest.java
new file mode 100644
index 0000000..1c2caa7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterDeployWithHostsSyspreppedTest.java
@@ -0,0 +1,413 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.topology;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.apache.ambari.server.Role;
+import org.apache.ambari.server.RoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleCommand;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariServer;
+import org.apache.ambari.server.controller.ClusterRequest;
+import org.apache.ambari.server.controller.ConfigurationRequest;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
+import org.apache.ambari.server.controller.internal.Stack;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.orm.entities.TopologyLogicalRequestEntity;
+import org.apache.ambari.server.security.encryption.CredentialStoreService;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.SecurityType;
+import org.easymock.Capture;
+import org.easymock.EasyMockRule;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.easymock.MockType;
+import org.easymock.TestSubject;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_ONLY;
+import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.isNull;
+import static org.easymock.EasyMock.newCapture;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(AmbariServer.class)
+public class ClusterDeployWithHostsSyspreppedTest {
+  private static final String CLUSTER_NAME = "test-cluster";
+  private static final long CLUSTER_ID = 1;
+  private static final String BLUEPRINT_NAME = "test-bp";
+  private static final String STACK_NAME = "test-stack";
+  private static final String STACK_VERSION = "test-stack-version";
+
+  @Rule
+  public EasyMockRule mocks = new EasyMockRule(this);
+
+  @TestSubject
+  private TopologyManager topologyManager = new TopologyManager();
+
+  @Mock(type = MockType.NICE)
+  private Blueprint blueprint;
+
+  @Mock(type = MockType.NICE)
+  private Stack stack;
+
+  @Mock(type = MockType.NICE)
+  private ProvisionClusterRequest request;
+  private PersistedTopologyRequest persistedTopologyRequest;
+//  @Mock(type = MockType.STRICT)
+  private LogicalRequestFactory logicalRequestFactory;
+  @Mock(type = MockType.DEFAULT)
+  private LogicalRequest logicalRequest;
+  @Mock(type = MockType.NICE)
+  private AmbariContext ambariContext;
+  @Mock(type = MockType.NICE)
+  private ConfigurationRequest configurationRequest;
+  @Mock(type = MockType.NICE)
+  private ConfigurationRequest configurationRequest2;
+  @Mock(type = MockType.NICE)
+  private ConfigurationRequest configurationRequest3;
+  @Mock(type = MockType.NICE)
+  private RequestStatusResponse requestStatusResponse;
+  @Mock(type = MockType.STRICT)
+  private ExecutorService executor;
+  @Mock(type = MockType.STRICT)
+  private PersistedState persistedState;
+  @Mock(type = MockType.NICE)
+  private HostGroup group1;
+  @Mock(type = MockType.NICE)
+  private HostGroup group2;
+  @Mock(type = MockType.STRICT)
+  private SecurityConfigurationFactory securityConfigurationFactory;
+  @Mock(type = MockType.STRICT)
+  private CredentialStoreService credentialStoreService;
+  @Mock(type = MockType.STRICT)
+  private ClusterController clusterController;
+  @Mock(type = MockType.STRICT)
+  private ResourceProvider resourceProvider;
+  @Mock(type = MockType.NICE)
+  private AmbariManagementController managementController;
+  @Mock(type = MockType.NICE)
+  private Clusters clusters;
+  @Mock(type = MockType.NICE)
+  private Cluster cluster;
+  @Mock(type = MockType.NICE)
+  private HostRoleCommand hostRoleCommandInstallComponent3;
+  @Mock(type = MockType.NICE)
+  private HostRoleCommand hostRoleCommandInstallComponent4;
+
+
+  @Mock(type = MockType.NICE)
+  private ComponentInfo serviceComponentInfo;
+  @Mock(type = MockType.NICE)
+  private ComponentInfo clientComponentInfo;
+
+  @Mock(type = MockType.STRICT)
+  private Future mockFuture;
+
+  private final Configuration stackConfig = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>());
+  private final Configuration bpConfiguration = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), stackConfig);
+  private final Configuration topoConfiguration = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), bpConfiguration);
+  private final Configuration bpGroup1Config = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), bpConfiguration);
+  private final Configuration bpGroup2Config = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), bpConfiguration);
+
+  private final Configuration topoGroup1Config = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), bpGroup1Config);
+  private final Configuration topoGroup2Config = new Configuration(new HashMap<String, Map<String, String>>(),
+    new HashMap<String, Map<String, Map<String, String>>>(), bpGroup2Config);
+
+  private HostGroupInfo group1Info = new HostGroupInfo("group1");
+  private HostGroupInfo group2Info = new HostGroupInfo("group2");
+  private Map<String, HostGroupInfo> groupInfoMap = new HashMap<String, HostGroupInfo>();
+
+  private Collection<String> group1Components = Arrays.asList("component1", "component2", "component3");
+  private Collection<String> group2Components = Arrays.asList("component3", "component4");
+
+  private Map<String, Collection<String>> group1ServiceComponents = new HashMap<String, Collection<String>>();
+  private Map<String, Collection<String>> group2ServiceComponents = new HashMap<String, Collection<String>>();
+
+  private Map<String, Collection<String>> serviceComponents = new HashMap<String, Collection<String>>();
+
+  private String predicate = "Hosts/host_name=foo";
+
+  private List<TopologyValidator> topologyValidators = new ArrayList<TopologyValidator>();
+
+  private Capture<ClusterTopology> clusterTopologyCapture;
+  private Capture<Map<String, Object>> configRequestPropertiesCapture;
+  private Capture<Map<String, Object>> configRequestPropertiesCapture2;
+  private Capture<Map<String, Object>> configRequestPropertiesCapture3;
+  private Capture<ClusterRequest> updateClusterConfigRequestCapture;
+  private Capture<Runnable> updateConfigTaskCapture;
+
+  @Before
+  public void setup() throws Exception {
+    clusterTopologyCapture = newCapture();
+    configRequestPropertiesCapture = newCapture();
+    configRequestPropertiesCapture2 = newCapture();
+    configRequestPropertiesCapture3 = newCapture();
+    updateClusterConfigRequestCapture = newCapture();
+    updateConfigTaskCapture = newCapture();
+
+    topoConfiguration.setProperty("service1-site", "s1-prop", "s1-prop-value");
+    topoConfiguration.setProperty("service2-site", "s2-prop", "s2-prop-value");
+    topoConfiguration.setProperty("cluster-env", "g-prop", "g-prop-value");
+
+    //clusterRequestCapture = new Capture<ClusterRequest>();
+    // group 1 has fqdn specified
+    group1Info.addHost("host1");
+    group1Info.setConfiguration(topoGroup1Config);
+    // group 2 has host_count and host_predicate specified
+    group2Info.setRequestedCount(2);
+    group2Info.setPredicate(predicate);
+    group2Info.setConfiguration(topoGroup2Config);
+
+    groupInfoMap.put("group1", group1Info);
+    groupInfoMap.put("group2", group2Info);
+
+    Map<String, HostGroup> groupMap = new HashMap<String, HostGroup>();
+    groupMap.put("group1", group1);
+    groupMap.put("group2", group2);
+
+    serviceComponents.put("service1", Arrays.asList("component1", "component3"));
+    serviceComponents.put("service2", Arrays.asList("component2", "component4"));
+
+    group1ServiceComponents.put("service1", Arrays.asList("component1", "component3"));
+    group1ServiceComponents.put("service2", Collections.singleton("component2"));
+    group2ServiceComponents.put("service2", Collections.singleton("component3"));
+    group2ServiceComponents.put("service2", Collections.singleton("component4"));
+
+    expect(blueprint.getHostGroup("group1")).andReturn(group1).anyTimes();
+    expect(blueprint.getHostGroup("group2")).andReturn(group2).anyTimes();
+    expect(blueprint.getComponents("service1")).andReturn(Arrays.asList("component1", "component3")).anyTimes();
+    expect(blueprint.getComponents("service2")).andReturn(Arrays.asList("component2", "component4")).anyTimes();
+    expect(blueprint.getConfiguration()).andReturn(bpConfiguration).anyTimes();
+    expect(blueprint.getHostGroups()).andReturn(groupMap).anyTimes();
+    expect(blueprint.getHostGroupsForComponent("component1")).andReturn(Collections.singleton(group1)).anyTimes();
+    expect(blueprint.getHostGroupsForComponent("component2")).andReturn(Collections.singleton(group1)).anyTimes();
+    expect(blueprint.getHostGroupsForComponent("component3")).andReturn(Arrays.asList(group1, group2)).anyTimes();
+    expect(blueprint.getHostGroupsForComponent("component4")).andReturn(Collections.singleton(group2)).anyTimes();
+    expect(blueprint.getHostGroupsForService("service1")).andReturn(Arrays.asList(group1, group2)).anyTimes();
+    expect(blueprint.getHostGroupsForService("service2")).andReturn(Arrays.asList(group1, group2)).anyTimes();
+    expect(blueprint.getName()).andReturn(BLUEPRINT_NAME).anyTimes();
+    expect(blueprint.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes();
+    expect(blueprint.getStack()).andReturn(stack).anyTimes();
+    // don't expect toEntity()
+
+    expect(stack.getAllConfigurationTypes("service1")).andReturn(Arrays.asList("service1-site", "service1-env")).anyTimes();
+    expect(stack.getAllConfigurationTypes("service2")).andReturn(Arrays.asList("service2-site", "service2-env")).anyTimes();
+    expect(stack.getAutoDeployInfo("component1")).andReturn(null).anyTimes();
+    expect(stack.getAutoDeployInfo("component2")).andReturn(null).anyTimes();
+    expect(stack.getAutoDeployInfo("component3")).andReturn(null).anyTimes();
+    expect(stack.getAutoDeployInfo("component4")).andReturn(null).anyTimes();
+
+    expect(serviceComponentInfo.isClient()).andReturn(false).anyTimes();
+    expect(clientComponentInfo.isClient()).andReturn(true).anyTimes();
+
+    expect(stack.getComponentInfo("component1")).andReturn(serviceComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component2")).andReturn(serviceComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component3")).andReturn(clientComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component4")).andReturn(clientComponentInfo).anyTimes();
+
+    expect(stack.getCardinality("component1")).andReturn(new Cardinality("1")).anyTimes();
+    expect(stack.getCardinality("component2")).andReturn(new Cardinality("1")).anyTimes();
+    expect(stack.getCardinality("component3")).andReturn(new Cardinality("1+")).anyTimes();
+    expect(stack.getCardinality("component4")).andReturn(new Cardinality("1+")).anyTimes();
+    expect(stack.getComponents()).andReturn(serviceComponents).anyTimes();
+    expect(stack.getComponents("service1")).andReturn(serviceComponents.get("service1")).anyTimes();
+    expect(stack.getComponents("service2")).andReturn(serviceComponents.get("service2")).anyTimes();
+    expect(stack.getConfiguration()).andReturn(stackConfig).anyTimes();
+    expect(stack.getName()).andReturn(STACK_NAME).anyTimes();
+    expect(stack.getVersion()).andReturn(STACK_VERSION).anyTimes();
+    expect(stack.getServiceForConfigType("service1-site")).andReturn("service1").anyTimes();
+    expect(stack.getServiceForConfigType("service2-site")).andReturn("service2").anyTimes();
+    expect(stack.getExcludedConfigurationTypes("service1")).andReturn(Collections.<String>emptySet()).anyTimes();
+    expect(stack.getExcludedConfigurationTypes("service2")).andReturn(Collections.<String>emptySet()).anyTimes();
+
+    expect(request.getBlueprint()).andReturn(blueprint).anyTimes();
+    expect(request.getClusterId()).andReturn(CLUSTER_ID).anyTimes();
+    expect(request.getClusterName()).andReturn(CLUSTER_NAME).anyTimes();
+    expect(request.getDescription()).andReturn("Provision Cluster Test").anyTimes();
+    expect(request.getConfiguration()).andReturn(topoConfiguration).anyTimes();
+    expect(request.getHostGroupInfo()).andReturn(groupInfoMap).anyTimes();
+    expect(request.getTopologyValidators()).andReturn(topologyValidators).anyTimes();
+    expect(request.getConfigRecommendationStrategy()).andReturn(ConfigRecommendationStrategy.NEVER_APPLY);
+    expect(request.getProvisionAction()).andReturn(INSTALL_ONLY).anyTimes();
+    expect(request.getSecurityConfiguration()).andReturn(null).anyTimes();
+
+
+    expect(group1.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes();
+    expect(group1.getCardinality()).andReturn("test cardinality").anyTimes();
+    expect(group1.containsMasterComponent()).andReturn(true).anyTimes();
+    expect(group1.getComponentNames()).andReturn(group1Components).anyTimes();
+    expect(group1.getComponents("service1")).andReturn(group1ServiceComponents.get("service1")).anyTimes();
+    expect(group1.getComponents("service2")).andReturn(group1ServiceComponents.get("service1")).anyTimes();
+    expect(group1.getConfiguration()).andReturn(topoGroup1Config).anyTimes();
+    expect(group1.getName()).andReturn("group1").anyTimes();
+    expect(group1.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes();
+    expect(group1.getStack()).andReturn(stack).anyTimes();
+
+    expect(group2.getBlueprintName()).andReturn(BLUEPRINT_NAME).anyTimes();
+    expect(group2.getCardinality()).andReturn("test cardinality").anyTimes();
+    expect(group2.containsMasterComponent()).andReturn(false).anyTimes();
+    expect(group2.getComponentNames()).andReturn(group2Components).anyTimes();
+    expect(group2.getComponents("service1")).andReturn(group2ServiceComponents.get("service1")).anyTimes();
+    expect(group2.getComponents("service2")).andReturn(group2ServiceComponents.get("service2")).anyTimes();
+    expect(group2.getConfiguration()).andReturn(topoGroup2Config).anyTimes();
+    expect(group2.getName()).andReturn("group2").anyTimes();
+    expect(group2.getServices()).andReturn(Arrays.asList("service1", "service2")).anyTimes();
+    expect(group2.getStack()).andReturn(stack).anyTimes();
+
+    // Create partial mock to allow actual logical request creation
+    logicalRequestFactory = createMockBuilder(LogicalRequestFactory.class).addMockedMethod(
+      LogicalRequestFactory.class.getMethod("createRequest",
+        Long.class, TopologyRequest.class, ClusterTopology.class,
+        TopologyLogicalRequestEntity.class)).createMock();
+    Field f = TopologyManager.class.getDeclaredField("logicalRequestFactory");
+    f.setAccessible(true);
+    f.set(topologyManager, logicalRequestFactory);
+
+    PowerMock.mockStatic(AmbariServer.class);
+    expect(AmbariServer.getController()).andReturn(managementController).anyTimes();
+    PowerMock.replay(AmbariServer.class);
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    expect(clusters.getClusterById(anyLong())).andReturn(cluster).anyTimes();
+    expect(cluster.getClusterName()).andReturn(CLUSTER_NAME).anyTimes();
+
+    expect(ambariContext.getPersistedTopologyState()).andReturn(persistedState).anyTimes();
+    //todo: don't ignore param
+    ambariContext.createAmbariResources(isA(ClusterTopology.class), eq(CLUSTER_NAME), (SecurityType) isNull(), (String) isNull());
+    expectLastCall().once();
+    expect(ambariContext.getNextRequestId()).andReturn(1L).once();
+    expect(ambariContext.isClusterKerberosEnabled(CLUSTER_ID)).andReturn(false).anyTimes();
+    expect(ambariContext.getClusterId(CLUSTER_NAME)).andReturn(CLUSTER_ID).anyTimes();
+    expect(ambariContext.getClusterName(CLUSTER_ID)).andReturn(CLUSTER_NAME).anyTimes();
+    expect(ambariContext.areHostsSysPrepped()).andReturn(true).anyTimes();
+    // so only INITIAL config
+    expect(ambariContext.createConfigurationRequests(capture(configRequestPropertiesCapture))).
+      andReturn(Collections.singletonList(configurationRequest));
+    expect(ambariContext.createConfigurationRequests(capture(configRequestPropertiesCapture2))).
+      andReturn(Collections.singletonList(configurationRequest2)).once();
+    expect(ambariContext.createConfigurationRequests(capture(configRequestPropertiesCapture3))).
+      andReturn(Collections.singletonList(configurationRequest3)).once();
+    // INSTALL task expectation
+
+
+    expect(ambariContext.createAmbariTask(anyLong(), anyLong(), eq("component3"),
+      anyString(), eq(AmbariContext.TaskType.INSTALL))).andReturn(hostRoleCommandInstallComponent3).times(3);
+    expect(ambariContext.createAmbariTask(anyLong(), anyLong(), eq("component4"),
+      anyString(), eq(AmbariContext.TaskType.INSTALL))).andReturn(hostRoleCommandInstallComponent4).times(2);
+
+    expect(hostRoleCommandInstallComponent3.getTaskId()).andReturn(1L).atLeastOnce();
+    expect(hostRoleCommandInstallComponent3.getRoleCommand()).andReturn(RoleCommand.INSTALL).atLeastOnce();
+    expect(hostRoleCommandInstallComponent3.getRole()).andReturn(Role.INSTALL_PACKAGES).atLeastOnce();
+    expect(hostRoleCommandInstallComponent3.getStatus()).andReturn(HostRoleStatus.COMPLETED).atLeastOnce();
+
+    expect(hostRoleCommandInstallComponent4.getTaskId()).andReturn(2L).atLeastOnce();
+    expect(hostRoleCommandInstallComponent4.getRoleCommand()).andReturn(RoleCommand.INSTALL).atLeastOnce();
+    expect(hostRoleCommandInstallComponent4.getRole()).andReturn(Role.INSTALL_PACKAGES).atLeastOnce();
+    expect(hostRoleCommandInstallComponent4.getStatus()).andReturn(HostRoleStatus.COMPLETED).atLeastOnce();
+
+    ambariContext.setConfigurationOnCluster(capture(updateClusterConfigRequestCapture));
+    expectLastCall().times(3);
+    ambariContext.persistInstallStateForUI(CLUSTER_NAME, STACK_NAME, STACK_VERSION);
+    expectLastCall().once();
+
+    expect(clusterController.ensureResourceProvider(anyObject(Resource.Type.class))).andReturn(resourceProvider);
+    expect(executor.submit(anyObject(AsyncCallableService.class))).andReturn(mockFuture);
+
+    persistedTopologyRequest = new PersistedTopologyRequest(1, request);
+    expect(persistedState.getAllRequests()).andReturn(Collections.<ClusterTopology,
+      List<LogicalRequest>>emptyMap()).once();
+    expect(persistedState.persistTopologyRequest(request)).andReturn(persistedTopologyRequest).once();
+    persistedState.persistLogicalRequest((LogicalRequest) anyObject(), anyLong());
+    expectLastCall().once();
+
+    replay(blueprint, stack, request, group1, group2, ambariContext, logicalRequestFactory, logicalRequest,
+      configurationRequest, configurationRequest2, configurationRequest3, requestStatusResponse, executor,
+      persistedState, securityConfigurationFactory, credentialStoreService, clusterController, resourceProvider,
+      mockFuture, managementController, clusters, cluster, hostRoleCommandInstallComponent3,
+      hostRoleCommandInstallComponent4, serviceComponentInfo, clientComponentInfo);
+
+    Class clazz = TopologyManager.class;
+
+    f = clazz.getDeclaredField("executor");
+    f.setAccessible(true);
+    f.set(topologyManager, executor);
+
+    EasyMockSupport.injectMocks(topologyManager);
+  }
+
+  @After
+  public void tearDown() {
+    verify(blueprint, stack, request, group1, group2, ambariContext, logicalRequestFactory,
+      logicalRequest, configurationRequest, configurationRequest2, configurationRequest3,
+      requestStatusResponse, executor, persistedState, mockFuture,
+      managementController, clusters, cluster, hostRoleCommandInstallComponent3, hostRoleCommandInstallComponent4);
+
+    reset(blueprint, stack, request, group1, group2, ambariContext, logicalRequestFactory,
+      logicalRequest, configurationRequest, configurationRequest2, configurationRequest3,
+      requestStatusResponse, executor, persistedState, mockFuture,
+      managementController, clusters, cluster, hostRoleCommandInstallComponent3, hostRoleCommandInstallComponent4);
+  }
+
+  @Test
+  public void testProvisionCluster() throws Exception {
+    topologyManager.provisionCluster(request);
+    LogicalRequest request = topologyManager.getRequest(1);
+    assertEquals(request.getHostRequests().size(), 3);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/62010bcf/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
index 0382b03..645110a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/topology/ClusterInstallWithoutStartTest.java
@@ -32,6 +32,7 @@ import static org.easymock.EasyMock.newCapture;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -62,6 +63,7 @@ import org.apache.ambari.server.orm.entities.TopologyLogicalRequestEntity;
 import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.SecurityType;
 import org.easymock.Capture;
 import org.easymock.EasyMockRule;
@@ -141,6 +143,12 @@ public class ClusterInstallWithoutStartTest {
   @Mock(type = MockType.NICE)
   private HostRoleCommand hostRoleCommand;
 
+
+  @Mock(type = MockType.NICE)
+  private ComponentInfo serviceComponentInfo;
+  @Mock(type = MockType.NICE)
+  private ComponentInfo clientComponentInfo;
+
   @Mock(type = MockType.STRICT)
   private Future mockFuture;
 
@@ -243,6 +251,15 @@ public class ClusterInstallWithoutStartTest {
     expect(stack.getAutoDeployInfo("component2")).andReturn(null).anyTimes();
     expect(stack.getAutoDeployInfo("component3")).andReturn(null).anyTimes();
     expect(stack.getAutoDeployInfo("component4")).andReturn(null).anyTimes();
+
+    expect(serviceComponentInfo.isClient()).andReturn(false).anyTimes();
+    expect(clientComponentInfo.isClient()).andReturn(true).anyTimes();
+
+    expect(stack.getComponentInfo("component1")).andReturn(serviceComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component2")).andReturn(serviceComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component3")).andReturn(clientComponentInfo).anyTimes();
+    expect(stack.getComponentInfo("component4")).andReturn(clientComponentInfo).anyTimes();
+
     expect(stack.getCardinality("component1")).andReturn(new Cardinality("1")).anyTimes();
     expect(stack.getCardinality("component2")).andReturn(new Cardinality("1")).anyTimes();
     expect(stack.getCardinality("component3")).andReturn(new Cardinality("1+")).anyTimes();
@@ -316,7 +333,7 @@ public class ClusterInstallWithoutStartTest {
     expect(ambariContext.isClusterKerberosEnabled(CLUSTER_ID)).andReturn(false).anyTimes();
     expect(ambariContext.getClusterId(CLUSTER_NAME)).andReturn(CLUSTER_ID).anyTimes();
     expect(ambariContext.getClusterName(CLUSTER_ID)).andReturn(CLUSTER_NAME).anyTimes();
-    // cluster configuration task run() isn't executed by mock executor
+    expect(ambariContext.areHostsSysPrepped()).andReturn(false).anyTimes();
     // so only INITIAL config
     expect(ambariContext.createConfigurationRequests(capture(configRequestPropertiesCapture))).
       andReturn(Collections.singletonList(configurationRequest));
@@ -350,7 +367,7 @@ public class ClusterInstallWithoutStartTest {
     replay(blueprint, stack, request, group1, group2, ambariContext, logicalRequestFactory, logicalRequest,
       configurationRequest, configurationRequest2, configurationRequest3, requestStatusResponse, executor,
       persistedState, securityConfigurationFactory, credentialStoreService, clusterController, resourceProvider,
-      mockFuture, managementController, clusters, cluster, hostRoleCommand);
+      mockFuture, managementController, clusters, cluster, hostRoleCommand, serviceComponentInfo, clientComponentInfo);
 
     Class clazz = TopologyManager.class;