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 2014/05/08 03:17:12 UTC

[1/2] git commit: AMBARI-5708. stacks api returning invalid href's after endpoint renaming

Repository: ambari
Updated Branches:
  refs/heads/branch-1.6.0 858444339 -> 2eb05118d


AMBARI-5708.  stacks api returning invalid href's after endpoint renaming


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

Branch: refs/heads/branch-1.6.0
Commit: 2eb05118de3e61c54326503a4bc69bd1a2413720
Parents: 2ddb477
Author: John Speidel <js...@hortonworks.com>
Authored: Wed May 7 20:38:42 2014 -0400
Committer: John Speidel <js...@hortonworks.com>
Committed: Wed May 7 20:58:10 2014 -0400

----------------------------------------------------------------------
 .../resources/BaseStacksResourceDefinition.java | 62 +++++++++++++++
 .../OperatingSystemResourceDefinition.java      |  2 +-
 .../StackConfigurationResourceDefinition.java   |  3 +-
 .../StackDependencyResourceDefinition.java      |  2 +-
 ...StackServiceComponentResourceDefinition.java |  3 +-
 .../StackServiceResourceDefinition.java         |  2 +-
 .../StackVersionResourceDefinition.java         |  2 +-
 .../BaseStacksResourceDefinitionTest.java       | 82 ++++++++++++++++++++
 8 files changed, 150 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinition.java
