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/04/21 22:41:33 UTC

[14/16] incubator-brooklyn git commit: entity spec looked up from catalog

entity spec looked up from catalog

refactors Brooklyn{AssemblyTemplateInstantiator,ComponentTemplateResolver} so that resolution is shared between the two.  this could be cleaned up further.
also applies some better debug/logging and html/underscore-template escaping.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f6c5619d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f6c5619d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f6c5619d

Branch: refs/heads/master
Commit: f6c5619d5bd3c7e92734fa08c16303da77453ddd
Parents: fb23d41
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Apr 21 09:56:40 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Apr 21 21:11:34 2015 +0100

----------------------------------------------------------------------
 .../catalog/internal/BasicBrooklynCatalog.java  | 22 +++----
 .../internal/EntityManagementUtils.java         |  5 ++
 .../policy/basic/AbstractEntityAdjunct.java     |  5 +-
 .../java/brooklyn/util/task/ValueResolver.java  |  7 ++-
 .../BrooklynAssemblyTemplateInstantiator.java   | 63 +++++++-------------
 .../BrooklynComponentTemplateResolver.java      | 58 ++++++++++++++----
 .../brooklyn/catalog/CatalogYamlEntityTest.java |  6 +-
 .../create-step-template-entry.html             |  8 +--
 8 files changed, 104 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/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 cd1f8c2..b49a240 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -621,16 +621,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         CatalogItemType itemType = TypeCoercions.coerce(getFirstAs(catalogMetadata, Object.class, "itemType", "item_type").orNull(), CatalogItemType.class);
         BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, "<load>:0", libraryBundles);
 
-        PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, loader, result).reconstruct();
-        if (!planInterpreter.isResolved()) {
-            throw Exceptions.create("Could not resolve item:\n"+sourceYaml, planInterpreter.getErrors());
-        }
-        itemType = planInterpreter.getCatalogItemType();
-        Map<?, ?> itemAsMap = planInterpreter.getItem();
-        // the "plan yaml" includes the services: ... or brooklyn.policies: ... outer key,
-        // as opposed to the rawer { type: xxx } map without that outer key which is valid as item input
-        // TODO this plan yaml is needed for subsequent reconstruction; would be nicer if it weren't! 
-        
         String id = getFirstAs(catalogMetadata, String.class, "id").orNull();
         String version = getFirstAs(catalogMetadata, String.class, "version").orNull();
         String symbolicName = getFirstAs(catalogMetadata, String.class, "symbolicName").orNull();
@@ -643,6 +633,18 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
             log.warn("Name property will be ignored due to the existence of displayName and at least one of id, symbolicName");
         }
 
