Skip to content
Permalink
Browse files
YAML: don’t wrap sub-entities in BasicApplication
Previously, any catalog item of type “template” would always be wrapped
in a BasicApplication. This was being done in three places. The first
is ok; the second two are bad:

1. When deploying a top-level “template” from the catalog.
2. When referring to a “template” catalog item in a member-spec (e.g.
   for a DynamicCluster)
3. When referring to a “template” catalog item in brooklyn.children.
  • Loading branch information
aledsage committed Jan 12, 2016
1 parent d058158 commit e3a16614055f83f68164d6cfe222668710a4f953
Showing 3 changed files with 158 additions and 1 deletion.
@@ -40,6 +40,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
@@ -89,6 +90,16 @@ public EntitySpec<? extends Application> createApplicationSpec(
// first build the children into an empty shell app
List<EntitySpec<?>> childSpecs = createServiceSpecs(template, platform, loader, encounteredTypeSymbolicNames);
for (EntitySpec<?> childSpec : childSpecs) {

if (Application.class.isAssignableFrom(childSpec.getType())) {
EntitySpec<? extends Application> appSpec = (EntitySpec<? extends Application>) childSpec;
if (EntityManagementUtils.canPromoteChildrenInWrappedApplication(appSpec)) {
EntitySpec<?> appChildSpec = Iterables.getOnlyElement(appSpec.getChildren());
EntityManagementUtils.mergeWrapperParentSpecToChildEntity(appSpec, appChildSpec);
childSpec = appChildSpec;
}
}

app.child(childSpec);
}

@@ -29,6 +29,7 @@

import javax.annotation.Nullable;

import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
@@ -49,6 +50,7 @@
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.mgmt.BrooklynTags;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
@@ -207,6 +209,16 @@ private <T extends Entity> void populateSpec(EntitySpec<T> spec, Set<String> enc
// encounteredRegisteredTypeIds must contain the items currently being loaded (the dependency chain),
// but not parent items in this type already resolved.
EntitySpec<? extends Entity> childSpec = entityResolver.resolveSpec(encounteredRegisteredTypeIds);

if (Application.class.isAssignableFrom(childSpec.getType())) {
EntitySpec<? extends Application> appSpec = (EntitySpec<? extends Application>) childSpec;
if (EntityManagementUtils.canPromoteChildrenInWrappedApplication(appSpec)) {
EntitySpec<?> appChildSpec = Iterables.getOnlyElement(appSpec.getChildren());
EntityManagementUtils.mergeWrapperParentSpecToChildEntity(appSpec, appChildSpec);
childSpec = appChildSpec;
}
}

spec.child(childSpec);
}
}
@@ -365,7 +377,18 @@ protected Object transformSpecialFlags(Object flag) {
@SuppressWarnings("unchecked")
Map<String, Object> resolvedConfig = (Map<String, Object>)transformSpecialFlags(specConfig.getSpecConfiguration());
specConfig.setSpecConfiguration(resolvedConfig);
return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(encounteredRegisteredTypeIds);
EntitySpec<?> entitySpec = Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(encounteredRegisteredTypeIds);

if (Application.class.isAssignableFrom(entitySpec.getType())) {
EntitySpec<? extends Application> appSpec = (EntitySpec<? extends Application>) entitySpec;
if (EntityManagementUtils.canPromoteChildrenInWrappedApplication(appSpec)) {
EntitySpec<?> childSpec = Iterables.getOnlyElement(appSpec.getChildren());
EntityManagementUtils.mergeWrapperParentSpecToChildEntity(appSpec, childSpec);
entitySpec = childSpec;
}
}
return entitySpec;

}
if (flag instanceof ManagementContextInjectable) {
log.debug("Injecting Brooklyn management context info object: {}", flag);
@@ -18,18 +18,28 @@
*/
package org.apache.brooklyn.camp.brooklyn.catalog;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.osgi.OsgiTestResources;
import org.testng.Assert;
import org.testng.TestListenerAdapter;
import org.testng.TestNG;
import org.testng.annotations.Test;

import com.google.common.collect.Iterables;


public class CatalogYamlTemplateTest extends AbstractYamlTest {

@@ -63,6 +73,119 @@ public void testAddCatalogItemAndCheckSource() throws Exception {
deleteCatalogEntity("t1");
}

@Test
public void testServiceTypeEntityOfTypeCatalogTemplateNotWrapped() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: t1",
" item_type: template",
" name: myT1",
" item:",
" services:",
" - type: " + TestEntity.class.getName());
addCatalogItems(
"brooklyn.catalog:",
" id: t2",
" item_type: template",
" name: myT2",
" item:",
" services:",
" - type: t1",
" - type: t1");

Entity app = createAndStartApplication(
"services:",
"- type: t2");
waitForApplicationTasks(app);

Entities.dumpInfo(app);
Entity t1a = Iterables.get(app.getChildren(), 0);
Entity t1b = Iterables.get(app.getChildren(), 1);
assertEquals(app.getChildren().size(), 2);
assertEquals(t1a.getChildren().size(), 0);
assertEquals(t1b.getChildren().size(), 0);

assertTrue(app instanceof BasicApplication);
assertTrue(t1a instanceof TestEntity);
assertTrue(t1b instanceof TestEntity);
}

@Test
public void testChildEntityOfTypeCatalogTemplateNotWrapped() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: t1",
" item_type: template",
" name: myT1",
" item:",
" services:",
" - type: " + TestEntity.class.getName());
addCatalogItems(
"brooklyn.catalog:",
" id: t2",
" item_type: template",
" name: myT2",
" item:",
" services:",
" - type: " + TestEntity.class.getName(),
" brooklyn.children:",
" - type: t1");

Entity app = createAndStartApplication(
"services:",
"- type: t2");
waitForApplicationTasks(app);

Entities.dumpInfo(app);
Entity t2 = Iterables.getOnlyElement(app.getChildren());
Entity t1 = Iterables.getOnlyElement(t2.getChildren());
assertEquals(t1.getChildren().size(), 0);

assertTrue(app instanceof BasicApplication);
assertTrue(t1 instanceof TestEntity);
assertTrue(t2 instanceof TestEntity);
}

@Test
public void testMemberSpecEntityOfTypeCatalogTemplateNotWrapped() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
" id: t1",
" item_type: template",
" name: myT1",
" item:",
" services:",
" - type: " + TestEntity.class.getName());
addCatalogItems(
"brooklyn.catalog:",
" id: t2",
" item_type: template",
" name: myT2",
" item:",
" services:",
" - type: " + DynamicCluster.class.getName(),
" brooklyn.config:",
" memberSpec:",
" $brooklyn:entitySpec:",
" type: t1",
" cluster.initial.size: 1");

Entity app = createAndStartApplication(
"location: localhost",
"services:",
"- type: t2");
waitForApplicationTasks(app);

Entities.dumpInfo(app);
DynamicCluster t2 = (DynamicCluster) Iterables.getOnlyElement(app.getChildren());
Entity t1 = Iterables.getOnlyElement(t2.getMembers());
assertEquals(t1.getChildren().size(), 0);

assertTrue(app instanceof BasicApplication);
assertTrue(t2 instanceof DynamicCluster);
assertTrue(t1 instanceof TestEntity);
}

private RegisteredType makeItem() {
TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);

0 comments on commit e3a1661

Please sign in to comment.