You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/02/06 13:48:15 UTC
[03/11] incubator-brooklyn git commit: Don't recurse into same
symbolicName catalog items when resolving CAMP dependencies.
Don't recurse into same symbolicName catalog items when resolving CAMP dependencies.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fecec16d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fecec16d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fecec16d
Branch: refs/heads/master
Commit: fecec16df9dafad6479ee0c47f41779477ae0afc
Parents: beeb4d8
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Dec 10 15:50:39 2014 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Jan 29 16:41:25 2015 +0200
----------------------------------------------------------------------
.../api/AssemblyTemplateSpecInstantiator.java | 5 ++
.../catalog/internal/BasicBrooklynCatalog.java | 13 ++---
.../camp/lite/TestAppAssemblyInstantiator.java | 6 +++
.../BrooklynAssemblyTemplateInstantiator.java | 23 ++++++---
.../brooklyn/catalog/CatalogYamlEntityTest.java | 52 ++++++++++++++++++++
5 files changed, 87 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fecec16d/core/src/main/java/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java b/core/src/main/java/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
index 25f3cbd..60b7921 100644
--- a/core/src/main/java/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
+++ b/core/src/main/java/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
@@ -21,11 +21,16 @@ package brooklyn.camp.brooklyn.api;
import io.brooklyn.camp.CampPlatform;
import io.brooklyn.camp.spi.AssemblyTemplate;
import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+
+import java.util.Set;
+
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.management.classloading.BrooklynClassLoadingContext;
public interface AssemblyTemplateSpecInstantiator extends AssemblyTemplateInstantiator {
EntitySpec<?> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfAppropriate);
+ EntitySpec<?> createNestedSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext itemLoader, Set<String> encounteredCatalogTypes);
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fecec16d/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index 2153ada..6b61b44 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -51,6 +51,7 @@ import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.policy.Policy;
import brooklyn.policy.PolicySpec;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.guava.Maybe;
import brooklyn.util.javalang.AggregateClassLoader;
@@ -305,7 +306,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
switch (item.getCatalogItemType()) {
case TEMPLATE:
case ENTITY:
- spec = createEntitySpec(plan, loader);
+ spec = createEntitySpec(loadedItem.getSymbolicName(), plan, loader);
break;
case POLICY:
spec = createPolicySpec(plan, loader);
@@ -335,7 +336,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
}
@SuppressWarnings("unchecked")
- private <T, SpecT> SpecT createEntitySpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+ private <T, SpecT> SpecT createEntitySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
// TODO should not register new AT each time we instantiate from the same plan; use some kind of cache
@@ -350,7 +351,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
try {
AssemblyTemplateInstantiator instantiator = at.getInstantiator().newInstance();
if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
- return (SpecT) ((AssemblyTemplateSpecInstantiator)instantiator).createSpec(at, camp, loader, true);
+ return (SpecT) ((AssemblyTemplateSpecInstantiator)instantiator).createNestedSpec(at, camp, loader, MutableSet.of(symbolicName));
}
throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at);
} catch (Exception e) {
@@ -529,7 +530,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
String versionedId = CatalogUtils.getVersionedId(catalogSymbolicName, catalogVersion);
BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, versionedId, libraries);
- AbstractBrooklynObjectSpec<?, ?> spec = createSpec(plan, loader);
+ AbstractBrooklynObjectSpec<?, ?> spec = createSpec(catalogSymbolicName, plan, loader);
CatalogItemDtoAbstract<?, ?> dto = createItemBuilder(spec, catalogSymbolicName, catalogVersion)
.libraries(libraries)
@@ -543,11 +544,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
return dto;
}
- private AbstractBrooklynObjectSpec<?,?> createSpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+ private AbstractBrooklynObjectSpec<?,?> createSpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
if (isPolicyPlan(plan)) {
return createPolicySpec(plan, loader);
} else {
- return createEntitySpec(plan, loader);
+ return createEntitySpec(symbolicName, plan, loader);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fecec16d/core/src/test/java/brooklyn/camp/lite/TestAppAssemblyInstantiator.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/camp/lite/TestAppAssemblyInstantiator.java b/core/src/test/java/brooklyn/camp/lite/TestAppAssemblyInstantiator.java
index e63bd1f..23d85f2 100644
--- a/core/src/test/java/brooklyn/camp/lite/TestAppAssemblyInstantiator.java
+++ b/core/src/test/java/brooklyn/camp/lite/TestAppAssemblyInstantiator.java
@@ -27,6 +27,7 @@ import io.brooklyn.camp.spi.collection.ResolvableLink;
import io.brooklyn.camp.spi.instantiate.BasicAssemblyTemplateInstantiator;
import java.util.Map;
+import java.util.Set;
import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
@@ -82,4 +83,9 @@ public class TestAppAssemblyInstantiator extends BasicAssemblyTemplateInstantiat
app.configure(ConfigBag.newInstance().putAll((Map)bc).getAllConfigAsConfigKeyMap());
}
+ @Override
+ public EntitySpec<?> createNestedSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext itemLoader, Set<String> encounteredCatalogTypes) {
+ return createSpec(template, platform, itemLoader, true);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fecec16d/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index d03502e..17949d8 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -171,7 +171,10 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
String brooklynType = entityResolver.getBrooklynType();
CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getCatalogItem();
- boolean firstOccurrence = encounteredCatalogTypes.add(brooklynType);
+ //Take the symoblicName part of the catalog item only for recursion detection to prevent
+ //cross referencing of different versions. Not interested in non-catalog item types.
+ //Prevent catalog items self-referencing even if explicitly different version.
+ boolean firstOccurrence = (item == null || encounteredCatalogTypes.add(item.getSymbolicName()));
boolean recursiveButTryJava = !firstOccurrence;
if (log.isTraceEnabled()) log.trace("Building CAMP template services: type="+brooklynType+"; item="+item+"; loader="+entityResolver.loader+"; encounteredCatalogTypes="+encounteredCatalogTypes);
@@ -223,7 +226,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
return null;
}
try {
- return resolveYamlSpec(mgmt, encounteredCatalogTypes, yaml, itemLoader);
+ return createNestedSpec(mgmt, encounteredCatalogTypes, yaml, itemLoader);
} finally {
try {
yaml.close();
@@ -242,10 +245,10 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
Reader input = new StringReader(yaml);
BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, item);
- return resolveYamlSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
+ return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
}
- private EntitySpec<?> resolveYamlSpec(ManagementContext mgmt,
+ private EntitySpec<?> createNestedSpec(ManagementContext mgmt,
Set<String> encounteredCatalogTypes, Reader input,
BrooklynClassLoadingContext itemLoader) {
CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get();
@@ -257,13 +260,21 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
} finally {
BrooklynLoaderTracker.unsetLoader(itemLoader);
}
+ return createNestedSpec(at, platform, itemLoader, encounteredCatalogTypes);
+ }
+ @Override
+ public EntitySpec<?> createNestedSpec(
+ AssemblyTemplate template,
+ CampPlatform platform,
+ BrooklynClassLoadingContext itemLoader,
+ Set<String> encounteredCatalogTypes) {
// In case we want to allow multiple top-level entities in a catalog we need to think
// about what it would mean to subsequently call buildChildrenEntitySpecs on the list of top-level entities!
try {
- AssemblyTemplateInstantiator ati = at.getInstantiator().newInstance();
+ AssemblyTemplateInstantiator ati = template.getInstantiator().newInstance();
if (ati instanceof BrooklynAssemblyTemplateInstantiator) {
- List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecsImpl(itemLoader, at, platform, encounteredCatalogTypes);
+ List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecsImpl(itemLoader, template, platform, encounteredCatalogTypes);
if (specs.size() > 1) {
throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+specs);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fecec16d/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
index 94c3316..5724351 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
@@ -34,6 +34,7 @@ import org.testng.annotations.Test;
import brooklyn.catalog.BrooklynCatalog;
import brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.BasicEntity;
import brooklyn.management.osgi.OsgiStandaloneTest;
@@ -368,6 +369,57 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
assertTrue(icon != null);
icon.close();
}
+
+ @Test
+ public void testMissingTypeDoesNotRecurse() {
+ String symbolicName = "my.catalog.app.id.basic";
+ addCatalogItem(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " version: " + TEST_VERSION,
+ "",
+ "services:",
+ "- type: brooklyn.entity.basic.BasicEntity");
+
+ try {
+ addCatalogItem(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " version: " + TEST_VERSION + "-update",
+ "",
+ "services:",
+ "- type: " + symbolicName);
+ fail("Catalog addition expected to fail due to non-existent java type " + symbolicName);
+ } catch (IllegalStateException e) {
+ assertEquals(e.getMessage(), "Recursive reference to " + symbolicName + " (and cannot be resolved as a Java type)");
+ }
+ }
+
+ @Test
+ public void testVersionedTypeDoesNotRecurse() {
+ String symbolicName = "my.catalog.app.id.basic";
+ addCatalogItem(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " version: " + TEST_VERSION,
+ "",
+ "services:",
+ "- type: brooklyn.entity.basic.BasicEntity");
+
+ String versionedId = CatalogUtils.getVersionedId(symbolicName, TEST_VERSION);
+ try {
+ addCatalogItem(
+ "brooklyn.catalog:",
+ " id: " + symbolicName,
+ " version: " + TEST_VERSION + "-update",
+ "",
+ "services:",
+ "- type: " + versionedId);
+ fail("Catalog addition expected to fail due to non-existent java type " + versionedId);
+ } catch (IllegalStateException e) {
+ assertEquals(e.getMessage(), "Recursive reference to " + versionedId + " (and cannot be resolved as a Java type)");
+ }
+ }
private void registerAndLaunchAndAssertSimpleEntity(String symbolicName, String serviceType) throws Exception {
addCatalogOSGiEntity(symbolicName, serviceType);