Repository: incubator-brooklyn Updated Branches: refs/heads/master ed289eceb -> 289eb5b85
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. Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e3a16614 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e3a16614 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e3a16614 Branch: refs/heads/master Commit: e3a16614055f83f68164d6cfe222668710a4f953 Parents: d058158 Author: Aled Sage <[email protected]> Authored: Tue Jan 12 16:55:01 2016 +0000 Committer: Aled Sage <[email protected]> Committed: Tue Jan 12 16:55:01 2016 +0000 ---------------------------------------------------------------------- .../BrooklynAssemblyTemplateInstantiator.java | 11 ++ .../BrooklynComponentTemplateResolver.java | 25 +++- .../catalog/CatalogYamlTemplateTest.java | 123 +++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3a16614/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java index 5840440..4d2ca82 100644 --- a/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java +++ b/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java @@ -40,6 +40,7 @@ import org.apache.brooklyn.util.core.flags.TypeCoercions; 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 class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe // 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); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3a16614/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java index 8f4db88..304a523 100644 --- a/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java +++ b/brooklyn-server/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean; 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.catalog.internal.CatalogUtils; 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 @@ public class BrooklynComponentTemplateResolver { // 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 @@ public class BrooklynComponentTemplateResolver { @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); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e3a16614/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java b/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java index c3dbc48..304ba8b 100644 --- a/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java +++ b/brooklyn-server/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java @@ -18,11 +18,19 @@ */ 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; @@ -30,6 +38,8 @@ 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 class CatalogYamlTemplateTest extends AbstractYamlTest { 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);
