You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2014/07/09 23:46:46 UTC
[33/50] git commit: Fix recursive call (catalog type == java type)
Fix recursive call (catalog type == java type)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/d8c42328
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d8c42328
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d8c42328
Branch: refs/heads/master
Commit: d8c42328ee6e6008c5647153f78846aef745de3a
Parents: c006d20
Author: Aled Sage <al...@gmail.com>
Authored: Tue Jul 8 10:42:31 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Jul 9 22:34:46 2014 +0100
----------------------------------------------------------------------
.../BrooklynAssemblyTemplateInstantiator.java | 29 ++++-
.../BrooklynComponentTemplateResolver.java | 8 +-
.../resources/CatalogBundleResourceTest.java | 128 +++++++++++--------
3 files changed, 106 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d8c42328/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 844fd41..590f35d 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
@@ -58,6 +58,7 @@ import brooklyn.util.flags.TypeCoercions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
@@ -213,20 +214,36 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
}
private List<EntitySpec<?>> buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform) {
+ return buildTemplateServicesAsSpecsImpl(loader, template, platform, Sets.<String>newLinkedHashSet());
+ }
+
+ private List<EntitySpec<?>> buildTemplateServicesAsSpecsImpl(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform, Set<String> encounteredCatalogTypes) {
List<EntitySpec<?>> result = Lists.newArrayList();
for (ResolvableLink<PlatformComponentTemplate> ctl: template.getPlatformComponentTemplates().links()) {
PlatformComponentTemplate appChildComponentTemplate = ctl.resolve();
BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, appChildComponentTemplate);
ManagementContext mgmt = loader.getManagementContext();
-
+
+ String catalogIdOrJavaType = entityResolver.getCatalogIdOrJavaType();
+
EntitySpec<?> spec;
CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getCatalogItem();
+
+ // FIXME
+ log.warn("buildTemplateServicesAsSpecsImpl: catalogIdOrJavaType="+catalogIdOrJavaType+"; item="+item+"; loader="+loader+"; template="+template+"; encounteredCatalogTypes="+encounteredCatalogTypes);
+
+
if (item == null || item.getJavaType() != null) {
spec = entityResolver.resolveSpec();
} else {
- spec = resolveCatalogYamlReferenceSpec(platform, mgmt, item);
+ boolean firstOccurrence = encounteredCatalogTypes.add(catalogIdOrJavaType);
+ if (firstOccurrence) {
+ spec = resolveCatalogYamlReferenceSpec(platform, mgmt, item, encounteredCatalogTypes);
+ } else {
+ throw new IllegalStateException("Recursive reference to " + catalogIdOrJavaType);
+ }
}
BrooklynClassLoadingContext newLoader = entityResolver.loader;
@@ -239,7 +256,9 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
private EntitySpec<?> resolveCatalogYamlReferenceSpec(CampPlatform platform,
ManagementContext mgmt,
- CatalogItem<Entity, EntitySpec<?>> item) {
+ CatalogItem<Entity, EntitySpec<?>> item,
+ Set<String> encounteredCatalogTypes) {
+
String yaml = item.getPlanYaml();
Reader input = new StringReader(yaml);
@@ -257,9 +276,9 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
try {
AssemblyTemplateInstantiator ati = at.getInstantiator().newInstance();
if (ati instanceof BrooklynAssemblyTemplateInstantiator) {
- List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecs(itemLoader, at, platform);
+ List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecsImpl(itemLoader, at, platform, encounteredCatalogTypes);
if (specs.size() > 1) {
- throw new UnsupportedOperationException("Only supporting single service in catalog item currently");
+ throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+specs);
}
return specs.get(0);
} else {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d8c42328/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 61984af..770b97f 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -191,8 +191,14 @@ public class BrooklynComponentTemplateResolver {
/** returns the entity class, if needed in contexts which scan its statics for example */
public Class<? extends Entity> loadEntityClass() {
+ return tryLoadEntityClass().get();
+ }
+
+ /** tries to load the Java entity class */
+ public Maybe<Class<? extends Entity>> tryLoadEntityClass() {
CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem();
String typeName = getCatalogIdOrJavaType();
+
if (item!=null) {
// add additional bundles
loader = new BrooklynClassLoadingContextSequential(mgmt, item.newClassLoadingContext(mgmt), loader);
@@ -214,7 +220,7 @@ public class BrooklynComponentTemplateResolver {
}
}
- return loader.loadClass(typeName, Entity.class);
+ return loader.tryLoadClass(typeName, Entity.class);
}
/** resolves the spec, updating the loader if a catalog item is loaded */
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d8c42328/usage/rest-server/src/test/java/brooklyn/rest/resources/CatalogBundleResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/CatalogBundleResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/CatalogBundleResourceTest.java
index 2fc3102..9780d30 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/CatalogBundleResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/CatalogBundleResourceTest.java
@@ -1,8 +1,10 @@
package brooklyn.rest.resources;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
+import java.io.InputStream;
import java.net.URI;
import javax.ws.rs.core.Response;
@@ -15,6 +17,7 @@ import brooklyn.management.osgi.OsgiStandaloneTest;
import brooklyn.rest.domain.ApplicationSummary;
import brooklyn.rest.domain.CatalogEntitySummary;
import brooklyn.rest.testing.BrooklynRestResourceTest;
+import brooklyn.util.stream.Streams;
import com.google.common.collect.Iterables;
import com.sun.jersey.api.client.ClientResponse;
@@ -37,29 +40,19 @@ public class CatalogBundleResourceTest extends BrooklynRestResourceTest {
@Test
public void testLaunchApplicationYaml() throws Exception {
String registeredTypeName = "my.catalog.app.id.launch";
- registerAndLaunch(registeredTypeName, SIMPLE_ENTITY_TYPE);
+ registerAndLaunchAndAssertSimpleEntity(registeredTypeName, SIMPLE_ENTITY_TYPE);
}
@Test
- public void testLaunchApplicationLoopYaml() throws Exception {
- String registeredTypeName = "my.catalog.app.id.launch";
- registerAndLaunch(registeredTypeName, registeredTypeName);
- }
+ public void testLaunchApplicationWithCatalogReferencingOtherCatalogYaml() throws Exception {
+ String referencedRegisteredTypeName = "my.catalog.app.id.referenced";
+ String referrerRegisteredTypeName = "my.catalog.app.id.referring";
+ addCatalogOSGiEntity(referencedRegisteredTypeName, SIMPLE_ENTITY_TYPE);
+ addCatalogOSGiEntity(referrerRegisteredTypeName, referencedRegisteredTypeName);
- private void registerAndLaunch(String registeredTypeName, String catalogServiceType) {
- addCatalogOSGiEntity(registeredTypeName, catalogServiceType);
+ String yaml = "{ name: simple-app-yaml, location: localhost, services: [ { serviceType: "+referrerRegisteredTypeName+" } ] }";
+ ApplicationSummary appSummary = createAndWaitForApp(yaml);
- String yaml = "{ name: simple-app-yaml, location: localhost, services: [ { serviceType: "+registeredTypeName+" } ] }";
-
- ClientResponse response = client().resource("/v1/applications")
- .entity(yaml, "application/x-yaml")
- .post(ClientResponse.class);
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
-
- // Expect app to be running
- URI appUri = response.getLocation();
- waitForApplicationToBeRunning(response.getLocation());
- ApplicationSummary appSummary = client().resource(appUri).get(ApplicationSummary.class);
String appId = appSummary.getId();
assertEquals(appSummary.getSpec().getName(), "simple-app-yaml");
@@ -69,23 +62,23 @@ public class CatalogBundleResourceTest extends BrooklynRestResourceTest {
}
@Test
- public void testLaunchApplicationWithCatalogReferencingOtherCatalogYaml() throws Exception {
- String referencedRegisteredTypeName = "my.catalog.app.id.referenced";
- String referrerRegisteredTypeName = "my.catalog.app.id.referring";
- addCatalogOSGiEntity(referencedRegisteredTypeName);
- addCatalogEntityReferencingCatalogEntry(referrerRegisteredTypeName, referencedRegisteredTypeName);
+ public void testLaunchApplicationLoopWithJavaTypeNameInYamlFails() throws Exception {
+ String registeredTypeName = SIMPLE_ENTITY_TYPE;
+ registerAndLaunchFailsWithRecursionError(registeredTypeName, registeredTypeName);
+ }
+
+ @Test
+ public void testLaunchApplicationLoopCatalogIdInYamlFails() throws Exception {
+ String registeredTypeName = "self.referencing.type";
+ registerAndLaunchFailsWithRecursionError(registeredTypeName, registeredTypeName);
+ }
+
+ private void registerAndLaunchAndAssertSimpleEntity(String registeredTypeName, String serviceType) {
+ addCatalogOSGiEntity(registeredTypeName, serviceType);
+
+ String yaml = "{ name: simple-app-yaml, location: localhost, services: [ { serviceType: "+registeredTypeName+" } ] }";
+ ApplicationSummary appSummary = createAndWaitForApp(yaml);
- String yaml = "{ name: simple-app-yaml, location: localhost, services: [ { serviceType: "+referrerRegisteredTypeName+" } ] }";
-
- ClientResponse response = client().resource("/v1/applications")
- .entity(yaml, "application/x-yaml")
- .post(ClientResponse.class);
- assertTrue(response.getStatus()/100 == 2, "response is "+response);
-
- // Expect app to be running
- URI appUri = response.getLocation();
- waitForApplicationToBeRunning(response.getLocation());
- ApplicationSummary appSummary = client().resource(appUri).get(ApplicationSummary.class);
String appId = appSummary.getId();
assertEquals(appSummary.getSpec().getName(), "simple-app-yaml");
@@ -94,12 +87,41 @@ public class CatalogBundleResourceTest extends BrooklynRestResourceTest {
assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
}
+ private void registerAndLaunchFailsWithRecursionError(String registeredTypeName, String serviceType) {
+ addCatalogOSGiEntity(registeredTypeName, serviceType);
+ try {
+ String yaml = "{ name: simple-app-yaml, location: localhost, services: [ { serviceType: "+registeredTypeName+" } ] }";
+ ClientResponse response = client().resource("/v1/applications")
+ .entity(yaml, "application/x-yaml")
+ .post(ClientResponse.class);
+
+ int responseStatus = response.getStatus();
+ String responseContent = getResponseContentAsString(response);
+
+ assertFalse(responseStatus/100 == 2, "response="+response+"; content="+responseContent);
+ assertTrue(responseContent.contains("Recursive reference to "+registeredTypeName), "content="+responseContent);
+ } finally {
+ deleteCatalogEntity(registeredTypeName);
+ }
+ }
+
+ private ApplicationSummary createAndWaitForApp(String yaml) {
+ ClientResponse response = client().resource("/v1/applications")
+ .entity(yaml, "application/x-yaml")
+ .post(ClientResponse.class);
+ assertTrue(response.getStatus()/100 == 2, "response is "+response);
+
+ URI appUri = response.getLocation();
+ waitForApplicationToBeRunning(response.getLocation());
+
+ return client().resource(appUri).get(ApplicationSummary.class);
+ }
private void addCatalogOSGiEntity(String registeredTypeName) {
addCatalogOSGiEntity(registeredTypeName, SIMPLE_ENTITY_TYPE);
}
- private void addCatalogOSGiEntity(String registeredTypeName, String catalogServiceType) {
+ private void addCatalogOSGiEntity(String registeredTypeName, String serviceType) {
String catalogYaml =
"name: "+registeredTypeName+"\n"+
// FIXME name above should be unnecessary when brooklyn.catalog below is working
@@ -113,24 +135,7 @@ public class CatalogBundleResourceTest extends BrooklynRestResourceTest {
" - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + "\n"+
"\n"+
"services:\n"+
- "- type: " + catalogServiceType;
-
- addCatalogEntity(catalogYaml);
- }
-
- private void addCatalogEntityReferencingCatalogEntry(String ownRegisteredTypeName, String otherRegisteredTypeName) {
- String catalogYaml =
- "name: "+ownRegisteredTypeName+"\n"+
- // FIXME name above should be unnecessary when brooklyn.catalog below is working
- "brooklyn.catalog:\n"+
- " id: " + ownRegisteredTypeName + "\n"+
- " name: My Referrer Catalog App\n"+
- " description: My referrer description\n"+
- " icon_url: classpath://path/to/myicon.jpg\n"+
- " version: 0.2.1\n"+
- "\n"+
- "services:\n"+
- "- type: "+otherRegisteredTypeName+"\n";
+ "- type: " + serviceType;
addCatalogEntity(catalogYaml);
}
@@ -141,4 +146,21 @@ public class CatalogBundleResourceTest extends BrooklynRestResourceTest {
assertEquals(catalogResponse.getStatus(), Response.Status.CREATED.getStatusCode());
}
+
+ private void deleteCatalogEntity(String catalogItem) {
+ ClientResponse catalogResponse = client().resource("/v1/catalog/entities/"+catalogItem)
+ .delete(ClientResponse.class);
+
+ assertEquals(catalogResponse.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+ }
+
+ private String getResponseContentAsString(ClientResponse response) {
+ InputStream in = null;
+ try {
+ in = response.getEntityInputStream();
+ return new String(Streams.readFully(in));
+ } finally {
+ Streams.closeQuietly(in);
+ }
+ }
}