+        PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, loader, result).reconstruct();
+        if (!planInterpreter.isResolved()) {
+            throw Exceptions.create("Could not resolve item "
+                + (Strings.isNonBlank(id) ? id : Strings.isNonBlank(symbolicName) ? symbolicName : Strings.isNonBlank(name) ? name : "<no-name>")
+                + ":\n"+sourceYaml, planInterpreter.getErrors());
+        }
+        itemType = planInterpreter.getCatalogItemType();
+        Map<?, ?> itemAsMap = planInterpreter.getItem();
+        // the "plan yaml" includes the services: ... or brooklyn.policies: ... outer key,
+        // as opposed to the rawer { type: xxx } map without that outer key which is valid as item input
+        // TODO this plan yaml is needed for subsequent reconstruction; would be nicer if it weren't! 
+
         // if symname not set, infer from: id, then name, then item id, then item name
         if (Strings.isBlank(symbolicName)) {
             if (Strings.isNonBlank(id)) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
index e6dc12a..046d56c 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
@@ -117,6 +117,11 @@ public class EntityManagementUtils {
                 assembly = instantiator.instantiate(at, camp);
                 return (T) mgmt.getEntityManager().getEntity(assembly.getId());
             } catch (UnsupportedOperationException e) {
+                if (at.getPlatformComponentTemplates()==null || at.getPlatformComponentTemplates().isEmpty()) {
+                    if (at.getCustomAttributes().containsKey("brooklyn.catalog"))
+                        throw new IllegalArgumentException("Unrecognized application blueprint format: expected an application, not a brooklyn.catalog");
+                    throw new IllegalArgumentException("Unrecognized application blueprint format: no services defined");
+                }
                 // map this (expected) error to a nicer message
                 throw new IllegalArgumentException("Unrecognized application blueprint format");
             } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
index 394ad03..638818e 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -306,7 +306,10 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
     }
     
     protected <K> K getRequiredConfig(ConfigKey<K> key) {
-        return checkNotNull(config().get(key), key.getName());
+        K result = config().get(key);
+        if (result==null) 
+            throw new NullPointerException("Value required for '"+key.getName()+"' in "+this);
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/core/src/main/java/brooklyn/util/task/ValueResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ValueResolver.java b/core/src/main/java/brooklyn/util/task/ValueResolver.java
index 4bb557e..cf887a7 100644
--- a/core/src/main/java/brooklyn/util/task/ValueResolver.java
+++ b/core/src/main/java/brooklyn/util/task/ValueResolver.java
@@ -265,7 +265,12 @@ public class ValueResolver<T> implements DeferredSupplier<T> {
                 final Object vf = v;
                 Callable<Object> callable = new Callable<Object>() {
                     public Object call() throws Exception {
-                        return ((DeferredSupplier<?>) vf).get();
+                        try {
+                            Tasks.setBlockingDetails("Retrieving "+vf);
+                            return ((DeferredSupplier<?>) vf).get();
+                        } finally {
+                            Tasks.resetBlockingDetails();
+                        }
                     } };
                     
                 if (Boolean.TRUE.equals(embedResolutionInTask) || timeout!=null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/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 af1cbb0..1519326 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
@@ -93,7 +93,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
 
         BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
             loader, buildWrapperAppTemplate(template));
-        EntitySpec<? extends Application> app = resolver.resolveSpec();
+        EntitySpec<? extends Application> app = resolver.resolveSpec(null);
 
         // first build the children into an empty shell app
         List<EntitySpec<?>> childSpecs = buildTemplateServicesAsSpecs(loader, template, platform);
@@ -156,38 +156,33 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         for (ResolvableLink<PlatformComponentTemplate> ctl: template.getPlatformComponentTemplates().links()) {
             PlatformComponentTemplate appChildComponentTemplate = ctl.resolve();
             BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, appChildComponentTemplate);
-            EntitySpec<?> spec = resolveSpec(entityResolver, encounteredCatalogTypes);
+            EntitySpec<?> spec = resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
 
             result.add(spec);
         }
         return result;
     }
 
