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/01 21:32:09 UTC
git commit: AMBARI-5648. Provide basic validation of fields for
blueprint create api.
Repository: ambari
Updated Branches:
refs/heads/trunk b0d850eb9 -> 327f9c3a8
AMBARI-5648. Provide basic validation of fields for blueprint create api.
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/327f9c3a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/327f9c3a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/327f9c3a
Branch: refs/heads/trunk
Commit: 327f9c3a87e9faad3a6acddbea5863851c3cd799
Parents: b0d850e
Author: John Speidel <js...@hortonworks.com>
Authored: Wed Apr 30 22:01:44 2014 -0400
Committer: John Speidel <js...@hortonworks.com>
Committed: Thu May 1 15:31:26 2014 -0400
----------------------------------------------------------------------
.../ambari/server/controller/AmbariServer.java | 3 +-
.../internal/BlueprintResourceProvider.java | 173 +++++++--
.../server/orm/entities/HostGroupEntity.java | 6 +-
.../internal/BlueprintResourceProviderTest.java | 380 ++++++++++++++++++-
4 files changed, 512 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/327f9c3a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index cdb7fea..5ee07e0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -511,7 +511,8 @@ public class AmbariServer {
StackDefinedPropertyProvider.init(injector);
NagiosPropertyProvider.init(injector);
AbstractControllerResourceProvider.init(injector.getInstance(ResourceProviderFactory.class));
- BlueprintResourceProvider.init(injector.getInstance(BlueprintDAO.class), injector.getInstance(Gson.class));
+ BlueprintResourceProvider.init(injector.getInstance(BlueprintDAO.class),
+ injector.getInstance(Gson.class), ambariMetaInfo);
StackDependencyResourceProvider.init(ambariMetaInfo);
ClusterResourceProvider.injectBlueprintDAO(injector.getInstance(BlueprintDAO.class));
ViewRegistry.init(injector.getInstance(ViewDAO.class), injector.getInstance(ViewInstanceDAO.class));
http://git-wip-us.apache.org/repos/asf/ambari/blob/327f9c3a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
index ea2fdec..353b58f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
@@ -22,6 +22,7 @@ import com.google.gson.Gson;
import com.google.inject.Inject;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.DuplicateResourceException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -39,6 +40,8 @@ import org.apache.ambari.server.orm.entities.BlueprintEntity;
import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
import org.apache.ambari.server.orm.entities.HostGroupEntity;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ServiceInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -92,6 +95,11 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
*/
private static Gson jsonSerializer;
+ /**
+ * Stack information.
+ */
+ private static AmbariMetaInfo stackInfo;
+
// ----- Constructors ----------------------------------------------------
@@ -110,11 +118,13 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
*
* @param blueprintDAO blueprint data access object
* @param gson gson json serializer
+ * @param metaInfo stack related information
*/
@Inject
- public static void init(BlueprintDAO blueprintDAO, Gson gson) {
+ public static void init(BlueprintDAO blueprintDAO, Gson gson, AmbariMetaInfo metaInfo) {
dao = blueprintDAO;
jsonSerializer = gson;
+ stackInfo = metaInfo;
}
@@ -186,8 +196,7 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
throws SystemException, UnsupportedPropertyException,
NoSuchResourceException, NoSuchParentResourceException {
- // no-op, blueprints are immutable
- //todo: meaningful error message
+ // no-op, blueprints are immutable. Service doesn't support PUT so should never get here.
return null;
}
@@ -319,7 +328,7 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
* @return new blueprint entity
*/
@SuppressWarnings("unchecked")
- protected BlueprintEntity toEntity(Map<String, Object> properties) {
+ protected BlueprintEntity toBlueprintEntity(Map<String, Object> properties) {
String name = (String) properties.get(BLUEPRINT_NAME_PROPERTY_ID);
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Blueprint name must be provided");
@@ -330,42 +339,146 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
blueprint.setStackName((String) properties.get(STACK_NAME_PROPERTY_ID));
blueprint.setStackVersion((String) properties.get(STACK_VERSION_PROPERTY_ID));
- Collection<HostGroupEntity> blueprintHostGroups = new ArrayList<HostGroupEntity>();
- blueprint.setHostGroups(blueprintHostGroups);
+ createHostGroupEntities(blueprint,
+ (HashSet<HashMap<String, Object>>) properties.get(HOST_GROUP_PROPERTY_ID));
- HashSet<HashMap<String, Object>> setHostGroups =
- (HashSet<HashMap<String, Object>>) properties.get(HOST_GROUP_PROPERTY_ID);
+ createBlueprintConfigEntities((Collection<Map<String,
+ String>>) properties.get(CONFIGURATION_PROPERTY_ID), blueprint);
+
+ return blueprint;
+ }
+
+ /**
+ * Create host group entities and add to the parent blueprint entity.
+ *
+ * @param blueprint parent blueprint entity
+ * @param setHostGroups set of host group property maps
+ */
+ @SuppressWarnings("unchecked")
+ private void createHostGroupEntities(BlueprintEntity blueprint,
+ HashSet<HashMap<String, Object>> setHostGroups) {
+
+ if (setHostGroups == null || setHostGroups.isEmpty()) {
+ throw new IllegalArgumentException("At least one host group must be specified in a blueprint");
+ }
+
+ Collection<HostGroupEntity> entities = new ArrayList<HostGroupEntity>();
+ Collection<String> stackComponentNames = getAllStackComponents(
+ blueprint.getStackName(), blueprint.getStackVersion());
for (HashMap<String, Object> hostGroupProperties : setHostGroups) {
- HostGroupEntity group = new HostGroupEntity();
- group.setName((String) hostGroupProperties.get(HOST_GROUP_NAME_PROPERTY_ID));
- group.setBlueprintEntity(blueprint);
- group.setBlueprintName(name);
- group.setCardinality((String) hostGroupProperties.get(HOST_GROUP_CARDINALITY_PROPERTY_ID));
+ HostGroupEntity hostGroup = new HostGroupEntity();
+ entities.add(hostGroup);
+
+ String hostGroupName = (String) hostGroupProperties.get(HOST_GROUP_NAME_PROPERTY_ID);
+ if (hostGroupName == null || hostGroupName.isEmpty()) {
+ throw new IllegalArgumentException("Every host group must include a non-null 'name' property");
+ }
+
+ hostGroup.setName(hostGroupName);
+ hostGroup.setBlueprintEntity(blueprint);
+ hostGroup.setBlueprintName(blueprint.getBlueprintName());
+ hostGroup.setCardinality((String) hostGroupProperties.get(HOST_GROUP_CARDINALITY_PROPERTY_ID));
+
createHostGroupConfigEntities((Collection<Map<String,
- String>>) hostGroupProperties.get(CONFIGURATION_PROPERTY_ID), group);
+ String>>) hostGroupProperties.get(CONFIGURATION_PROPERTY_ID), hostGroup);
- Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
- group.setComponents(components);
+ createComponentEntities(hostGroup, (HashSet<HashMap<String, String>>)
+ hostGroupProperties.get(COMPONENT_PROPERTY_ID), stackComponentNames);
+ }
+ blueprint.setHostGroups(entities);
+ }
- HashSet<HashMap<String, String>> setComponents =
- (HashSet<HashMap<String, String>>) hostGroupProperties.get(COMPONENT_PROPERTY_ID);
- for (HashMap<String, String> componentProperties : setComponents) {
- HostGroupComponentEntity component = new HostGroupComponentEntity();
- component.setName(componentProperties.get(COMPONENT_NAME_PROPERTY_ID));
- component.setBlueprintName(name);
- component.setHostGroupEntity(group);
- component.setHostGroupName((String) hostGroupProperties.get(HOST_GROUP_NAME_PROPERTY_ID));
+ /**
+ * Create component entities and add to parent host group.
+ *
+ * @param group parent host group
+ * @param setComponents set of component property maps
+ * @param componentNames set of all component names for the associated stack
+ */
+ @SuppressWarnings("unchecked")
+ private void createComponentEntities(HostGroupEntity group, HashSet<HashMap<String, String>> setComponents,
+ Collection<String> componentNames) {
+
+ Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
+ String groupName = group.getName();
+ group.setComponents(components);
+
+ if (setComponents == null || setComponents.isEmpty()) {
+ throw new IllegalArgumentException("Host group '" + groupName + "' must contain at least one component");
+ }
- components.add(component);
+ for (HashMap<String, String> componentProperties : setComponents) {
+ HostGroupComponentEntity component = new HostGroupComponentEntity();
+ components.add(component);
+
+ String componentName = componentProperties.get(COMPONENT_NAME_PROPERTY_ID);
+ if (componentName == null || componentName.isEmpty()) {
+ throw new IllegalArgumentException("Host group '" + groupName +
+ "' contains a component with no 'name' property");
}
- blueprintHostGroups.add(group);
+
+ if (! componentNames.contains(componentName)) {
+ throw new IllegalArgumentException("The component '" + componentName + "' in host group '" +
+ groupName + "' is not valid for the specified stack");
+ }
+
+ component.setName(componentName);
+ component.setBlueprintName(group.getBlueprintName());
+ component.setHostGroupEntity(group);
+ component.setHostGroupName(group.getName());
}
+ group.setComponents(components);
+ }
- createBlueprintConfigEntities((Collection<Map<String,
- String>>) properties.get(CONFIGURATION_PROPERTY_ID), blueprint);
+ /**
+ * Obtain all component names for the specified stack.
+ *
+ * @param stackName stack name
+ * @param stackVersion stack version
+ *
+ * @return collection of component names for the specified stack
+ * @throws IllegalArgumentException if the specified stack doesn't exist
+ */
+ private Collection<String> getAllStackComponents(String stackName, String stackVersion) {
+ Collection<String> componentNames = new HashSet<String>();
+ componentNames.add("AMBARI_SERVER");
+ Collection<ComponentInfo> components;
+ try {
+ components = getComponents(stackName, stackVersion);
+ } catch (AmbariException e) {
+ throw new IllegalArgumentException("The specified stack doesn't exist. Name='" +
+ stackName + "', Version='" + stackVersion + "'");
+ }
+ if (components != null) {
+ for (ComponentInfo component : components) {
+ componentNames.add(component.getName());
+ }
+ }
+ return componentNames;
+ }
- return blueprint;
+ /**
+ * Get all the components for the specified stack.
+ *
+ * @param stackName stack name
+ * @param version stack version
+ *
+ * @return all components for the specified stack
+ * @throws AmbariException if the stack doesn't exist
+ */
+ private Collection<ComponentInfo> getComponents(String stackName, String version) throws AmbariException {
+ Collection<ComponentInfo> components = new HashSet<ComponentInfo>();
+ Map<String, ServiceInfo> services = stackInfo.getServices(stackName, version);
+
+ for (ServiceInfo service : services.values()) {
+ List<ComponentInfo> serviceComponents = stackInfo.getComponentsByService(
+ stackName, version, service.getName());
+ for (ComponentInfo component : serviceComponents) {
+ components.add(component);
+ }
+ }
+ return components;
}
/**
@@ -470,7 +583,7 @@ public class BlueprintResourceProvider extends AbstractResourceProvider {
return new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
- BlueprintEntity blueprint = toEntity(properties);
+ BlueprintEntity blueprint = toBlueprintEntity(properties);
if (LOG.isDebugEnabled()) {
LOG.debug("Creating Blueprint, name=" + blueprint.getBlueprintName());
http://git-wip-us.apache.org/repos/asf/ambari/blob/327f9c3a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostGroupEntity.java
index 863632a..f0422e3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/HostGroupEntity.java
@@ -47,7 +47,7 @@ public class HostGroupEntity {
@Column
@Basic
- private String cardinality;
+ private String cardinality = "NOT SPECIFIED";
@OneToMany(cascade = CascadeType.ALL, mappedBy = "hostGroup")
private Collection<HostGroupComponentEntity> components;
@@ -165,6 +165,8 @@ public class HostGroupEntity {
* @param cardinality cardinality value
*/
public void setCardinality(String cardinality) {
- this.cardinality = cardinality;
+ if (cardinality != null) {
+ this.cardinality = cardinality;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/327f9c3a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java
index 9e12c63..f046b00 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java
@@ -19,6 +19,9 @@
package org.apache.ambari.server.controller.internal;
import com.google.gson.Gson;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ParentObjectNotFoundException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.predicate.EqualsPredicate;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -36,6 +39,8 @@ import org.apache.ambari.server.orm.entities.BlueprintEntity;
import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
import org.apache.ambari.server.orm.entities.HostGroupEntity;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.ServiceInfo;
import org.easymock.Capture;
import static org.junit.Assert.assertFalse;
@@ -71,37 +76,58 @@ import static org.junit.Assert.fail;
/**
* BlueprintResourceProvider unit tests.
*/
+@SuppressWarnings("unchecked")
public class BlueprintResourceProviderTest {
private static String BLUEPRINT_NAME = "test-blueprint";
private final static BlueprintDAO dao = createStrictMock(BlueprintDAO.class);
private final static Gson gson = new Gson();
+ private final static AmbariMetaInfo metaInfo = createStrictMock(AmbariMetaInfo.class);
@BeforeClass
public static void initClass() {
- BlueprintResourceProvider.init(dao, gson);
+ BlueprintResourceProvider.init(dao, gson, metaInfo);
}
@Before
public void resetGlobalMocks() {
- reset(dao);
+ reset(dao, metaInfo);
}
@Test
- public void testCreateResources() throws ResourceAlreadyExistsException, SystemException,
- UnsupportedPropertyException, NoSuchParentResourceException {
+ public void testCreateResources() throws AmbariException, ResourceAlreadyExistsException, SystemException,
+ UnsupportedPropertyException, NoSuchParentResourceException {
- Set<Map<String, Object>> setProperties = getTestProperties();
Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+
+
Capture<BlueprintEntity> entityCapture = new Capture<BlueprintEntity>();
// set expectations
expect(request.getProperties()).andReturn(setProperties);
expect(dao.findByName(BLUEPRINT_NAME)).andReturn(null);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
dao.create(capture(entityCapture));
- replay(dao, request);
+ replay(dao, metaInfo, request);
// end expectations
ResourceProvider provider = createProvider();
@@ -119,24 +145,41 @@ public class BlueprintResourceProviderTest {
validateEntity(entityCapture.getValue(), false);
- verify(dao, request);
+ verify(dao, metaInfo, request);
}
@Test
- public void testCreateResources_withConfiguration() throws ResourceAlreadyExistsException, SystemException,
+ public void testCreateResources_withConfiguration() throws AmbariException, ResourceAlreadyExistsException, SystemException,
UnsupportedPropertyException, NoSuchParentResourceException {
Set<Map<String, Object>> setProperties = getTestProperties();
setConfigurationProperties(setProperties);
Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
Capture<BlueprintEntity> entityCapture = new Capture<BlueprintEntity>();
// set expectations
expect(request.getProperties()).andReturn(setProperties);
expect(dao.findByName(BLUEPRINT_NAME)).andReturn(null);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
dao.create(capture(entityCapture));
- replay(dao, request);
+ replay(dao, metaInfo, request);
// end expectations
ResourceProvider provider = createProvider();
@@ -154,7 +197,7 @@ public class BlueprintResourceProviderTest {
validateEntity(entityCapture.getValue(), true);
- verify(dao, request);
+ verify(dao, metaInfo, request);
}
@Test
@@ -163,8 +206,7 @@ public class BlueprintResourceProviderTest {
Request request = createNiceMock(Request.class);
ResourceProvider provider = createProvider();
- BlueprintEntity entity = ((BlueprintResourceProvider) provider).toEntity(
- getTestProperties().iterator().next());
+ BlueprintEntity entity = createEntity(getTestProperties().iterator().next());
List<BlueprintEntity> results = new ArrayList<BlueprintEntity>();
results.add(entity);
@@ -188,8 +230,7 @@ public class BlueprintResourceProviderTest {
ResourceProvider provider = createProvider();
Set<Map<String, Object>> testProperties = getTestProperties();
setConfigurationProperties(testProperties);
- BlueprintEntity entity = ((BlueprintResourceProvider) provider).toEntity(
- testProperties.iterator().next());
+ BlueprintEntity entity = createEntity(testProperties.iterator().next());
List<BlueprintEntity> results = new ArrayList<BlueprintEntity>();
results.add(entity);
@@ -213,8 +254,7 @@ public class BlueprintResourceProviderTest {
Capture<BlueprintEntity> entityCapture = new Capture<BlueprintEntity>();
ResourceProvider provider = createProvider();
- BlueprintEntity blueprintEntity = ((BlueprintResourceProvider) provider).toEntity(
- getTestProperties().iterator().next());
+ BlueprintEntity blueprintEntity = createEntity(getTestProperties().iterator().next());
// set expectations
expect(dao.findByName(BLUEPRINT_NAME)).andReturn(blueprintEntity);
@@ -240,6 +280,256 @@ public class BlueprintResourceProviderTest {
validateEntity(entityCapture.getValue(), false);
}
+ @Test
+ public void testCreateResource_validate__NoHostGroups() throws AmbariException, ResourceAlreadyExistsException, SystemException,
+ UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+ setProperties.iterator().next().remove(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID);
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ try {
+ provider.createResources(request);
+ fail("Exception expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ verify(dao, metaInfo, request);
+ }
+
+ @Test
+ public void testCreateResource_Validate__NoHostGroupName() throws AmbariException, ResourceAlreadyExistsException,
+ SystemException, UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+ ((HashSet<Map<String, String>>) setProperties.iterator().next().get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).
+ iterator().next().put("name", "");
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ try {
+ provider.createResources(request);
+ fail("Exception expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ verify(dao, metaInfo, request);
+ }
+
+ @Test
+ public void testCreateResource_Validate__NoHostGroupComponents() throws AmbariException, ResourceAlreadyExistsException,
+ SystemException, UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+ ((HashSet<Map<String, String>>) setProperties.iterator().next().get(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).
+ iterator().next().remove("components");
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ try {
+ provider.createResources(request);
+ fail("Exception expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ verify(dao, metaInfo, request);
+ }
+
+ @Test
+ public void testCreateResource_Validate__NoHostGroupComponentName() throws AmbariException, ResourceAlreadyExistsException,
+ SystemException, UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+ ((HashSet<Map<String, String>>) ((HashSet<Map<String, Object>>) setProperties.iterator().next().get(
+ BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).iterator().next().get("components")).
+ iterator().next().put("name", "");
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ try {
+ provider.createResources(request);
+ fail("Exception expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ verify(dao, metaInfo, request);
+ }
+
+ @Test
+ public void testCreateResource_Validate__InvalidComponent() throws AmbariException, ResourceAlreadyExistsException,
+ SystemException, UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ // change component1->foo which results in a validation failure for bad component name
+ component1.setName("foo");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ try {
+ provider.createResources(request);
+ fail("Exception expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ verify(dao, metaInfo, request);
+ }
+
+ @Test
+ public void testCreateResource_Validate__AmbariServerComponent() throws AmbariException, ResourceAlreadyExistsException,
+ SystemException, UnsupportedPropertyException, NoSuchParentResourceException
+ {
+ Request request = createMock(Request.class);
+
+ Map<String, ServiceInfo> services = new HashMap<String, ServiceInfo>();
+ ServiceInfo service = new ServiceInfo();
+ service.setName("test-service");
+ services.put("test-service", service);
+
+ List<ComponentInfo> serviceComponents = new ArrayList<ComponentInfo>();
+ ComponentInfo component1 = new ComponentInfo();
+ component1.setName("component1");
+ ComponentInfo component2 = new ComponentInfo();
+ component2.setName("component2");
+ serviceComponents.add(component1);
+ serviceComponents.add(component2);
+
+ Set<Map<String, Object>> setProperties = getTestProperties();
+ ((HashSet<Map<String, String>>) ((HashSet<Map<String, Object>>) setProperties.iterator().next().get(
+ BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID)).iterator().next().get("components")).
+ iterator().next().put("name", "AMBARI_SERVER");
+
+
+ Capture<BlueprintEntity> entityCapture = new Capture<BlueprintEntity>();
+
+ // set expectations
+ expect(request.getProperties()).andReturn(setProperties);
+ expect(dao.findByName(BLUEPRINT_NAME)).andReturn(null);
+ expect(metaInfo.getServices("test-stack-name", "test-stack-version")).andReturn(services).anyTimes();
+ expect(metaInfo.getComponentsByService("test-stack-name", "test-stack-version", "test-service")).
+ andReturn(serviceComponents).anyTimes();
+ dao.create(capture(entityCapture));
+
+ replay(dao, metaInfo, request);
+ // end expectations
+
+ ResourceProvider provider = createProvider();
+ AbstractResourceProviderTest.TestObserver observer = new AbstractResourceProviderTest.TestObserver();
+ ((ObservableResourceProvider)provider).addObserver(observer);
+
+ provider.createResources(request);
+
+ ResourceProviderEvent lastEvent = observer.getLastEvent();
+ assertNotNull(lastEvent);
+ assertEquals(Resource.Type.Blueprint, lastEvent.getResourceType());
+ assertEquals(ResourceProviderEvent.Type.Create, lastEvent.getType());
+ assertEquals(request, lastEvent.getRequest());
+ assertNull(lastEvent.getPredicate());
+
+ verify(dao, metaInfo, request);
+ }
+
private Set<Map<String, Object>> getTestProperties() {
Map<String, String> mapHostGroupComponentProperties = new HashMap<String, String>();
mapHostGroupComponentProperties.put(BlueprintResourceProvider.COMPONENT_NAME_PROPERTY_ID, "component1");
@@ -272,7 +562,6 @@ public class BlueprintResourceProviderTest {
mapProperties.put(BlueprintResourceProvider.BLUEPRINT_NAME_PROPERTY_ID, BLUEPRINT_NAME);
mapProperties.put(BlueprintResourceProvider.STACK_NAME_PROPERTY_ID, "test-stack-name");
mapProperties.put(BlueprintResourceProvider.STACK_VERSION_PROPERTY_ID, "test-stack-version");
- mapProperties.put(BlueprintResourceProvider.STACK_VERSION_PROPERTY_ID, "test-stack-version");
mapProperties.put(BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID, setHostGroupProperties);
return Collections.singleton(mapProperties);
@@ -415,5 +704,62 @@ public class BlueprintResourceProviderTest {
PropertyHelper.getPropertyIds(Resource.Type.Blueprint),
PropertyHelper.getKeyPropertyIds(Resource.Type.Blueprint));
}
+
+ private BlueprintEntity createEntity(Map<String, Object> properties) {
+ BlueprintEntity entity = new BlueprintEntity();
+ entity.setBlueprintName((String) properties.get(BlueprintResourceProvider.BLUEPRINT_NAME_PROPERTY_ID));
+ entity.setStackName((String) properties.get(BlueprintResourceProvider.STACK_NAME_PROPERTY_ID));
+ entity.setStackVersion((String) properties.get(BlueprintResourceProvider.STACK_VERSION_PROPERTY_ID));
+
+ Set<Map<String, Object>> hostGroupProperties = (Set<Map<String, Object>>) properties.get(
+ BlueprintResourceProvider.HOST_GROUP_PROPERTY_ID);
+
+ Collection<HostGroupEntity> hostGroups = new ArrayList<HostGroupEntity>();
+ for (Map<String, Object> groupProperties : hostGroupProperties) {
+ HostGroupEntity hostGroup = new HostGroupEntity();
+ hostGroups.add(hostGroup);
+ hostGroup.setName((String) groupProperties.get(BlueprintResourceProvider.HOST_GROUP_NAME_PROPERTY_ID));
+ hostGroup.setCardinality((String) groupProperties.get(BlueprintResourceProvider.HOST_GROUP_CARDINALITY_PROPERTY_ID));
+ hostGroup.setConfigurations(new ArrayList<HostGroupConfigEntity>());
+
+ Set<Map<String, String>> setComponentProperties = (Set<Map<String, String>>) groupProperties.get(
+ BlueprintResourceProvider.COMPONENT_PROPERTY_ID);
+
+ Collection<HostGroupComponentEntity> components = new ArrayList<HostGroupComponentEntity>();
+ for (Map<String, String> compProperties : setComponentProperties) {
+ HostGroupComponentEntity component = new HostGroupComponentEntity();
+ components.add(component);
+ component.setName(compProperties.get(BlueprintResourceProvider.COMPONENT_NAME_PROPERTY_ID));
+ }
+ hostGroup.setComponents(components);
+
+ }
+ entity.setHostGroups(hostGroups);
+
+
+ Collection<Map<String, String>> configProperties = (Collection<Map<String, String>>) properties.get(
+ BlueprintResourceProvider.CONFIGURATION_PROPERTY_ID);
+ Map<String, String> configData = new HashMap<String, String>();
+ Collection<BlueprintConfigEntity> configs = new ArrayList<BlueprintConfigEntity>();
+ if (configProperties != null) {
+ for (Map<String, String> config : configProperties) {
+ BlueprintConfigEntity configEntity = new BlueprintConfigEntity();
+ for (Map.Entry<String, String> entry : config.entrySet()) {
+ String absolutePropName = entry.getKey();
+
+ int idx = absolutePropName.indexOf('/');
+ if (configEntity.getType() == null) {
+ configEntity.setType(absolutePropName.substring(0, idx));
+ }
+ configData.put(absolutePropName.substring(idx + 1), entry.getValue());
+ }
+ configEntity.setConfigData(gson.toJson(configData));
+ configs.add(configEntity);
+ }
+ }
+ entity.setConfigurations(configs);
+
+ return entity;
+ }
}