new file mode 100644
index 0000000..63b1ca7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinition.java
@@ -0,0 +1,62 @@
+/**
+ * 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.api.resources;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Abstract base class for all stacks related resource definitions.
+ * Because we cloned /stacks from /stacks2 and changed the endpoint names in stacks,
+ * this class is a temporary mechanism to deviate from the standard /stacks2 endpoint names.
+ *
+ */
+public abstract class BaseStacksResourceDefinition extends BaseResourceDefinition {
+  protected BaseStacksResourceDefinition(Resource.Type resourceType) {
+    super(resourceType);
+  }
+
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    return Collections.<PostProcessor>singletonList(new StacksHrefProcessor());
+  }
+
+  private class StacksHrefProcessor extends BaseHrefPostProcessor {
+    @Override
+    /**
+     * If processing a /stacks endpoint, replace the endpoint names.
+     */
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      super.process(request, resultNode, href);
+
+      String nodeHref = resultNode.getProperty("href");
+      if (nodeHref != null && nodeHref.contains("/stacks/")) {
+        nodeHref = nodeHref.replace("stackServices", "services");
+        nodeHref = nodeHref.replace("serviceComponents", "components");
+        nodeHref = nodeHref.replace("operatingSystems", "operating_systems");
+      }
+
+      resultNode.setProperty("href", nodeHref);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/OperatingSystemResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/OperatingSystemResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/OperatingSystemResourceDefinition.java
index b9c85ec..6faf6fb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/OperatingSystemResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/OperatingSystemResourceDefinition.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
 
-public class OperatingSystemResourceDefinition extends BaseResourceDefinition {
+public class OperatingSystemResourceDefinition extends BaseStacksResourceDefinition {
 
   public OperatingSystemResourceDefinition(Type resourceType) {
     super(resourceType);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackConfigurationResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackConfigurationResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackConfigurationResourceDefinition.java
index 222ff42..53903ba 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackConfigurationResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackConfigurationResourceDefinition.java
@@ -22,8 +22,7 @@ package org.apache.ambari.server.api.resources;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
 
-public class StackConfigurationResourceDefinition extends
-    BaseResourceDefinition {
+public class StackConfigurationResourceDefinition extends BaseStacksResourceDefinition {
 
   public StackConfigurationResourceDefinition(Type resourceType) {
     super(resourceType);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackDependencyResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackDependencyResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackDependencyResourceDefinition.java
index 19ac584..0743a7f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackDependencyResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackDependencyResourceDefinition.java
@@ -23,7 +23,7 @@ import org.apache.ambari.server.controller.spi.Resource;
 /**
  * Stack Service Dependency Resource Definition.
  */
-public class StackDependencyResourceDefinition extends BaseResourceDefinition {
+public class StackDependencyResourceDefinition extends BaseStacksResourceDefinition {
 
   /**
    * Constructor.

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceComponentResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceComponentResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceComponentResourceDefinition.java
index 00620e9..cad2a99 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceComponentResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceComponentResourceDefinition.java
@@ -23,8 +23,7 @@ import org.apache.ambari.server.controller.spi.Resource;
 import java.util.Collections;
 import java.util.Set;
 
-public class StackServiceComponentResourceDefinition extends
-    BaseResourceDefinition {
+public class StackServiceComponentResourceDefinition extends BaseStacksResourceDefinition {
 
   public StackServiceComponentResourceDefinition() {
     super(Resource.Type.StackServiceComponent);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceResourceDefinition.java
index 0c8f4f9..cb1dfb1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackServiceResourceDefinition.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
 
-public class StackServiceResourceDefinition extends BaseResourceDefinition {
+public class StackServiceResourceDefinition extends BaseStacksResourceDefinition {
 
   public StackServiceResourceDefinition(Type resourceType) {
     super(resourceType);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
index 97f1908..d641e4c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/StackVersionResourceDefinition.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
 
-public class StackVersionResourceDefinition extends BaseResourceDefinition {
+public class StackVersionResourceDefinition extends BaseStacksResourceDefinition {
 
   public StackVersionResourceDefinition(Type resourceType) {
     super(Resource.Type.StackVersion);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2eb05118/ambari-server/src/test/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinitionTest.java
new file mode 100644
index 0000000..b235876
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/BaseStacksResourceDefinitionTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.api.resources;
+
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.api.util.TreeNodeImpl;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+
+/**
+ * BaseStacksResourceDefinition unit tests
+ */
+public class BaseStacksResourceDefinitionTest {
+
+  @Test
+  public void testHrefCreation() {
+    TestResourceDefinition resourceDefinition = new TestResourceDefinition();
+    ResourceDefinition.PostProcessor processor = resourceDefinition.getPostProcessors().iterator().next();
+
+    TreeNode<Resource> node = new TreeNodeImpl<Resource>(new TreeNodeImpl<Resource>(null, null, null), null, "test");
+
+    String href = "/stacks/HDP/versions/1.3.2/stackServices/foo";
+    processor.process(null, node, href);
+    assertEquals("/stacks/HDP/versions/1.3.2/services/foo", node.getProperty("href"));
+
+    href = "/stacks2/HDP/versions/1.3.2/stackServices/foo";
+    processor.process(null, node, href);
+    assertEquals("/stacks2/HDP/versions/1.3.2/stackServices/foo", node.getProperty("href"));
+
+    href = "/stacks/HDP/versions/1.3.2/stackServices/foo/serviceComponents";
+    processor.process(null, node, href);
+    assertEquals("/stacks/HDP/versions/1.3.2/services/foo/components", node.getProperty("href"));
+
+    href = "/stacks2/HDP/versions/1.3.2/stackServices/foo/serviceComponents";
+    processor.process(null, node, href);
+    assertEquals("/stacks2/HDP/versions/1.3.2/stackServices/foo/serviceComponents", node.getProperty("href"));
+
+    href = "/stacks/HDP/versions/1.3.2/operatingSystems";
+    processor.process(null, node, href);
+    assertEquals("/stacks/HDP/versions/1.3.2/operating_systems", node.getProperty("href"));
+
+    href = "/stacks2/HDP/versions/1.3.2/operatingSystems";
+    processor.process(null, node, href);
+    assertEquals("/stacks2/HDP/versions/1.3.2/operatingSystems", node.getProperty("href"));
+  }
+
+  private class TestResourceDefinition extends BaseStacksResourceDefinition {
+    private TestResourceDefinition() {
+      super(Resource.Type.StackServiceComponent);
+    }
+
+    @Override
+    public String getPluralName() {
+      return "tests";
+    }
+
+    @Override
+    public String getSingularName() {
+      return "test";
+    }
+  }
+}
+


[2/2] git commit: AMBARI-5706. Provide basic validation for cluster create via a blueprint

Posted by js...@apache.org.
AMBARI-5706. Provide basic validation for cluster create via a blueprint


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

Branch: refs/heads/branch-1.6.0
Commit: 2ddb477f71da7ce7f34a973ca96208b7c1f33780
Parents: 8584443
Author: John Speidel <js...@hortonworks.com>
Authored: Wed May 7 17:59:56 2014 -0400
Committer: John Speidel <js...@hortonworks.com>
Committed: Wed May 7 20:58:10 2014 -0400

----------------------------------------------------------------------
 .../internal/ClusterResourceProvider.java       |  18 +-
 .../internal/ClusterResourceProviderTest.java   | 515 +++++++++++++++++++
 2 files changed, 531 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2ddb477f/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index f038df4..1d05b46 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -671,7 +671,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
    * @param properties           request properties
    * @param blueprintHostGroups  blueprint host groups
    *
-   * @throws IllegalArgumentException a host-group in the request doesn't match a host-group in the blueprint
+   * @throws IllegalArgumentException a host_group in the request doesn't match a host-group in the blueprint
    */
   private void applyRequestInfoToHostGroups(Map<String, Object> properties,
                                             Map<String, HostGroup> blueprintHostGroups)
@@ -681,9 +681,16 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
     Collection<Map<String, Object>> hostGroups =
         (Collection<Map<String, Object>>) properties.get("host_groups");
 
+    if (hostGroups == null || hostGroups.isEmpty()) {
+      throw new IllegalArgumentException("'host_groups' element must be included in cluster create body");
+    }
+
     // iterate over host groups provided in request body
     for (Map<String, Object> hostGroupProperties : hostGroups) {
       String name = (String) hostGroupProperties.get("name");
+      if (name == null || name.isEmpty()) {
+        throw new IllegalArgumentException("Every host_group must include a non-null 'name' property");
+      }
       HostGroup hostGroup = blueprintHostGroups.get(name);
 
       if (hostGroup == null) {
@@ -692,11 +699,18 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
       }
 
       Collection hosts = (Collection) hostGroupProperties.get("hosts");
+      if (hosts == null || hosts.isEmpty()) {
+        throw new IllegalArgumentException("Host group '" + name + "' must contain a 'hosts' element");
+      }
       for (Object oHost : hosts) {
         @SuppressWarnings("unchecked")
         Map<String, String> mapHostProperties = (Map<String, String>) oHost;
         //add host information to host group
-        hostGroup.addHostInfo(mapHostProperties.get("fqdn"));
+        String fqdn = mapHostProperties.get("fqdn");
+        if (fqdn == null || fqdn.isEmpty()) {
+          throw new IllegalArgumentException("Host group '" + name + "' hosts element must include at least one fqdn");
+        }
+        hostGroup.addHostInfo(fqdn);
       }
       Map<String, Map<String, String>> existingConfigurations = hostGroup.getConfigurations();
       overrideExistingProperties(existingConfigurations, (Collection<Map<String, String>>)

http://git-wip-us.apache.org/repos/asf/ambari/blob/2ddb477f/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
index e644b08..616df5b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java
@@ -698,6 +698,521 @@ public class ClusterResourceProviderTest {
   }
 
   @Test
+  public void testCreateResource_blueprint__noHostGroups() throws Exception {
+    String blueprintName = "test-blueprint";
+    String stackName = "test";
+    String stackVersion = "1.23";
+    String clusterName = "c1";
+
+    BlueprintDAO blueprintDAO = createStrictMock(BlueprintDAO.class);
+    AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+    AmbariManagementController managementController = createStrictMock(AmbariManagementController.class);
+    Request request = createNiceMock(Request.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+    BlueprintEntity blueprint = createNiceMock(BlueprintEntity.class);
+    StackServiceResponse stackServiceResponse1 = createNiceMock(StackServiceResponse.class);
+    StackServiceResponse stackServiceResponse2 = createNiceMock(StackServiceResponse.class);
+    Capture<Set<StackServiceRequest>> stackServiceRequestCapture = new Capture<Set<StackServiceRequest>>();
+
+    StackServiceComponentResponse stackServiceComponentResponse1 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse2 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse3 = createNiceMock(StackServiceComponentResponse.class);
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture1 = new Capture<Set<StackServiceComponentRequest>>();
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture2 = new Capture<Set<StackServiceComponentRequest>>();
+
+    StackConfigurationResponse stackConfigurationResponse1 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse2 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse3 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse4 = createNiceMock(StackConfigurationResponse.class);
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture1 = new Capture<Set<StackConfigurationRequest>>();
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture2 = new Capture<Set<StackConfigurationRequest>>();
+
+    BlueprintConfigEntity blueprintConfig = createNiceMock(BlueprintConfigEntity.class);
+
+    HostGroupEntity hostGroup = createNiceMock(HostGroupEntity.class);
+    HostGroupComponentEntity hostGroupComponent1 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent2 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent3 = createNiceMock(HostGroupComponentEntity.class);
+
+    HostGroupConfigEntity hostGroupConfig = createNiceMock(HostGroupConfigEntity.class);
+
+    ServiceResourceProvider serviceResourceProvider = createStrictMock(ServiceResourceProvider.class);
+    ResourceProvider componentResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostComponentResourceProvider = createStrictMock(ResourceProvider.class);
+    ConfigGroupResourceProvider configGroupResourceProvider = createStrictMock(ConfigGroupResourceProvider.class);
+    PersistKeyValueImpl persistKeyValue = createNiceMock(PersistKeyValueImpl.class);
+
+    Set<StackServiceResponse> stackServiceResponses = new LinkedHashSet<StackServiceResponse>();
+    stackServiceResponses.add(stackServiceResponse1);
+    stackServiceResponses.add(stackServiceResponse2);
+
+    // service1 has 2 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses1 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses1.add(stackServiceComponentResponse1);
+    stackServiceComponentResponses1.add(stackServiceComponentResponse2);
+
+    // service2 has 1 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses2 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses2.add(stackServiceComponentResponse3);
+
+    // service1 has 1 config
+    Set<StackConfigurationResponse> stackConfigurationResponses1 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses1.add(stackConfigurationResponse1);
+
+    // service2 has 3 config
+    Set<StackConfigurationResponse> stackConfigurationResponses2 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses2.add(stackConfigurationResponse2);
+    stackConfigurationResponses2.add(stackConfigurationResponse3);
+    stackConfigurationResponses2.add(stackConfigurationResponse4);
+
+    Collection<HostGroupComponentEntity> hostGroupComponents = new LinkedHashSet<HostGroupComponentEntity>();
+    hostGroupComponents.add(hostGroupComponent1);
+    hostGroupComponents.add(hostGroupComponent2);
+    hostGroupComponents.add(hostGroupComponent3);
+
+    // request properties
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName);
+    properties.put(ClusterResourceProvider.BLUEPRINT_PROPERTY_ID, blueprintName);
+    propertySet.add(properties);
+
+    Map<String, String> mapGroupConfigProperties = new HashMap<String, String>();
+    mapGroupConfigProperties.put("myGroupProp", "awesomeValue");
+
+    // blueprint cluster configuration properties
+    Map<String, String> blueprintConfigProperties = new HashMap<String, String>();
+    blueprintConfigProperties.put("property1", "value2");
+    blueprintConfigProperties.put("new.property", "new.property.value");
+
+    // expectations
+    expect(request.getProperties()).andReturn(propertySet).anyTimes();
+    expect(blueprintDAO.findByName(blueprintName)).andReturn(blueprint);
+    expect(blueprint.getStackName()).andReturn(stackName);
+    expect(blueprint.getStackVersion()).andReturn(stackVersion);
+
+    expect(managementController.getStackServices(capture(stackServiceRequestCapture))).andReturn(stackServiceResponses);
+    expect(stackServiceResponse1.getServiceName()).andReturn("service1");
+    expect(stackServiceResponse2.getServiceName()).andReturn("service2");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture1))).
+        andReturn(stackServiceComponentResponses1);
+    expect(stackServiceComponentResponse1.getComponentName()).andReturn("component1");
+    expect(stackServiceComponentResponse2.getComponentName()).andReturn("component2");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture1))).
+        andReturn(stackConfigurationResponses1);
+    expect(stackConfigurationResponse1.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse1.getPropertyName()).andReturn("property1");
+    expect(stackConfigurationResponse1.getPropertyValue()).andReturn("value1");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture2))).
+        andReturn(stackServiceComponentResponses2);
+    expect(stackServiceComponentResponse3.getComponentName()).andReturn("component3");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture2))).
+        andReturn(stackConfigurationResponses2);
+    expect(stackConfigurationResponse2.getType()).andReturn("hdfs-site.xml");
+    expect(stackConfigurationResponse2.getPropertyName()).andReturn("property2");
+    expect(stackConfigurationResponse2.getPropertyValue()).andReturn("value2");
+
+    expect(stackConfigurationResponse3.getType()).andReturn("global.xml");
+    expect(stackConfigurationResponse3.getPropertyName()).andReturn("oozie_user");
+    expect(stackConfigurationResponse3.getPropertyValue()).andReturn("oozie");
+
+    expect(stackConfigurationResponse4.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse4.getPropertyName()).andReturn("property3");
+    expect(stackConfigurationResponse4.getPropertyValue()).andReturn("value3");
+
+    expect(blueprintConfig.getBlueprintName()).andReturn("test-blueprint").anyTimes();
+    expect(blueprintConfig.getType()).andReturn("core-site").anyTimes();
+
+    expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
+    expect(hostGroup.getName()).andReturn("group1").anyTimes();
+    expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
+    expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
+    expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
+    expect(hostGroupComponent3.getName()).andReturn("component3").anyTimes();
+    expect(hostGroup.getConfigurations()).andReturn(
+        Collections.<HostGroupConfigEntity>singleton(hostGroupConfig)).anyTimes();
+
+    expect(hostGroupConfig.getType()).andReturn("core-site").anyTimes();
+    expect(hostGroupConfig.getConfigData()).andReturn(new Gson().toJson(mapGroupConfigProperties)).anyTimes();
+
+    replay(blueprintDAO, managementController, request, response, blueprint, stackServiceResponse1, stackServiceResponse2,
+        stackServiceComponentResponse1, stackServiceComponentResponse2, stackServiceComponentResponse3,
+        stackConfigurationResponse1, stackConfigurationResponse2, stackConfigurationResponse3, stackConfigurationResponse4,
+        blueprintConfig, hostGroup, hostGroupComponent1, hostGroupComponent2, hostGroupComponent3, hostGroupConfig,
+        serviceResourceProvider, componentResourceProvider, hostResourceProvider, hostComponentResourceProvider,
+        configGroupResourceProvider, persistKeyValue, metaInfo);
+
+    // test
+    ClusterResourceProvider.init(blueprintDAO, metaInfo);
+    ResourceProvider provider = new TestClusterResourceProvider(
+        managementController, serviceResourceProvider, componentResourceProvider,
+        hostResourceProvider, hostComponentResourceProvider, configGroupResourceProvider);
+
+    try {
+      provider.createResources(request);
+      fail("Expected exception for missing password property");
+    } catch (IllegalArgumentException e) {
+      //expected
+    }
+  }
+
+  @Test
+  public void testCreateResource_blueprint__hostGroupMissingName() throws Exception {
+    String blueprintName = "test-blueprint";
+    String stackName = "test";
+    String stackVersion = "1.23";
+    String clusterName = "c1";
+
+    BlueprintDAO blueprintDAO = createStrictMock(BlueprintDAO.class);
+    AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+    AmbariManagementController managementController = createStrictMock(AmbariManagementController.class);
+    Request request = createNiceMock(Request.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+    BlueprintEntity blueprint = createNiceMock(BlueprintEntity.class);
+    StackServiceResponse stackServiceResponse1 = createNiceMock(StackServiceResponse.class);
+    StackServiceResponse stackServiceResponse2 = createNiceMock(StackServiceResponse.class);
+    Capture<Set<StackServiceRequest>> stackServiceRequestCapture = new Capture<Set<StackServiceRequest>>();
+
+    StackServiceComponentResponse stackServiceComponentResponse1 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse2 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse3 = createNiceMock(StackServiceComponentResponse.class);
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture1 = new Capture<Set<StackServiceComponentRequest>>();
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture2 = new Capture<Set<StackServiceComponentRequest>>();
+
+    StackConfigurationResponse stackConfigurationResponse1 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse2 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse3 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse4 = createNiceMock(StackConfigurationResponse.class);
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture1 = new Capture<Set<StackConfigurationRequest>>();
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture2 = new Capture<Set<StackConfigurationRequest>>();
+
+    BlueprintConfigEntity blueprintConfig = createNiceMock(BlueprintConfigEntity.class);
+
+    HostGroupEntity hostGroup = createNiceMock(HostGroupEntity.class);
+    HostGroupComponentEntity hostGroupComponent1 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent2 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent3 = createNiceMock(HostGroupComponentEntity.class);
+
+    HostGroupConfigEntity hostGroupConfig = createNiceMock(HostGroupConfigEntity.class);
+
+    ServiceResourceProvider serviceResourceProvider = createStrictMock(ServiceResourceProvider.class);
+    ResourceProvider componentResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostComponentResourceProvider = createStrictMock(ResourceProvider.class);
+    ConfigGroupResourceProvider configGroupResourceProvider = createStrictMock(ConfigGroupResourceProvider.class);
+    PersistKeyValueImpl persistKeyValue = createNiceMock(PersistKeyValueImpl.class);
+
+    Set<StackServiceResponse> stackServiceResponses = new LinkedHashSet<StackServiceResponse>();
+    stackServiceResponses.add(stackServiceResponse1);
+    stackServiceResponses.add(stackServiceResponse2);
+
+    // service1 has 2 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses1 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses1.add(stackServiceComponentResponse1);
+    stackServiceComponentResponses1.add(stackServiceComponentResponse2);
+
+    // service2 has 1 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses2 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses2.add(stackServiceComponentResponse3);
+
+    // service1 has 1 config
+    Set<StackConfigurationResponse> stackConfigurationResponses1 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses1.add(stackConfigurationResponse1);
+
+    // service2 has 3 config
+    Set<StackConfigurationResponse> stackConfigurationResponses2 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses2.add(stackConfigurationResponse2);
+    stackConfigurationResponses2.add(stackConfigurationResponse3);
+    stackConfigurationResponses2.add(stackConfigurationResponse4);
+
+    Collection<HostGroupComponentEntity> hostGroupComponents = new LinkedHashSet<HostGroupComponentEntity>();
+    hostGroupComponents.add(hostGroupComponent1);
+    hostGroupComponents.add(hostGroupComponent2);
+    hostGroupComponents.add(hostGroupComponent3);
+
+    // request properties
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName);
+    properties.put(ClusterResourceProvider.BLUEPRINT_PROPERTY_ID, blueprintName);
+    propertySet.add(properties);
+
+    Collection<Map<String, Object>> hostGroups = new ArrayList<Map<String, Object>>();
+    Map<String, Object> hostGroupProperties = new HashMap<String, Object>();
+    hostGroups.add(hostGroupProperties);
+    Collection<Map<String, String>> hostGroupHosts = new ArrayList<Map<String, String>>();
+    hostGroupProperties.put("hosts", hostGroupHosts);
+    Map<String, String> hostGroupHostProperties = new HashMap<String, String>();
+    hostGroupHostProperties.put("fqdn", "host.domain");
+    hostGroupHosts.add(hostGroupHostProperties);
+    properties.put("host_groups", hostGroups);
+
+    Map<String, String> mapGroupConfigProperties = new HashMap<String, String>();
+    mapGroupConfigProperties.put("myGroupProp", "awesomeValue");
+
+    // blueprint cluster configuration properties
+    Map<String, String> blueprintConfigProperties = new HashMap<String, String>();
+    blueprintConfigProperties.put("property1", "value2");
+    blueprintConfigProperties.put("new.property", "new.property.value");
+
+    // expectations
+    expect(request.getProperties()).andReturn(propertySet).anyTimes();
+    expect(blueprintDAO.findByName(blueprintName)).andReturn(blueprint);
+    expect(blueprint.getStackName()).andReturn(stackName);
+    expect(blueprint.getStackVersion()).andReturn(stackVersion);
+
+    expect(managementController.getStackServices(capture(stackServiceRequestCapture))).andReturn(stackServiceResponses);
+    expect(stackServiceResponse1.getServiceName()).andReturn("service1");
+    expect(stackServiceResponse2.getServiceName()).andReturn("service2");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture1))).
+        andReturn(stackServiceComponentResponses1);
+    expect(stackServiceComponentResponse1.getComponentName()).andReturn("component1");
+    expect(stackServiceComponentResponse2.getComponentName()).andReturn("component2");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture1))).
+        andReturn(stackConfigurationResponses1);
+    expect(stackConfigurationResponse1.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse1.getPropertyName()).andReturn("property1");
+    expect(stackConfigurationResponse1.getPropertyValue()).andReturn("value1");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture2))).
+        andReturn(stackServiceComponentResponses2);
+    expect(stackServiceComponentResponse3.getComponentName()).andReturn("component3");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture2))).
+        andReturn(stackConfigurationResponses2);
+    expect(stackConfigurationResponse2.getType()).andReturn("hdfs-site.xml");
+    expect(stackConfigurationResponse2.getPropertyName()).andReturn("property2");
+    expect(stackConfigurationResponse2.getPropertyValue()).andReturn("value2");
+
+    expect(stackConfigurationResponse3.getType()).andReturn("global.xml");
+    expect(stackConfigurationResponse3.getPropertyName()).andReturn("oozie_user");
+    expect(stackConfigurationResponse3.getPropertyValue()).andReturn("oozie");
+
+    expect(stackConfigurationResponse4.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse4.getPropertyName()).andReturn("property3");
+    expect(stackConfigurationResponse4.getPropertyValue()).andReturn("value3");
+
+    expect(blueprintConfig.getBlueprintName()).andReturn("test-blueprint").anyTimes();
+    expect(blueprintConfig.getType()).andReturn("core-site").anyTimes();
+
+    expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
+    expect(hostGroup.getName()).andReturn("group1").anyTimes();
+    expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
+    expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
+    expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
+    expect(hostGroupComponent3.getName()).andReturn("component3").anyTimes();
+    expect(hostGroup.getConfigurations()).andReturn(
+        Collections.<HostGroupConfigEntity>singleton(hostGroupConfig)).anyTimes();
+
+    expect(hostGroupConfig.getType()).andReturn("core-site").anyTimes();
+    expect(hostGroupConfig.getConfigData()).andReturn(new Gson().toJson(mapGroupConfigProperties)).anyTimes();
+
+    replay(blueprintDAO, managementController, request, response, blueprint, stackServiceResponse1, stackServiceResponse2,
+        stackServiceComponentResponse1, stackServiceComponentResponse2, stackServiceComponentResponse3,
+        stackConfigurationResponse1, stackConfigurationResponse2, stackConfigurationResponse3, stackConfigurationResponse4,
+        blueprintConfig, hostGroup, hostGroupComponent1, hostGroupComponent2, hostGroupComponent3, hostGroupConfig,
+        serviceResourceProvider, componentResourceProvider, hostResourceProvider, hostComponentResourceProvider,
+        configGroupResourceProvider, persistKeyValue, metaInfo);
+
+    // test
+    ClusterResourceProvider.init(blueprintDAO, metaInfo);
+    ResourceProvider provider = new TestClusterResourceProvider(
+        managementController, serviceResourceProvider, componentResourceProvider,
+        hostResourceProvider, hostComponentResourceProvider, configGroupResourceProvider);
+
+    try {
+      provider.createResources(request);
+      fail("Expected exception for missing password property");
+    } catch (IllegalArgumentException e) {
+      //expected
+    }
+  }
+
+  @Test
+  public void testCreateResource_blueprint__hostGroupMissingFQDN() throws Exception {
+    String blueprintName = "test-blueprint";
+    String stackName = "test";
+    String stackVersion = "1.23";
+    String clusterName = "c1";
+
+    BlueprintDAO blueprintDAO = createStrictMock(BlueprintDAO.class);
+    AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class);
+    AmbariManagementController managementController = createStrictMock(AmbariManagementController.class);
+    Request request = createNiceMock(Request.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+    BlueprintEntity blueprint = createNiceMock(BlueprintEntity.class);
+    StackServiceResponse stackServiceResponse1 = createNiceMock(StackServiceResponse.class);
+    StackServiceResponse stackServiceResponse2 = createNiceMock(StackServiceResponse.class);
+    Capture<Set<StackServiceRequest>> stackServiceRequestCapture = new Capture<Set<StackServiceRequest>>();
+
+    StackServiceComponentResponse stackServiceComponentResponse1 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse2 = createNiceMock(StackServiceComponentResponse.class);
+    StackServiceComponentResponse stackServiceComponentResponse3 = createNiceMock(StackServiceComponentResponse.class);
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture1 = new Capture<Set<StackServiceComponentRequest>>();
+    Capture<Set<StackServiceComponentRequest>> serviceComponentRequestCapture2 = new Capture<Set<StackServiceComponentRequest>>();
+
+    StackConfigurationResponse stackConfigurationResponse1 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse2 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse3 = createNiceMock(StackConfigurationResponse.class);
+    StackConfigurationResponse stackConfigurationResponse4 = createNiceMock(StackConfigurationResponse.class);
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture1 = new Capture<Set<StackConfigurationRequest>>();
+    Capture<Set<StackConfigurationRequest>> serviceConfigurationRequestCapture2 = new Capture<Set<StackConfigurationRequest>>();
+
+    BlueprintConfigEntity blueprintConfig = createNiceMock(BlueprintConfigEntity.class);
+
+    HostGroupEntity hostGroup = createNiceMock(HostGroupEntity.class);
+    HostGroupComponentEntity hostGroupComponent1 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent2 = createNiceMock(HostGroupComponentEntity.class);
+    HostGroupComponentEntity hostGroupComponent3 = createNiceMock(HostGroupComponentEntity.class);
+
+    HostGroupConfigEntity hostGroupConfig = createNiceMock(HostGroupConfigEntity.class);
+
+    ServiceResourceProvider serviceResourceProvider = createStrictMock(ServiceResourceProvider.class);
+    ResourceProvider componentResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostResourceProvider = createStrictMock(ResourceProvider.class);
+    ResourceProvider hostComponentResourceProvider = createStrictMock(ResourceProvider.class);
+    ConfigGroupResourceProvider configGroupResourceProvider = createStrictMock(ConfigGroupResourceProvider.class);
+    PersistKeyValueImpl persistKeyValue = createNiceMock(PersistKeyValueImpl.class);
+
+    Set<StackServiceResponse> stackServiceResponses = new LinkedHashSet<StackServiceResponse>();
+    stackServiceResponses.add(stackServiceResponse1);
+    stackServiceResponses.add(stackServiceResponse2);
+
+    // service1 has 2 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses1 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses1.add(stackServiceComponentResponse1);
+    stackServiceComponentResponses1.add(stackServiceComponentResponse2);
+
+    // service2 has 1 components
+    Set<StackServiceComponentResponse> stackServiceComponentResponses2 = new LinkedHashSet<StackServiceComponentResponse>();
+    stackServiceComponentResponses2.add(stackServiceComponentResponse3);
+
+    // service1 has 1 config
+    Set<StackConfigurationResponse> stackConfigurationResponses1 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses1.add(stackConfigurationResponse1);
+
+    // service2 has 3 config
+    Set<StackConfigurationResponse> stackConfigurationResponses2 = new LinkedHashSet<StackConfigurationResponse>();
+    stackConfigurationResponses2.add(stackConfigurationResponse2);
+    stackConfigurationResponses2.add(stackConfigurationResponse3);
+    stackConfigurationResponses2.add(stackConfigurationResponse4);
+
+    Collection<HostGroupComponentEntity> hostGroupComponents = new LinkedHashSet<HostGroupComponentEntity>();
+    hostGroupComponents.add(hostGroupComponent1);
+    hostGroupComponents.add(hostGroupComponent2);
+    hostGroupComponents.add(hostGroupComponent3);
+
+    // request properties
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    properties.put(ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID, clusterName);
+    properties.put(ClusterResourceProvider.BLUEPRINT_PROPERTY_ID, blueprintName);
+    propertySet.add(properties);
+
+    Collection<Map<String, Object>> hostGroups = new ArrayList<Map<String, Object>>();
+    Map<String, Object> hostGroupProperties = new HashMap<String, Object>();
+    hostGroups.add(hostGroupProperties);
+    hostGroupProperties.put("name", "group1");
+    Collection<Map<String, String>> hostGroupHosts = new ArrayList<Map<String, String>>();
+    hostGroupProperties.put("hosts", hostGroupHosts);
+    Map<String, String> hostGroupHostProperties = new HashMap<String, String>();
+        hostGroupHosts.add(hostGroupHostProperties);
+    properties.put("host_groups", hostGroups);
+
+    Map<String, String> mapGroupConfigProperties = new HashMap<String, String>();
+    mapGroupConfigProperties.put("myGroupProp", "awesomeValue");
+
+    // blueprint cluster configuration properties
+    Map<String, String> blueprintConfigProperties = new HashMap<String, String>();
+    blueprintConfigProperties.put("property1", "value2");
+    blueprintConfigProperties.put("new.property", "new.property.value");
+
+    // expectations
+    expect(request.getProperties()).andReturn(propertySet).anyTimes();
+    expect(blueprintDAO.findByName(blueprintName)).andReturn(blueprint);
+    expect(blueprint.getStackName()).andReturn(stackName);
+    expect(blueprint.getStackVersion()).andReturn(stackVersion);
+
+    expect(managementController.getStackServices(capture(stackServiceRequestCapture))).andReturn(stackServiceResponses);
+    expect(stackServiceResponse1.getServiceName()).andReturn("service1");
+    expect(stackServiceResponse2.getServiceName()).andReturn("service2");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture1))).
+        andReturn(stackServiceComponentResponses1);
+    expect(stackServiceComponentResponse1.getComponentName()).andReturn("component1");
+    expect(stackServiceComponentResponse2.getComponentName()).andReturn("component2");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture1))).
+        andReturn(stackConfigurationResponses1);
+    expect(stackConfigurationResponse1.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse1.getPropertyName()).andReturn("property1");
+    expect(stackConfigurationResponse1.getPropertyValue()).andReturn("value1");
+
+    expect(managementController.getStackComponents(capture(serviceComponentRequestCapture2))).
+        andReturn(stackServiceComponentResponses2);
+    expect(stackServiceComponentResponse3.getComponentName()).andReturn("component3");
+
+    expect(managementController.getStackConfigurations(capture(serviceConfigurationRequestCapture2))).
+        andReturn(stackConfigurationResponses2);
+    expect(stackConfigurationResponse2.getType()).andReturn("hdfs-site.xml");
+    expect(stackConfigurationResponse2.getPropertyName()).andReturn("property2");
+    expect(stackConfigurationResponse2.getPropertyValue()).andReturn("value2");
+
+    expect(stackConfigurationResponse3.getType()).andReturn("global.xml");
+    expect(stackConfigurationResponse3.getPropertyName()).andReturn("oozie_user");
+    expect(stackConfigurationResponse3.getPropertyValue()).andReturn("oozie");
+
+    expect(stackConfigurationResponse4.getType()).andReturn("core-site.xml");
+    expect(stackConfigurationResponse4.getPropertyName()).andReturn("property3");
+    expect(stackConfigurationResponse4.getPropertyValue()).andReturn("value3");
+
+    expect(blueprintConfig.getBlueprintName()).andReturn("test-blueprint").anyTimes();
+    expect(blueprintConfig.getType()).andReturn("core-site").anyTimes();
+
+    expect(blueprint.getHostGroups()).andReturn(Collections.singleton(hostGroup)).anyTimes();
+    expect(hostGroup.getName()).andReturn("group1").anyTimes();
+    expect(hostGroup.getComponents()).andReturn(hostGroupComponents).anyTimes();
+    expect(hostGroupComponent1.getName()).andReturn("component1").anyTimes();
+    expect(hostGroupComponent2.getName()).andReturn("component2").anyTimes();
+    expect(hostGroupComponent3.getName()).andReturn("component3").anyTimes();
+    expect(hostGroup.getConfigurations()).andReturn(
+        Collections.<HostGroupConfigEntity>singleton(hostGroupConfig)).anyTimes();
+
+    expect(hostGroupConfig.getType()).andReturn("core-site").anyTimes();
+    expect(hostGroupConfig.getConfigData()).andReturn(new Gson().toJson(mapGroupConfigProperties)).anyTimes();
+
+    replay(blueprintDAO, managementController, request, response, blueprint, stackServiceResponse1, stackServiceResponse2,
+        stackServiceComponentResponse1, stackServiceComponentResponse2, stackServiceComponentResponse3,
+        stackConfigurationResponse1, stackConfigurationResponse2, stackConfigurationResponse3, stackConfigurationResponse4,
+        blueprintConfig, hostGroup, hostGroupComponent1, hostGroupComponent2, hostGroupComponent3, hostGroupConfig,
+        serviceResourceProvider, componentResourceProvider, hostResourceProvider, hostComponentResourceProvider,
+        configGroupResourceProvider, persistKeyValue, metaInfo);
+
+    // test
+    ClusterResourceProvider.init(blueprintDAO, metaInfo);
+    ResourceProvider provider = new TestClusterResourceProvider(
+        managementController, serviceResourceProvider, componentResourceProvider,
+        hostResourceProvider, hostComponentResourceProvider, configGroupResourceProvider);
+
+    try {
+      provider.createResources(request);
+      fail("Expected exception for missing password property");
+    } catch (IllegalArgumentException e) {
+      //expected
+    }
+  }
+
+  @Test
   public void testCreateResource_blueprint__defaultPassword() throws Exception {
     String blueprintName = "test-blueprint";
     String stackName = "test";