-    protected EntitySpec<?> resolveSpec(
+    static EntitySpec<?> resolveSpec(ResourceUtils ru,
             BrooklynComponentTemplateResolver entityResolver,
             Set<String> encounteredCatalogTypes) {
-        ManagementContext mgmt = entityResolver.getLoader().getManagementContext();
-
         String brooklynType = entityResolver.getServiceTypeResolver().getBrooklynType(entityResolver.getDeclaredType());
         CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getServiceTypeResolver().getCatalogItem(entityResolver, entityResolver.getDeclaredType());
 
-        //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.getLoader()+"; encounteredCatalogTypes="+encounteredCatalogTypes);
 
         EntitySpec<?> spec = null;
         String protocol = Urls.getProtocol(brooklynType);
         if (protocol != null) {
             if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
-                spec = tryResolveYamlURLReferenceSpec(brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
+                spec = tryResolveYamlUrlReferenceSpec(ru, brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
                 if (spec != null) {
                     entityResolver.populateSpec(spec);
                 }
             } else {
+                // TODO support https above
+                // TODO this will probably be logged if we refer to  chef:cookbook  or other service types which BCTR accepts;
+                // better would be to have BCTR supporting the calls above
                 log.warn("The reference " + brooklynType + " looks like an URL but the protocol " +
                         protocol + " isn't white listed (" + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + "). " +
                         "Will try to load it as catalog item or java type.");
@@ -195,42 +190,20 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         }
 
         if (spec == null) {
-            // - Load a java class from current loader (item == null || entityResolver.isJavaTypePrefix())
-            // - Load a java class specified in an old-style catalog item (item != null && item.getJavaType() != null)
-            //   Old-style catalog items (can be defined in catalog.xml only) don't have structure, only a single type, so
-            //   they are loaded as a simple java type, only taking the class name from the catalog item instead of the
-            //   type value in the YAML. Classpath entries in the item are also used (through the catalog root classloader).
-            if (item == null || item.getJavaType() != null || entityResolver.isJavaTypePrefix()) {
-                spec = entityResolver.resolveSpec();
-
-            // Same as above case, but this time force java type loading (either as plain class or through an old-style
-            // catalog item, since we have already loaded a class item with the same name as the type value.
-            } else if (recursiveButTryJava) {
-                if (entityResolver.tryLoadEntityClass().isAbsent()) {
-                    throw new IllegalStateException("Recursive reference to " + brooklynType + " (and cannot be resolved as a Java type)");
-                }
-                spec = entityResolver.resolveSpec();
-
-            // Only case that's left is a catalog item with YAML content - try to parse it recursively
-            // including it's OSGi bundles in the loader classpath.
-            } else {
-                //TODO migrate to catalog.createSpec
-                spec = resolveCatalogYamlReferenceSpec(mgmt, item, encounteredCatalogTypes);
-                spec.catalogItemId(item.getId());
-                entityResolver.populateSpec(spec);
-            }
+            // load from java or yaml
+            spec = entityResolver.resolveSpec(encounteredCatalogTypes);
         }
 
         return spec;
     }
 
-    private EntitySpec<?> tryResolveYamlURLReferenceSpec(
+    private static EntitySpec<?> tryResolveYamlUrlReferenceSpec(
+            ResourceUtils ru,
             String brooklynType, BrooklynClassLoadingContext itemLoader,
             Set<String> encounteredCatalogTypes) {
         ManagementContext mgmt = itemLoader.getManagementContext();
         Reader yaml;
         try {
-            ResourceUtils ru = ResourceUtils.create(this);
             yaml = new InputStreamReader(ru.getResourceFromUrl(brooklynType), "UTF-8");
         } catch (Exception e) {
             log.warn("AssemblyTemplate type " + brooklynType + " which looks like a URL can't be fetched.", e);
@@ -247,7 +220,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         }
     }
 
-    private EntitySpec<?> resolveCatalogYamlReferenceSpec(
+    static EntitySpec<?> resolveCatalogYamlReferenceSpec(
             ManagementContext mgmt,
             CatalogItem<Entity, EntitySpec<?>> item,
             Set<String> encounteredCatalogTypes) {
@@ -259,7 +232,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
     }
 
-    private EntitySpec<?> createNestedSpec(ManagementContext mgmt,
+    private static EntitySpec<?> createNestedSpec(ManagementContext mgmt,
             Set<String> encounteredCatalogTypes, Reader input,
             BrooklynClassLoadingContext itemLoader) {
         CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get();
@@ -271,7 +244,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         } finally {
             BrooklynLoaderTracker.unsetLoader(itemLoader);
         }
-        return createNestedSpec(at, platform, itemLoader, encounteredCatalogTypes);
+        return createNestedSpecStatic(at, platform, itemLoader, encounteredCatalogTypes);
     }
 
     @Override
@@ -280,6 +253,14 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
             CampPlatform platform,
             BrooklynClassLoadingContext itemLoader,
             Set<String> encounteredCatalogTypes) {
+        return createNestedSpecStatic(template, platform, itemLoader, encounteredCatalogTypes);
+    }
+    
+    private static EntitySpec<?> createNestedSpecStatic(
+        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 {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/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 67e5af1..618d4a3 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
@@ -56,6 +56,7 @@ import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.classloading.BrooklynClassLoadingContext;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.internal.ManagementContextInternal;
+import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;
@@ -209,20 +210,57 @@ public class BrooklynComponentTemplateResolver {
     }
 
     /** resolves the spec, updating the loader if a catalog item is loaded */
-    protected <T extends Entity> EntitySpec<T> resolveSpec() {
+    protected <T extends Entity> EntitySpec<T> resolveSpec(Set<String> encounteredCatalogTypes) {
         if (alreadyBuilt.getAndSet(true))
             throw new IllegalStateException("Spec can only be used once: "+this);
 
-        EntitySpec<T> spec = createSpec();
+        EntitySpec<T> spec = createSpec(encounteredCatalogTypes);
         populateSpec(spec);
 
         return spec;
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected <T extends Entity> EntitySpec<T> createSpec() {
-        Class<T> type = (Class<T>) loadEntityClass();
+    protected <T extends Entity> EntitySpec<T> createSpec(Set<String> encounteredCatalogTypes) {
+        CatalogItem<Entity, EntitySpec<?>> item = getServiceTypeResolver().getCatalogItem(this, getDeclaredType());
+        if (encounteredCatalogTypes==null) encounteredCatalogTypes = MutableSet.of();
+        
+        //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;
+
+        // - Load a java class from current loader (item == null || entityResolver.isJavaTypePrefix())
+        // - Load a java class specified in an old-style catalog item (item != null && item.getJavaType() != null)
+        //   Old-style catalog items (can be defined in catalog.xml only) don't have structure, only a single type, so
+        //   they are loaded as a simple java type, only taking the class name from the catalog item instead of the
+        //   type value in the YAML. Classpath entries in the item are also used (through the catalog root classloader).
+        if (item == null || item.getJavaType() != null || isJavaTypePrefix()) {
+            return createSpecFromJavaType();
+
+        // Same as above case, but this time force java type loading (either as plain class or through an old-style
+        // catalog item, since we have already loaded a class item with the same name as the type value.
+        } else if (recursiveButTryJava) {
+            if (tryLoadEntityClass().isAbsent()) {
+                throw new IllegalStateException("Recursive reference to " + item + " (and cannot be resolved as a Java type)");
+            }
+            return createSpecFromJavaType();
 
+        // Only case that's left is a catalog item with YAML content - try to parse it recursively
+        // including it's OSGi bundles in the loader classpath.
+        } else {
+            // TODO perhaps migrate to catalog.createSpec ?
+            EntitySpec<?> spec = BrooklynAssemblyTemplateInstantiator.resolveCatalogYamlReferenceSpec(mgmt, item, encounteredCatalogTypes);
+            spec.catalogItemId(item.getId());
+            
+            return (EntitySpec<T>)spec;
+        }
+    }
+    
+    protected <T extends Entity> EntitySpec<T> createSpecFromJavaType() {
+        Class<T> type = (Class<T>) loadEntityClass();
+        
         EntitySpec<T> spec;
         if (type.isInterface()) {
             spec = EntitySpec.create(type);
@@ -256,17 +294,15 @@ public class BrooklynComponentTemplateResolver {
 
         Object childrenObj = attrs.getStringKey("brooklyn.children");
         if (childrenObj != null) {
+            // Creating a new set of encounteredCatalogTypes means that this won't check things recursively;
+            // but we are looking at children so we probably *should* be resetting the recursive list we've looked at;
+            // (but see also, a previous comment here which suggested otherwise? - Apr 2015)
             Set<String> encounteredCatalogTypes = MutableSet.of();
 
             Iterable<Map<String,?>> children = (Iterable<Map<String,?>>)childrenObj;
             for (Map<String,?> childAttrs : children) {
                 BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, childAttrs);
-                BrooklynAssemblyTemplateInstantiator instantiator = new BrooklynAssemblyTemplateInstantiator();
-                // TODO: Creating a new set of encounteredCatalogTypes prevents the recursive definition check in
-                // BrooklynAssemblyTemplateInstantiator.resolveSpec from correctly determining if a YAML entity is
-                // defined recursively. However, the number of overrides of newInstance, and the number of places
-                // calling populateSpec make it difficult to pass encounteredCatalogTypes in as a parameter
-                EntitySpec<? extends Entity> childSpec = instantiator.resolveSpec(entityResolver, encounteredCatalogTypes);
+                EntitySpec<? extends Entity> childSpec = BrooklynAssemblyTemplateInstantiator.resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
                 spec.child(childSpec);
             }
         }
@@ -411,7 +447,7 @@ 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();
+                return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(null);
             }
             if (flag instanceof ManagementContextInjectable) {
                 log.debug("Injecting Brooklyn management context info object: {}", flag);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/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 e5eae35..1e321dc 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
@@ -40,6 +40,7 @@ import brooklyn.management.osgi.OsgiTestResources;
 import brooklyn.test.TestResourceUnavailableException;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
+import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.Iterables;
 
@@ -217,7 +218,7 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
         String yaml = "name: simple-app-yaml\n" +
                       "location: localhost\n" +
                       "services: \n" +
-                      "  - serviceType: " + ver(referrerSymbolicName);
+                      "  - type: " + ver(referrerSymbolicName);
         Entity app = createAndStartApplication(yaml);
 
         Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
@@ -344,7 +345,8 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
             // TODO only fails if using 'services', because that forces plan parsing; should fail in all cases
             addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referrerSymbolicName));
             fail("Expected to throw");
-        } catch (IllegalStateException e) {
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
             assertTrue(e.getMessage().contains(referrerSymbolicName), "message was: "+e);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f6c5619d/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html
index d70fd9b..b72bb10 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/create-step-template-entry.html
@@ -18,16 +18,16 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-<div class="template-lozenge frame" id="<%= id %>" data-name="<%= name %>" data-yaml="<%= planYaml %>">
+<div class="template-lozenge frame" id="<%- id %>" data-name="<%- name %>" data-yaml="<%- planYaml %>">
     <% if (iconUrl) { %>
     <div class="icon">
-        <img src="<%= iconUrl %>" alt="(icon)" />
+        <img src="<%- iconUrl %>" alt="(icon)" />
     </div>
     <% } %>
     <div class="blurb">
-        <div class="title"><%= name %></div>
+        <div class="title"><%- name %></div>
         <div class="description">
-            <%= description ? description : "" %>
+            <%- description ? description : "" %>
         </div>
     </div>
 </div>