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/08/19 16:35:33 UTC

[1/4] incubator-brooklyn git commit: This closes #760. Makes YAML pluggable.

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 0f6041e41 -> fb6a4a1d0


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/resources/org/apache/brooklyn/core/test/camp/brooklyn/lite/test-app-service-blueprint.yaml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/brooklyn/core/test/camp/brooklyn/lite/test-app-service-blueprint.yaml b/core/src/test/resources/org/apache/brooklyn/core/test/camp/brooklyn/lite/test-app-service-blueprint.yaml
deleted file mode 100644
index c0bb607..0000000
--- a/core/src/test/resources/org/apache/brooklyn/core/test/camp/brooklyn/lite/test-app-service-blueprint.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#  http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-name: sample
-description: Tomcat sample JSP and servlet application.
-origin: http://www.oracle.com/nCAMP/Hand
-services:
-  -
-    type: io.camp.mock:AppServer
-    name: Hello WAR
-    wars:
-        /: hello.war
-    controller.spec:
-        port: 80
-
-brooklyn.catalog:
-  name: catalog-name
-  type: io.camp.mock.MyApplication
-  version: 0.9
-  libraries:
-  - name: org.apache.brooklyn.test.resources.osgi.brooklyn-test-osgi-entities
-    version: 0.1.0
-    url: classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/pom.xml
----------------------------------------------------------------------
diff --git a/usage/camp/pom.xml b/usage/camp/pom.xml
index 9a643e1..34da33c 100644
--- a/usage/camp/pom.xml
+++ b/usage/camp/pom.xml
@@ -36,6 +36,11 @@
     <dependencies>
         
         <dependency>
+            <groupId>org.apache.brooklyn.camp</groupId>
+            <artifactId>camp-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.brooklyn</groupId>
             <artifactId>brooklyn-core</artifactId>
             <version>${project.version}</version>
@@ -112,6 +117,13 @@
         
         <!-- demo and tests -->
         <dependency>
+            <groupId>org.apache.brooklyn.camp</groupId>
+            <artifactId>camp-base</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.brooklyn</groupId>
             <artifactId>brooklyn-core</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java
index 09dcd78..515ec9f 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java
@@ -43,7 +43,8 @@ public class BrooklynCampConstants {
             .inheritance(ConfigInheritance.NONE)
             .build();
 
-    public static final ConfigKey<CampPlatform> CAMP_PLATFORM = BrooklynServerConfig.CAMP_PLATFORM;
+    public static final ConfigKey<CampPlatform> CAMP_PLATFORM = ConfigKeys.newConfigKey(CampPlatform.class, "brooklyn.camp.platform",
+            "Config set at brooklyn management platform to find the CampPlatform instance (bi-directional)");
 
     public static final Set<String> YAML_URL_PROTOCOL_WHITELIST = ImmutableSet.of("classpath", "http");
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
new file mode 100644
index 0000000..c345a9d
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.api;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.camp.CampPlatform;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+
+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/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index 82bef64..8285a26 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -26,8 +26,6 @@ import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
@@ -40,20 +38,23 @@ import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
 import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
 import org.apache.brooklyn.camp.spi.Assembly;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder;
+import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
 import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
 import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
-import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.entity.core.Entities;
 import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.net.Urls;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -74,11 +75,15 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
     }
 
     public Application create(AssemblyTemplate template, CampPlatform platform) {
-        Application instance = EntityManagementUtils.createUnstarted(getBrooklynManagementContext(platform), template);
-        log.debug("CAMP created {}", instance);
+        ManagementContext mgmt = getBrooklynManagementContext(platform);
+        BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
+        EntitySpec<? extends Application> spec = createSpec(template, platform, loader, true);
+        Application instance = mgmt.getEntityManager().createEntity(spec);
+        log.info("CAMP placing '{}' under management", instance);
+        Entities.startManagement(instance, mgmt);
         return instance;
     }
-
+    
     private ManagementContext getBrooklynManagementContext(CampPlatform platform) {
         return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
     }
@@ -92,6 +97,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
             loader, buildWrapperAppTemplate(template));
         EntitySpec<? extends Application> app = resolver.resolveSpec(null);
+        app.configure(EntityManagementUtils.WRAPPER_APP_MARKER, Boolean.TRUE);
 
         // first build the children into an empty shell app
         List<EntitySpec<?>> childSpecs = buildTemplateServicesAsSpecs(loader, template, platform);
@@ -106,8 +112,6 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
             // if promoted, apply the transformations done to the app
             // (transformations will be done by the resolveSpec call above, but we are collapsing oldApp so transfer to app=newApp)
             EntityManagementUtils.collapseSpec(oldApp, app);
-        } else {
-            app.configure(EntityManagementUtils.WRAPPER_APP_MARKER, Boolean.TRUE);
         }
 
         return app;
@@ -141,7 +145,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         if (childSpec.getType()==null || !Application.class.isAssignableFrom(childSpec.getType()))
             return false;
 
-        return EntityManagementUtils.hasNoNameOrCustomKeysOrRoot(template, app);
+        return EntityManagementUtils.canPromote(app);
     }
 
     private List<EntitySpec<?>> buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform) {
@@ -154,14 +158,16 @@ 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(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
+            EntitySpec<?> spec = resolveSpec(platform, ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
 
             result.add(spec);
         }
         return result;
     }
 
-    static EntitySpec<?> resolveSpec(ResourceUtils ru,
+    static EntitySpec<?> resolveSpec(
+            CampPlatform platform,
+            ResourceUtils ru,
             BrooklynComponentTemplateResolver entityResolver,
             Set<String> encounteredCatalogTypes) {
         String brooklynType = entityResolver.getServiceTypeResolver().getBrooklynType(entityResolver.getDeclaredType());
@@ -173,7 +179,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         String protocol = Urls.getProtocol(brooklynType);
         if (protocol != null) {
             if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
-                spec = tryResolveYamlUrlReferenceSpec(ru, brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
+                spec = tryResolveYamlUrlReferenceSpec(platform, ru, brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
                 if (spec != null) {
                     entityResolver.populateSpec(spec);
                 }
@@ -196,10 +202,10 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
     }
 
     private static EntitySpec<?> tryResolveYamlUrlReferenceSpec(
+            CampPlatform platform,
             ResourceUtils ru,
             String brooklynType, BrooklynClassLoadingContext itemLoader,
             Set<String> encounteredCatalogTypes) {
-        ManagementContext mgmt = itemLoader.getManagementContext();
         Reader yaml;
         try {
             yaml = new InputStreamReader(ru.getResourceFromUrl(brooklynType), "UTF-8");
@@ -208,7 +214,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
             return null;
         }
         try {
-            return createNestedSpec(mgmt, encounteredCatalogTypes, yaml, itemLoader);
+            return createNestedSpec(platform, encounteredCatalogTypes, yaml, itemLoader);
         } finally {
             try {
                 yaml.close();
@@ -219,21 +225,20 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
     }
 
     static EntitySpec<?> resolveCatalogYamlReferenceSpec(
-            ManagementContext mgmt,
+            CampPlatform platform,
             CatalogItem<Entity, EntitySpec<?>> item,
             Set<String> encounteredCatalogTypes) {
-
+        ManagementContext mgmt = getManagementContext(platform);
         String yaml = item.getPlanYaml();
         Reader input = new StringReader(yaml);
         BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, item);
 
-        return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
+        return createNestedSpec(platform, encounteredCatalogTypes, input, itemLoader);
     }
 
-    private static EntitySpec<?> createNestedSpec(ManagementContext mgmt,
+    private static EntitySpec<?> createNestedSpec(CampPlatform platform,
             Set<String> encounteredCatalogTypes, Reader input,
             BrooklynClassLoadingContext itemLoader) {
-        CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get();
 
         AssemblyTemplate at;
         BrooklynLoaderTracker.setLoader(itemLoader);
@@ -277,4 +282,8 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         }
     }
 
+    private static ManagementContext getManagementContext(CampPlatform platform) {
+        return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index f858370..32bfa24 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -28,8 +28,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.annotation.Nullable;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
@@ -37,6 +35,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver;
@@ -65,6 +64,8 @@ import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.Reflections;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
 import com.google.common.base.Splitter;
@@ -250,7 +251,7 @@ public class BrooklynComponentTemplateResolver {
         // including it's OSGi bundles in the loader classpath.
         } else {
             // TODO perhaps migrate to catalog.createSpec ?
-            EntitySpec<?> spec = BrooklynAssemblyTemplateInstantiator.resolveCatalogYamlReferenceSpec(mgmt, item, encounteredCatalogTypes);
+            EntitySpec<?> spec = BrooklynAssemblyTemplateInstantiator.resolveCatalogYamlReferenceSpec(getCampPlatform(), item, encounteredCatalogTypes);
             spec.catalogItemId(item.getId());
             
             return (EntitySpec<T>)spec;
@@ -303,7 +304,7 @@ public class BrooklynComponentTemplateResolver {
             Iterable<Map<String,?>> children = (Iterable<Map<String,?>>)childrenObj;
             for (Map<String,?> childAttrs : children) {
                 BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, childAttrs);
-                EntitySpec<? extends Entity> childSpec = BrooklynAssemblyTemplateInstantiator.resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
+                EntitySpec<? extends Entity> childSpec = BrooklynAssemblyTemplateInstantiator.resolveSpec(getCampPlatform(), ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
                 spec.child(childSpec);
             }
         }
@@ -486,4 +487,7 @@ public class BrooklynComponentTemplateResolver {
         return (List<Map<String, Object>>) attrs.get(BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
     }
 
+    private CampPlatform getCampPlatform() {
+        return CampCatalogUtils.getCampPlatform(mgmt);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
new file mode 100644
index 0000000..71aded1
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.spi.creation;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.camp.CampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
+import org.apache.brooklyn.camp.util.yaml.Yamls;
+import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
+import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class CampCatalogUtils {
+
+    public static AbstractBrooklynObjectSpec<?, ?> createSpec(ManagementContext mgmt, CatalogItem<?, ?> item) {
+        // preferred way is to parse the yaml, to resolve references late;
+        // the parsing on load is to populate some fields, but it is optional.
+        // TODO messy for location and policy that we need brooklyn.{locations,policies} root of the yaml, but it works;
+        // see related comment when the yaml is set, in addAbstractCatalogItems
+        // (not sure if anywhere else relies on that syntax; if not, it should be easy to fix!)
+        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, item);
+        DeploymentPlan plan = makePlanFromYaml(loader.getManagementContext(), item.getPlanYaml());
+        Preconditions.checkNotNull(item.getCatalogItemType(), "catalog item type for "+plan);
+        AbstractBrooklynObjectSpec<?, ?> spec;
+        switch (item.getCatalogItemType()) {
+            case TEMPLATE:
+            case ENTITY:
+                spec = createEntitySpec(item.getSymbolicName(), plan, loader);
+                break;
+            case LOCATION: 
+                spec = createLocationSpec(plan, loader);
+                break;
+            case POLICY: 
+                spec = createPolicySpec(item.getSymbolicName(), plan, loader);
+                break;
+            default:
+                throw new IllegalStateException("Unknown CI Type "+item.getCatalogItemType()+" for "+plan);
+        }
+
+        ((AbstractBrooklynObjectSpec<?, ?>)spec).catalogItemId(item.getId());
+
+        if (Strings.isBlank( ((AbstractBrooklynObjectSpec<?, ?>)spec).getDisplayName() ))
+            ((AbstractBrooklynObjectSpec<?, ?>)spec).displayName(item.getDisplayName());
+
+        return spec;
+    }
+
+    private static EntitySpec<?> createEntitySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+        CampPlatform camp = getCampPlatform(loader.getManagementContext());
+
+        // TODO should not register new AT each time we instantiate from the same plan; use some kind of cache
+        AssemblyTemplate at;
+        BrooklynLoaderTracker.setLoader(loader);
+        try {
+            at = camp.pdp().registerDeploymentPlan(plan);
+        } finally {
+            BrooklynLoaderTracker.unsetLoader(loader);
+        }
+
+        try {
+            AssemblyTemplateInstantiator instantiator = at.getInstantiator().newInstance();
+            if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
+                return ((AssemblyTemplateSpecInstantiator)instantiator).createNestedSpec(at, camp, loader, 
+                    getInitialEncounteredSymbol(symbolicName));
+            }
+            throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    private static MutableSet<String> getInitialEncounteredSymbol(String symbolicName) {
+        return symbolicName==null ? MutableSet.<String>of() : MutableSet.of(symbolicName);
+    }
+
+    private static PolicySpec<?> createPolicySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+        return createPolicySpec(plan, loader, getInitialEncounteredSymbol(symbolicName));
+    }
+
+    private static PolicySpec<?> createPolicySpec(DeploymentPlan plan, BrooklynClassLoadingContext loader, Set<String> encounteredCatalogTypes) {
+        //Would ideally re-use io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver.PolicySpecResolver
+        //but it is CAMP specific and there is no easy way to get hold of it.
+        Object policies = checkNotNull(plan.getCustomAttributes().get(BasicBrooklynCatalog.POLICIES_KEY), "policy config");
+        if (!(policies instanceof Iterable<?>)) {
+            throw new IllegalStateException("The value of " + BasicBrooklynCatalog.POLICIES_KEY + " must be an Iterable.");
+        }
+
+        Object policy = Iterables.getOnlyElement((Iterable<?>)policies);
+
+        return createPolicySpec(loader, policy, encounteredCatalogTypes);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static PolicySpec<?> createPolicySpec(BrooklynClassLoadingContext loader, Object policy, Set<String> encounteredCatalogTypes) {
+        Map<String, Object> itemMap;
+        if (policy instanceof String) {
+            itemMap = ImmutableMap.<String, Object>of("type", policy);
+        } else if (policy instanceof Map) {
+            itemMap = (Map<String, Object>) policy;
+        } else {
+            throw new IllegalStateException("Policy expected to be string or map. Unsupported object type " + policy.getClass().getName() + " (" + policy.toString() + ")");
+        }
+
+        String versionedId = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "policy_type", "policyType", "type"), "policy type");
+        PolicySpec<? extends Policy> spec;
+        CatalogItem<?, ?> policyItem = CatalogUtils.getCatalogItemOptionalVersion(loader.getManagementContext(), versionedId);
+        if (policyItem != null && !encounteredCatalogTypes.contains(policyItem.getSymbolicName())) {
+            if (policyItem.getCatalogItemType() != CatalogItemType.POLICY) {
+                throw new IllegalStateException("Non-policy catalog item in policy context: " + policyItem);
+            }
+            //TODO re-use createSpec
+            BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(loader.getManagementContext(), policyItem);
+            if (policyItem.getPlanYaml() != null) {
+                DeploymentPlan plan = makePlanFromYaml(loader.getManagementContext(), policyItem.getPlanYaml());
+                encounteredCatalogTypes.add(policyItem.getSymbolicName());
+                return createPolicySpec(plan, itemLoader, encounteredCatalogTypes);
+            } else if (policyItem.getJavaType() != null) {
+                spec = PolicySpec.create((Class<Policy>)itemLoader.loadClass(policyItem.getJavaType()));
+            } else {
+                throw new IllegalStateException("Invalid policy item - neither yaml nor javaType: " + policyItem);
+            }
+        } else {
+            spec = PolicySpec.create(loader.loadClass(versionedId, Policy.class));
+        }
+        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
+        if (brooklynConfig != null) {
+            spec.configure(brooklynConfig);
+        }
+        return spec;
+    }
+
+    private static LocationSpec<?> createLocationSpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
+        // See #createPolicySpec; this impl is modeled on that.
+        // spec.catalogItemId is set by caller
+        Object locations = checkNotNull(plan.getCustomAttributes().get(BasicBrooklynCatalog.LOCATIONS_KEY), "location config");
+        if (!(locations instanceof Iterable<?>)) {
+            throw new IllegalStateException("The value of " + BasicBrooklynCatalog.LOCATIONS_KEY + " must be an Iterable.");
+        }
+
+        Object location = Iterables.getOnlyElement((Iterable<?>)locations);
+
+        return createLocationSpec(loader, location); 
+    }
+
+    @SuppressWarnings("unchecked")
+    private static LocationSpec<?> createLocationSpec(BrooklynClassLoadingContext loader, Object location) {
+        Map<String, Object> itemMap;
+        if (location instanceof String) {
+            itemMap = ImmutableMap.<String, Object>of("type", location);
+        } else if (location instanceof Map) {
+            itemMap = (Map<String, Object>) location;
+        } else {
+            throw new IllegalStateException("Location expected to be string or map. Unsupported object type " + location.getClass().getName() + " (" + location.toString() + ")");
+        }
+
+        String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type");
+        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
+        Maybe<Class<? extends Location>> javaClass = loader.tryLoadClass(type, Location.class);
+        if (javaClass.isPresent()) {
+            LocationSpec<?> spec = LocationSpec.create(javaClass.get());
+            if (brooklynConfig != null) {
+                spec.configure(brooklynConfig);
+            }
+            return spec;
+        } else {
+            Maybe<Location> loc = loader.getManagementContext().getLocationRegistry().resolve(type, false, brooklynConfig);
+            if (loc.isPresent()) {
+                // TODO extensions?
+                Map<String, Object> locConfig = ((ConfigurationSupportInternal)loc.get().config()).getBag().getAllConfig();
+                Class<? extends Location> locType = loc.get().getClass();
+                Set<Object> locTags = loc.get().tags().getTags();
+                String locDisplayName = loc.get().getDisplayName();
+                return LocationSpec.create(locType)
+                        .configure(locConfig)
+                        .displayName(locDisplayName)
+                        .tags(locTags);
+            } else {
+                throw new IllegalStateException("No class or resolver found for location type "+type);
+            }
+        }
+    }
+
+    private static DeploymentPlan makePlanFromYaml(ManagementContext mgmt, String yaml) {
+        CampPlatform camp = getCampPlatform(mgmt);
+        return camp.pdp().parseDeploymentPlan(Streams.newReaderWithContents(yaml));
+    }
+
+    /**
+     * @return the CAMP platform associated with a management context, if there is one.
+     */
+    public static CampPlatform getCampPlatform(ManagementContext mgmt) {
+        CampPlatform result = mgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
+        if (result!=null) {
+            return result;
+        } else {
+            throw new IllegalStateException("No CAMP Platform is registered with this Brooklyn management context.");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
new file mode 100644
index 0000000..7650a9b
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.spi.creation;
+
+import java.io.StringReader;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.camp.CampPlatform;
+import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+
+public class CampToSpecTransformer implements PlanToSpecTransformer {
+
+    public static final String YAML_CAMP_PLAN_TYPE = "org.apache.brooklyn.camp/yaml";
+
+    private ManagementContext mgmt;
+
+    @Override
+    public String getName() {
+        return YAML_CAMP_PLAN_TYPE;
+    }
+
+    @Override
+    public boolean accepts(String mime) {
+        return YAML_CAMP_PLAN_TYPE.equals(mime);
+    }
+
+    @Override
+    public <T extends Application> EntitySpec<T> createApplicationSpec(String plan) {
+      CampPlatform camp = CampCatalogUtils.getCampPlatform(mgmt);
+      AssemblyTemplate at = camp.pdp().registerDeploymentPlan( new StringReader(plan) );
+      AssemblyTemplateInstantiator instantiator;
+      try {
+          instantiator = at.getInstantiator().newInstance();
+      } catch (Exception e) {
+          throw Exceptions.propagate(e);
+      }
+      if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
+          BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
+          @SuppressWarnings("unchecked")
+          EntitySpec<T> createSpec = (EntitySpec<T>) ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, true);
+          return createSpec;
+      } else {
+          // The unknown instantiator can create the app (Assembly), but not a spec.
+          // Currently, all brooklyn plans should produce the above.
+          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");
+      }
+    }
+
+    @Override
+    public AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(CatalogItem<?, ?> item) {
+        return CampCatalogUtils.createSpec(mgmt, item);
+    }
+
+    @Override
+    public void injectManagementContext(ManagementContext mgmt) {
+        this.mgmt = mgmt;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer b/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer
new file mode 100644
index 0000000..e93291e
--- /dev/null
+++ b/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.core.plan.PlanToSpecTransformer
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.brooklyn.camp.brooklyn.spi.creation.CampToSpecTransformer

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
index 67ccb1b..30a93e4 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
@@ -46,7 +46,12 @@ public class CatalogYamlCombiTest extends AbstractYamlTest {
             "brooklyn.catalog:",
             "  version: "+TEST_VERSION,
             "  items:",
-            "  - item:",
+            
+            "  - itemType: entity",
+            "    item:",
+            // TODO inclusion of the above information gives a better error message when no transformers
+//            "  - item:",
+            
             "      id: A",
             "      type: "+BasicEntity.class.getName(),
             "      brooklyn.config: { a: 1, b: 0 }",

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampPlatformWithJustBrooklynMgmt.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampPlatformWithJustBrooklynMgmt.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampPlatformWithJustBrooklynMgmt.java
new file mode 100644
index 0000000..e65d49d
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampPlatformWithJustBrooklynMgmt.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.test.lite;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.camp.BasicCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+
+public class CampPlatformWithJustBrooklynMgmt extends BasicCampPlatform implements HasBrooklynManagementContext {
+
+    private ManagementContext mgmt;
+
+    public CampPlatformWithJustBrooklynMgmt(ManagementContext mgmt) {
+        this.mgmt = mgmt;
+        ((BrooklynProperties)mgmt.getConfig()).put(BrooklynCampConstants.CAMP_PLATFORM, this);
+    }
+    
+    @Override
+    public ManagementContext getBrooklynManagementContext() {
+        return mgmt;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
new file mode 100644
index 0000000..cfd5b38
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.test.lite;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.camp.spi.Assembly;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.pdp.PdpYamlTest;
+import org.apache.brooklyn.camp.test.mock.web.MockWebPlatform;
+import org.apache.brooklyn.core.catalog.CatalogPredicates;
+import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
+import org.apache.brooklyn.core.catalog.internal.CatalogDto;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.effector.core.AddChildrenEffector;
+import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.stream.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+/** Tests of lightweight CAMP integration. Since the "real" integration is in brooklyn-camp project,
+ * but some aspects of CAMP we want to be able to test here. */
+public class CampYamlLiteTest {
+    private static final String TEST_VERSION = "0.1.2";
+
+    private static final Logger log = LoggerFactory.getLogger(CampYamlLiteTest.class);
+    
+    protected LocalManagementContext mgmt;
+    protected CampPlatformWithJustBrooklynMgmt platform;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstanceWithOsgi();
+        platform = new CampPlatformWithJustBrooklynMgmt(mgmt);
+        MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        if (mgmt!=null) mgmt.terminate();
+    }
+    
+    /** based on {@link PdpYamlTest} for parsing,
+     * then creating a {@link TestAppAssembly} */
+    @Test
+    public void testYamlServiceMatchAndBrooklynInstantiate() throws Exception {
+        Reader input = new InputStreamReader(getClass().getResourceAsStream("test-app-service-blueprint.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+        log.info("AT is:\n"+at.toString());
+        Assert.assertEquals(at.getName(), "sample");
+        Assert.assertEquals(at.getPlatformComponentTemplates().links().size(), 1);
+        
+        // now use brooklyn to instantiate - note it won't be faithful, but it will set some config keys
+        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+        
+        TestApplication app = ((TestAppAssembly)assembly).getBrooklynApp();
+        Assert.assertEquals( app.getConfig(TestEntity.CONF_NAME), "sample" );
+        Map<String, String> map = app.getConfig(TestEntity.CONF_MAP_THING);
+        Assert.assertEquals( map.get("desc"), "Tomcat sample JSP and servlet application." );
+        
+        Assert.assertEquals( app.getChildren().size(), 1 );
+        Entity svc = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertEquals( svc.getConfig(TestEntity.CONF_NAME), "Hello WAR" );
+        map = svc.getConfig(TestEntity.CONF_MAP_THING);
+        Assert.assertEquals( map.get("type"), MockWebPlatform.APPSERVER.getType() );
+        // desc ensures we got the information from the matcher, as this value is NOT in the yaml
+        Assert.assertEquals( map.get("desc"), MockWebPlatform.APPSERVER.getDescription() );
+    }
+
+    /** based on {@link PdpYamlTest} for parsing,
+     * then creating a {@link TestAppAssembly} */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testAddChildrenEffector() throws Exception {
+        String childYaml = Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml"));
+        AddChildrenEffector newEff = new AddChildrenEffector(ConfigBag.newInstance()
+            .configure(AddChildrenEffector.EFFECTOR_NAME, "add_tomcat")
+            .configure(AddChildrenEffector.BLUEPRINT_YAML, childYaml)
+            .configure(AddChildrenEffector.EFFECTOR_PARAMETER_DEFS, MutableMap.of("war", (Object)MutableMap.of(
+                "defaultValue", "foo.war"))) ) ;
+        TestApplication app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).addInitializer(newEff), mgmt);
+
+        // test adding, with a parameter
+        Task<List> task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.of("war", "foo.bar"));
+        List result = task.get();
+        
+        Entity newChild = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.bar");
+        
+        Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId());
+        Entities.unmanage(newChild);
+        
+        // and test default value
+        task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.<String,Object>of());
+        result = task.get();
+        
+        newChild = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.war");
+        
+        Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId());
+        Entities.unmanage(newChild);
+    }
+
+    @Test
+    public void testYamlServiceForCatalog() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        CatalogItem<?, ?> realItem = Iterables.getOnlyElement(mgmt.getCatalog().addItems(Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml"))));
+        Iterable<CatalogItem<Object, Object>> retrievedItems = mgmt.getCatalog()
+                .getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo("catalog-name")));
+        
+        Assert.assertEquals(Iterables.size(retrievedItems), 1, "Wrong retrieved items: "+retrievedItems);
+        CatalogItem<Object, Object> retrievedItem = Iterables.getOnlyElement(retrievedItems);
+        Assert.assertEquals(retrievedItem, realItem);
+
+        Collection<CatalogBundle> bundles = retrievedItem.getLibraries();
+        Assert.assertEquals(bundles.size(), 1);
+        CatalogBundle bundle = Iterables.getOnlyElement(bundles);
+        Assert.assertEquals(bundle.getUrl(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL);
+        Assert.assertEquals(bundle.getVersion(), "0.1.0");
+
+        EntitySpec<?> spec1 = (EntitySpec<?>) mgmt.getCatalog().createSpec(retrievedItem);
+        assertNotNull(spec1);
+        Assert.assertEquals(spec1.getConfig().get(TestEntity.CONF_NAME), "sample");
+        
+        // TODO other assertions, about children
+    }
+
+    @Test
+    public void testRegisterCustomEntityWithBundleWhereEntityIsFromCoreAndIconFromBundle() throws IOException {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id";
+        String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
+        String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl);
+
+        mgmt.getCatalog().addItems(yaml);
+
+        assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl);
+    }
+
+    @Test
+    public void testResetXmlWithCustomEntity() throws IOException {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id";
+        String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
+        String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl);
+
+        LocalManagementContext mgmt2 = LocalManagementContextForTests.newInstanceWithOsgi();
+        try {
+            CampPlatformWithJustBrooklynMgmt platform2 = new CampPlatformWithJustBrooklynMgmt(mgmt2);
+            MockWebPlatform.populate(platform2, TestAppAssemblyInstantiator.class);
+
+            mgmt2.getCatalog().addItems(yaml);
+            String xml = ((BasicBrooklynCatalog) mgmt2.getCatalog()).toXmlString();
+            ((BasicBrooklynCatalog) mgmt.getCatalog()).reset(CatalogDto.newDtoFromXmlContents(xml, "copy of temporary catalog"));
+        } finally {
+            mgmt2.terminate();
+        }
+
+        assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl);
+    }
+
+    private String getSampleMyCatalogAppYaml(String symbolicName, String bundleUrl) {
+        return "brooklyn.catalog:\n" +
+                "  id: " + symbolicName + "\n" +
+                "  name: My Catalog App\n" +
+                "  description: My description\n" +
+                "  icon_url: classpath:/brooklyn/osgi/tests/icon.gif\n" +
+                "  version: " + TEST_VERSION + "\n" +
+                "  libraries:\n" +
+                "  - url: " + bundleUrl + "\n" +
+                "\n" +
+                "services:\n" +
+                "- type: io.camp.mock:AppServer\n";
+    }
+
+    private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {
+        CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " +
+                Joiner.on(",").join(mgmt.getCatalog().getCatalogItems()));
+        assertEquals(item.getSymbolicName(), symbolicName);
+
+        // stored as yaml, not java
+        assertNotNull(item.getPlanYaml());
+        Assert.assertTrue(item.getPlanYaml().contains("io.camp.mock:AppServer"));
+
+        // and let's check we have libraries
+        Collection<CatalogBundle> libs = item.getLibraries();
+        assertEquals(libs.size(), 1);
+        CatalogBundle bundle = Iterables.getOnlyElement(libs);
+        assertEquals(bundle.getUrl(), bundleUrl);
+
+        // now let's check other things on the item
+        assertEquals(item.getDisplayName(), "My Catalog App");
+        assertEquals(item.getDescription(), "My description");
+        assertEquals(item.getIconUrl(), "classpath:/brooklyn/osgi/tests/icon.gif");
+
+        // and confirm we can resolve ICON
+        byte[] iconData = Streams.readFully(ResourceUtils.create(CatalogUtils.newClassLoadingContext(mgmt, item)).getResourceFromUrl(item.getIconUrl()));
+        assertEquals(iconData.length, 43);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssembly.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssembly.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssembly.java
new file mode 100644
index 0000000..877c00b
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssembly.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.test.lite;
+
+import org.apache.brooklyn.camp.spi.Assembly;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+
+public class TestAppAssembly extends Assembly {
+
+    private TestApplication brooklynApp;
+
+    public TestAppAssembly(TestApplication brooklynApp) {
+        this.brooklynApp = brooklynApp;
+    }
+    
+    public TestApplication getBrooklynApp() {
+        return brooklynApp;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssemblyInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssemblyInstantiator.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssemblyInstantiator.java
new file mode 100644
index 0000000..512e8ef
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/TestAppAssemblyInstantiator.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.test.lite;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.camp.CampPlatform;
+import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+import org.apache.brooklyn.camp.spi.AbstractResource;
+import org.apache.brooklyn.camp.spi.Assembly;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
+import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
+import org.apache.brooklyn.camp.spi.instantiate.BasicAssemblyTemplateInstantiator;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+
+/** simple illustrative instantiator which always makes a {@link TestApplication}, populated with {@link TestEntity} children,
+ * all setting {@link TestEntity#CONF_NAME} for the name in the plan and in the service specs
+ * <p>
+ * the "real" instantiator for brooklyn is in brooklyn-camp project, not visible here, so let's have something we can test */
+public class TestAppAssemblyInstantiator extends BasicAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
+
+    @Override
+    public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) {
+        if (!(platform instanceof HasBrooklynManagementContext)) {
+            throw new IllegalStateException("Instantiator can only be used with CAMP platforms with a Brooklyn management context");
+        }
+        ManagementContext mgmt = ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
+        
+        TestApplication app = (TestApplication) mgmt.getEntityManager().createEntity( createSpec(template, platform, null, false) );
+        mgmt.getEntityManager().manage(app);
+
+        return new TestAppAssembly(app);
+    }
+
+    @Override
+    public EntitySpec<?> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrap) {
+        EntitySpec<TestApplication> app = EntitySpec.create(TestApplication.class)
+            .configure(TestEntity.CONF_NAME, template.getName())
+            .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", template.getType(), "desc", template.getDescription()));
+        applyBrooklynConfig(template, app);
+        
+        for (ResolvableLink<PlatformComponentTemplate> t: template.getPlatformComponentTemplates().links()) {
+            EntitySpec<TestEntity> spec = EntitySpec.create(TestEntity.class)
+                .configure(TestEntity.CONF_NAME, t.getName())
+                .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", t.resolve().getType(), "desc", t.resolve().getDescription()));
+            applyBrooklynConfig(t.resolve(), app);
+            app.child(spec);
+        }
+        
+        return app;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private void applyBrooklynConfig(AbstractResource template, EntitySpec<TestApplication> app) {
+        Object bc = template.getCustomAttributes().get("brooklyn.config");
+        if (bc instanceof Map)
+            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/6ed695e5/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/test/lite/test-app-service-blueprint.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/test/lite/test-app-service-blueprint.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/test/lite/test-app-service-blueprint.yaml
new file mode 100644
index 0000000..c0bb607
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/test/lite/test-app-service-blueprint.yaml
@@ -0,0 +1,38 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+name: sample
+description: Tomcat sample JSP and servlet application.
+origin: http://www.oracle.com/nCAMP/Hand
+services:
+  -
+    type: io.camp.mock:AppServer
+    name: Hello WAR
+    wars:
+        /: hello.war
+    controller.spec:
+        port: 80
+
+brooklyn.catalog:
+  name: catalog-name
+  type: io.camp.mock.MyApplication
+  version: 0.9
+  libraries:
+  - name: org.apache.brooklyn.test.resources.osgi.brooklyn-test-osgi-entities
+    version: 0.1.0
+    url: classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
index 5ea82f7..d8a0fc9 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
@@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.Closeable;
 import java.io.File;
-import java.io.StringReader;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -49,13 +48,11 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
 import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
-import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.config.ConfigPredicates;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.internal.BrooklynShutdownHooks;
@@ -77,17 +74,6 @@ import org.apache.brooklyn.entity.core.StartableApplication;
 import org.apache.brooklyn.entity.factory.ApplicationBuilder;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.entity.trait.Startable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Splitter;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
 import org.apache.brooklyn.launcher.config.StopWhichAppsOnShutdown;
 import org.apache.brooklyn.location.core.PortRanges;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation.LocalhostMachine;
@@ -107,6 +93,16 @@ import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
 /**
  * Example usage is:
@@ -172,6 +168,7 @@ public class BrooklynLauncher {
     private Duration haHeartbeatPeriodOverride = null;
     
     private volatile BrooklynWebServer webServer;
+    @SuppressWarnings("unused")
     private CampPlatform campPlatform;
 
     private boolean started;
@@ -916,7 +913,7 @@ public class BrooklynLauncher {
             apps.add(app);
         }
         for (String blueprint : yamlAppsToManage) {
-            Application app = getAppFromYaml(blueprint);
+            Application app = EntityManagementUtils.createUnstarted(managementContext, blueprint);
             // Note: BrooklynAssemblyTemplateInstantiator automatically puts applications under management.
             apps.add(app);
         }
@@ -956,23 +953,6 @@ public class BrooklynLauncher {
                 .start(ImmutableList.of(localhost));
     }
 
-    protected Application getAppFromYaml(String input) {
-        AssemblyTemplate at = campPlatform.pdp().registerDeploymentPlan(new StringReader(input));
-        BrooklynAssemblyTemplateInstantiator instantiator;
-        try {
-            AssemblyTemplateInstantiator ati = at.getInstantiator().newInstance();
-            if (ati instanceof BrooklynAssemblyTemplateInstantiator) {
-                instantiator = BrooklynAssemblyTemplateInstantiator.class.cast(ati);
-            } else {
-                throw new IllegalStateException("Cannot create application with instantiator: " + ati);
-            }
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-        Application app = instantiator.create(at, campPlatform);
-        return app;
-    }
-    
     protected void startApps() {
         if ((stopWhichAppsOnShutdown==StopWhichAppsOnShutdown.ALL) || 
             (stopWhichAppsOnShutdown==StopWhichAppsOnShutdown.ALL_IF_NOT_PERSISTED && persistMode==PersistMode.DISABLED)) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
index edeedaa..2df17f3 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
@@ -144,8 +144,4 @@ public abstract class AbstractBrooklynRestResource implements ManagementContextI
 
     }
 
-    protected CampPlatform camp() {
-        return BrooklynServerConfig.getCampPlatform(mgmt()).get();
-    }
-    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 84e5190..dcb8b74 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -23,7 +23,6 @@ import static javax.ws.rs.core.Response.created;
 import static javax.ws.rs.core.Response.status;
 import static javax.ws.rs.core.Response.Status.ACCEPTED;
 
-import java.io.StringReader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Collection;
@@ -37,19 +36,14 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.UriInfo;
 
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.node.ArrayNode;
-import org.codehaus.jackson.node.ObjectNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 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.entity.Group;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
@@ -65,7 +59,6 @@ import org.apache.brooklyn.entity.trait.Startable;
 import org.apache.brooklyn.rest.api.ApplicationApi;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;
 import org.apache.brooklyn.rest.domain.ApplicationSummary;
-import org.apache.brooklyn.rest.domain.EntitySpec;
 import org.apache.brooklyn.rest.domain.EntitySummary;
 import org.apache.brooklyn.rest.domain.TaskSummary;
 import org.apache.brooklyn.rest.filter.HaHotStateRequired;
@@ -79,6 +72,11 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.node.ArrayNode;
+import org.codehaus.jackson.node.ObjectNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Throwables;
 import com.google.common.collect.FluentIterable;
@@ -274,28 +272,32 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
         }
 
         log.debug("Creating app from yaml:\n{}", yaml);
-        AssemblyTemplate at = camp().pdp().registerDeploymentPlan( new StringReader(yaml) );
+        EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpec(mgmt(), yaml);
         
-        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION, at)) {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION, spec)) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
                 Entitlements.getEntitlementContext().user(), yaml);
         }
 
-        return launch(at);
+        return launch(yaml, spec);
     }
 
-    private Response launch(AssemblyTemplate at) {
+    private Response launch(String yaml, EntitySpec<? extends Application> spec) {
         try {
-            CreationResult<? extends Application, Void> result = EntityManagementUtils.createStarting(mgmt(), at);
+            Application app = EntityManagementUtils.createUnstarted(mgmt(), spec);
+            CreationResult<Application,Void> result = EntityManagementUtils.start(app);
             
-            Application app = result.get();
-            if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, 
-                StringAndArgument.of(Startable.START.getName(), null)))) {
+            boolean isEntitled = Entitlements.isEntitled(
+                    mgmt().getEntitlementManager(),
+                    Entitlements.INVOKE_EFFECTOR,
+                    EntityAndItem.of(app, StringAndArgument.of(Startable.START.getName(), null)));
+
+            if (!isEntitled) {
                 throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
-                    Entitlements.getEntitlementContext().user(), at.getType());
+                    Entitlements.getEntitlementContext().user(), spec.getType());
             }
 
-            log.info("Launched from YAML: " + at + " -> " + app + " (" + result.task() + ")");
+            log.info("Launched from YAML: " + yaml + " -> " + app + " (" + result.task() + ")");
 
             URI ref = URI.create(app.getApplicationId());
             ResponseBuilder response = created(ref);
@@ -316,6 +318,9 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
         // attempt legacy format
         try {
             ApplicationSpec appSpec = mapper().readValue(inputToAutodetectType, ApplicationSpec.class);
+            if (appSpec.getType() != null || appSpec.getEntities() != null) {
+                looksLikeLegacy = true;
+            }
             return createFromAppSpec(appSpec);
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
@@ -323,39 +328,19 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
             log.debug("Input is not legacy ApplicationSpec JSON (will try others): "+e, e);
         }
 
-        AssemblyTemplate template = null;
-        boolean looksLikeYaml = false;
-        try {
-            template = camp().pdp().registerDeploymentPlan(new StringReader(new String(inputToAutodetectType)));
-            if (!template.getPlatformComponentTemplates().isEmpty() || !template.getApplicationComponentTemplates().isEmpty()) {
-                looksLikeYaml = true;
-            } else {
-                if (template.getCustomAttributes().containsKey("type") || template.getCustomAttributes().containsKey("entities")) {
-                    looksLikeLegacy = true;
-                }
-            }
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            log.debug("Input is not valid YAML: "+e);
-        }
+        //TODO infer encoding from request
+        String potentialYaml = new String(inputToAutodetectType);
+        EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpec(mgmt(), potentialYaml);
 
         // TODO not json - try ZIP, etc
 
-        if (template!=null) {
-            try {
-                return launch(template);
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                if (looksLikeYaml)
-                    throw Exceptions.propagate(e);
-            }
-        }
-
-        if ((looksLikeLegacy || !looksLikeYaml) && legacyFormatException!=null)
-            // throw the error from legacy creation if it looks like it was the legacy format
+        if (spec != null) {
+            return launch(potentialYaml, spec);
+        } else if (looksLikeLegacy) {
             throw Throwables.propagate(legacyFormatException);
-
-        return Response.serverError().entity("Unsupported format; not able to autodetect.").build();
+        } else {
+            return Response.serverError().entity("Unsupported format; not able to autodetect.").build();
+        }
     }
 
     @Override
@@ -388,7 +373,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
             return;
         }
 
-        for (EntitySpec entitySpec : applicationSpec.getEntities()) {
+        for (org.apache.brooklyn.rest.domain.EntitySpec entitySpec : applicationSpec.getEntities()) {
             String entityType = entitySpec.getType();
             checkEntityTypeIsValid(checkNotNull(entityType, "entityType"));
         }
@@ -458,4 +443,4 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
         return result;
     }
 
-}
\ No newline at end of file
+}


[3/4] incubator-brooklyn git commit: code review comments on pluggable yaml -- tidy-up of generics and javadoc mainly

Posted by he...@apache.org.
code review comments on pluggable yaml -- tidy-up of generics and javadoc mainly


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

Branch: refs/heads/master
Commit: a47d5aaa5e4b8794f81e547c29742db3b751e71e
Parents: 6ed695e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Aug 19 15:34:27 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Aug 19 15:34:27 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/core/mgmt/EntityManagementUtils.java |  3 ++-
 .../core/plan/PlanNotRecognizedException.java     |  5 +----
 .../brooklyn/core/plan/PlanToSpecTransformer.java | 18 ++++++++++++++++--
 .../brooklyn/spi/creation/CampCatalogUtils.java   |  2 +-
 .../spi/creation/CampToSpecTransformer.java       |  5 +++--
 5 files changed, 23 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a47d5aaa/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index 1b150f1..4d37824 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -95,11 +95,12 @@ public class EntityManagementUtils {
         throw new PlanNotRecognizedException("Invalid plan, tried parsing with " + types);
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     public static AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(ManagementContext mgmt, CatalogItem<?, ?> item) {
         Collection<String> types = new ArrayList<String>();
         for (PlanToSpecTransformer c : PlanToSpecFactory.all(mgmt)) {
             try {
-                return c.createCatalogSpec(item);
+                return c.createCatalogSpec((CatalogItem)item);
             } catch (PlanNotRecognizedException e) {
                 types.add(c.getName());
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a47d5aaa/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
index 2551220..4d62d4a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
@@ -19,11 +19,8 @@
 package org.apache.brooklyn.core.plan;
 
 public class PlanNotRecognizedException extends RuntimeException {
-    private static final long serialVersionUID = 1L;
 
-    public PlanNotRecognizedException() {
-        super();
-    }
+    private static final long serialVersionUID = -5590108442839125317L;
 
     public PlanNotRecognizedException(String message, Throwable cause) {
         super(message, cause);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a47d5aaa/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
index 13cd3bb..66f1b62 100644
--- a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
@@ -18,6 +18,8 @@
  */
 package org.apache.brooklyn.core.plan;
 
+import java.util.ServiceLoader;
+
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.EntitySpec;
@@ -26,10 +28,22 @@ import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
 
 import com.google.common.annotations.Beta;
 
+/** Pluggable {@link ServiceLoader} interface for defferent plan-interpreters.
+ * Implementations should take a plan and return an {@link EntitySpec}.
+ */
+@Beta
 public interface PlanToSpecTransformer extends ManagementContextInjectable {
+    
+    /** Human-readable name for this transformer */
     String getName();
-    @Beta
+    
+    /** whether this accepts the given MIME format */
     boolean accepts(String mime);
+    
+    /** creates an {@link EntitySpec} given a plan, according to the transformation rules this understands */
     <T extends Application> EntitySpec<T> createApplicationSpec(String plan);
-    AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(CatalogItem<?, ?> item);
+    
+    /** creates an object spec given a catalog item, according to the transformation rules this understands */
+    <T,SpecT extends AbstractBrooklynObjectSpec<T, SpecT>> AbstractBrooklynObjectSpec<T, SpecT> createCatalogSpec(CatalogItem<T, SpecT> item);
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a47d5aaa/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
index 71aded1..59557bb 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
@@ -39,7 +39,6 @@ import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate;
 import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
-import org.apache.brooklyn.camp.util.yaml.Yamls;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
@@ -49,6 +48,7 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.yaml.Yamls;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a47d5aaa/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
index 7650a9b..abf3200 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java
@@ -78,9 +78,10 @@ public class CampToSpecTransformer implements PlanToSpecTransformer {
       }
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
-    public AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(CatalogItem<?, ?> item) {
-        return CampCatalogUtils.createSpec(mgmt, item);
+    public <T, SpecT extends AbstractBrooklynObjectSpec<T, SpecT>> AbstractBrooklynObjectSpec<T, SpecT> createCatalogSpec(CatalogItem<T, SpecT> item) {
+        return (AbstractBrooklynObjectSpec<T, SpecT>) CampCatalogUtils.createSpec(mgmt, (CatalogItem)item);
     }
 
     @Override


[2/4] incubator-brooklyn git commit: This closes #760. Makes YAML pluggable.

Posted by he...@apache.org.
This closes #760. Makes YAML pluggable.

I've done effectively a rebase-resolve-squash on the commits from that PR. Doing a formal rebase was very hard due to all the conflicts.

This uses a ServiceLoader to get CAMP stuff, with a list of transformers supported.

For the record the commit log of #760, squashed here, is:

> commit f7067c2c10942cfea15ecbe0cb4e8e31e8fb6cde
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Tue Jul 21 17:25:15 2015 +0300
>
>     Use plugins to parse yaml plans
>
>     Move all CAMP related code to a CAMP implementation of the plugin.
>
> commit c9db2547e1fd0e16b23cb09f04f4cffe6db01ad8
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Tue Jul 21 15:01:51 2015 +0300
>
>     Decrease API surface in CampCatalogUtils
>
> commit 4e24d5f93d250dbbbcf579f2a406f63e1c315798
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Tue Jul 21 13:17:42 2015 +0300
>
>     Deduplicate code
>
> commit a953e059066aa53323db0ed027366a4b5994ecfc
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Mon Jul 20 18:55:18 2015 +0300
>
>     Move all CAMP-related code to a single place - brooklyn-launcher
>
>     Use existing utils methods wrapping CAMP calls - in EntityManagementUtils.
>
> commit dc4b37f6c07337171b61ab25beb9bcea617d9452
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Mon Jul 20 16:36:32 2015 +0300
>
>     Move all CAMP-related code to a single place - brooklyn-rest-server
>
>     Use existing utils methods wrapping CAMP calls - in EntityManagementUtils.
>
> commit 3b8bc66c35ba84db158f2018b967bf501f5811c8
> Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
> Date:   Mon Jul 20 16:02:36 2015 +0300
>
>     Move all CAMP-related code to a single place - brooklyn-core
>
>     EntityManagementUtils and CampCatalogUtils interface to the CAMP parser now.
>


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

Branch: refs/heads/master
Commit: 6ed695e51bfda4478187d4a12ab28149caa4914c
Parents: 0f6041e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Aug 19 11:02:12 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Aug 19 13:48:36 2015 +0100

----------------------------------------------------------------------
 core/pom.xml                                    |  16 +-
 .../api/AssemblyTemplateSpecInstantiator.java   |  35 ---
 .../catalog/internal/BasicBrooklynCatalog.java  | 243 +++---------------
 .../core/mgmt/EntityManagementUtils.java        | 200 ++++++---------
 .../core/plan/PlanNotRecognizedException.java   |  40 +++
 .../brooklyn/core/plan/PlanToSpecFactory.java   |  46 ++++
 .../core/plan/PlanToSpecTransformer.java        |  35 +++
 .../core/server/BrooklynServerConfig.java       |  14 -
 .../core/mgmt/rebind/RebindCatalogItemTest.java |  93 ++++---
 ...talogWhenCatalogPersistenceDisabledTest.java |   8 +-
 .../lite/CampPlatformWithJustBrooklynMgmt.java  |  41 ---
 .../camp/brooklyn/lite/CampYamlLiteTest.java    | 255 -------------------
 .../camp/brooklyn/lite/TestAppAssembly.java     |  36 ---
 .../lite/TestAppAssemblyInstantiator.java       |  90 -------
 .../lite/test-app-service-blueprint.yaml        |  38 ---
 usage/camp/pom.xml                              |  12 +
 .../camp/brooklyn/BrooklynCampConstants.java    |   3 +-
 .../api/AssemblyTemplateSpecInstantiator.java   |  35 +++
 .../BrooklynAssemblyTemplateInstantiator.java   |  51 ++--
 .../BrooklynComponentTemplateResolver.java      |  12 +-
 .../brooklyn/spi/creation/CampCatalogUtils.java | 244 ++++++++++++++++++
 .../spi/creation/CampToSpecTransformer.java     |  91 +++++++
 ...che.brooklyn.core.plan.PlanToSpecTransformer |  19 ++
 .../brooklyn/catalog/CatalogYamlCombiTest.java  |   7 +-
 .../lite/CampPlatformWithJustBrooklynMgmt.java  |  41 +++
 .../brooklyn/test/lite/CampYamlLiteTest.java    | 254 ++++++++++++++++++
 .../brooklyn/test/lite/TestAppAssembly.java     |  36 +++
 .../test/lite/TestAppAssemblyInstantiator.java  |  90 +++++++
 .../test/lite/test-app-service-blueprint.yaml   |  38 +++
 .../brooklyn/launcher/BrooklynLauncher.java     |  46 +---
 .../resources/AbstractBrooklynRestResource.java |   4 -
 .../rest/resources/ApplicationResource.java     |  83 +++---
 32 files changed, 1252 insertions(+), 1004 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 1c8565a..f38b995 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -54,18 +54,6 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.brooklyn.camp</groupId>
-            <artifactId>camp-base</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.brooklyn.camp</groupId>
-            <artifactId>camp-base</artifactId>
-            <version>${project.version}</version>
-            <classifier>tests</classifier>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>io.cloudsoft.windows</groupId>
             <artifactId>winrm4j</artifactId>
             <version>${winrm4j.version}</version>
@@ -172,6 +160,10 @@
             <groupId>com.maxmind.geoip2</groupId>
             <artifactId>geoip2</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>org.testng</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java b/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
deleted file mode 100644
index c345a9d..0000000
--- a/core/src/main/java/org/apache/brooklyn/camp/brooklyn/api/AssemblyTemplateSpecInstantiator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.camp.brooklyn.api;
-
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.camp.CampPlatform;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-
-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/6ed695e5/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index 4fd7878..23d37ba 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -30,27 +30,19 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.yaml.snakeyaml.Yaml;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
-import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.camp.CampPlatform;
-import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
 import org.apache.brooklyn.core.catalog.CatalogPredicates;
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
@@ -64,12 +56,14 @@ import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.AggregateClassLoader;
 import org.apache.brooklyn.util.javalang.LoadedClassLoader;
 import org.apache.brooklyn.util.javalang.Reflections;
-import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
 import org.apache.brooklyn.util.yaml.Yamls;
 import org.apache.brooklyn.util.yaml.Yamls.YamlExtract;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
 
 import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
@@ -84,8 +78,8 @@ import com.google.common.collect.Iterables;
 /* TODO the complex tree-structured catalogs are only useful when we are relying on those separate catalog classloaders
  * to isolate classpaths. with osgi everything is just put into the "manual additions" catalog. */
 public class BasicBrooklynCatalog implements BrooklynCatalog {
-    private static final String POLICIES_KEY = "brooklyn.policies";
-    private static final String LOCATIONS_KEY = "brooklyn.locations";
+    public static final String POLICIES_KEY = "brooklyn.policies";
+    public static final String LOCATIONS_KEY = "brooklyn.locations";
     public static final String NO_VERSION = "0.0.0.SNAPSHOT";
 
     private static final Logger log = LoggerFactory.getLogger(BasicBrooklynCatalog.class);
@@ -321,45 +315,20 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         }
     }
 
-    @SuppressWarnings("unchecked")
     @Override
     public <T, SpecT> SpecT createSpec(CatalogItem<T, SpecT> item) {
         if (item == null) return null;
+        @SuppressWarnings("unchecked")
         CatalogItemDo<T,SpecT> loadedItem = (CatalogItemDo<T, SpecT>) getCatalogItemDo(item.getSymbolicName(), item.getVersion());
         if (loadedItem == null) throw new RuntimeException(item+" not in catalog; cannot create spec");
         Class<SpecT> specType = loadedItem.getSpecType();
         if (specType==null) return null;
 
-        String yaml = loadedItem.getPlanYaml();
-
-        if (yaml!=null) {
-            // preferred way is to parse the yaml, to resolve references late;
-            // the parsing on load is to populate some fields, but it is optional.
-            // TODO messy for location and policy that we need brooklyn.{locations,policies} root of the yaml, but it works;
-            // see related comment when the yaml is set, in addAbstractCatalogItems
-            // (not sure if anywhere else relies on that syntax; if not, it should be easy to fix!)
-            DeploymentPlan plan = makePlanFromYaml(yaml);
-            BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, item);
-            SpecT spec;
-            switch (item.getCatalogItemType()) {
-                case TEMPLATE:
-                case ENTITY:
-                    spec = createEntitySpec(loadedItem.getSymbolicName(), plan, loader);
-                    break;
-                case POLICY:
-                    spec = createPolicySpec(loadedItem.getSymbolicName(), plan, loader);
-                    break;
-                case LOCATION:
-                    spec = createLocationSpec(plan, loader);
-                    break;
-                default: throw new RuntimeException("Only entity, policy & location catalog items are supported. Unsupported catalog item type " + item.getCatalogItemType());
+        if (loadedItem.getPlanYaml() != null) {
+            SpecT yamlSpec = (SpecT) EntityManagementUtils.createCatalogSpec(mgmt, loadedItem);
+            if (yamlSpec != null) {
+                return yamlSpec;
             }
-            ((AbstractBrooklynObjectSpec<?, ?>)spec).catalogItemId(item.getId());
-            
-            if (Strings.isBlank( ((AbstractBrooklynObjectSpec<?, ?>)spec).getDisplayName() ))
-                ((AbstractBrooklynObjectSpec<?, ?>)spec).displayName(item.getDisplayName());
-            
-            return spec;
         }
 
         // revert to legacy mechanism
@@ -373,6 +342,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         }
         try {
             if (loadedItem.getJavaType()!=null) {
+                @SuppressWarnings("unchecked")
                 SpecT specT = (SpecT) method.invoke(null, loadedItem.loadJavaClass(mgmt));
                 spec = specT;
             }
@@ -387,154 +357,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         return spec;
     }
 
-    private <T, SpecT> SpecT createSpec(String optionalId, CatalogItemType ciType, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
-        Preconditions.checkNotNull(ciType, "catalog item type for "+plan); 
-        switch (ciType) {
-        case TEMPLATE:
-        case ENTITY: 
-            return createEntitySpec(optionalId, plan, loader);
-        case LOCATION: return createLocationSpec(plan, loader);
-        case POLICY: return createPolicySpec(optionalId, plan, loader);
-        }
-        throw new IllegalStateException("Unknown CI Type "+ciType+" for "+plan);
-    }
-    
-    @SuppressWarnings("unchecked")
-    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
-        AssemblyTemplate at;
-        BrooklynLoaderTracker.setLoader(loader);
-        try {
-            at = camp.pdp().registerDeploymentPlan(plan);
-        } finally {
-            BrooklynLoaderTracker.unsetLoader(loader);
-        }
-
-        try {
-            AssemblyTemplateInstantiator instantiator = at.getInstantiator().newInstance();
-            if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-                return (SpecT) ((AssemblyTemplateSpecInstantiator)instantiator).createNestedSpec(at, camp, loader, 
-                    getInitialEncounteredSymbol(symbolicName));
-            }
-            throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    private MutableSet<String> getInitialEncounteredSymbol(String symbolicName) {
-        return symbolicName==null ? MutableSet.<String>of() : MutableSet.of(symbolicName);
-    }
-
-    private <T, SpecT> SpecT createPolicySpec(String symbolicName, DeploymentPlan plan, BrooklynClassLoadingContext loader) {
-        return createPolicySpec(plan, loader, getInitialEncounteredSymbol(symbolicName));
-    }
-
-    private <T, SpecT> SpecT createPolicySpec(DeploymentPlan plan, BrooklynClassLoadingContext loader, Set<String> encounteredCatalogTypes) {
-        //Would ideally re-use org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver.PolicySpecResolver
-        //but it is CAMP specific and there is no easy way to get hold of it.
-        Object policies = checkNotNull(plan.getCustomAttributes().get(POLICIES_KEY), "policy config");
-        if (!(policies instanceof Iterable<?>)) {
-            throw new IllegalStateException("The value of " + POLICIES_KEY + " must be an Iterable.");
-        }
-
-        Object policy = Iterables.getOnlyElement((Iterable<?>)policies);
-
-        return createPolicySpec(loader, policy, encounteredCatalogTypes);
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T, SpecT> SpecT createPolicySpec(BrooklynClassLoadingContext loader, Object policy, Set<String> encounteredCatalogTypes) {
-        Map<String, Object> itemMap;
-        if (policy instanceof String) {
-            itemMap = ImmutableMap.<String, Object>of("type", policy);
-        } else if (policy instanceof Map) {
-            itemMap = (Map<String, Object>) policy;
-        } else {
-            throw new IllegalStateException("Policy expected to be string or map. Unsupported object type " + policy.getClass().getName() + " (" + policy.toString() + ")");
-        }
-
-        String versionedId = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "policy_type", "policyType", "type"), "policy type");
-        PolicySpec<? extends Policy> spec;
-        CatalogItem<?, ?> policyItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt, versionedId);
-        if (policyItem != null && !encounteredCatalogTypes.contains(policyItem.getSymbolicName())) {
-            if (policyItem.getCatalogItemType() != CatalogItemType.POLICY) {
-                throw new IllegalStateException("Non-policy catalog item in policy context: " + policyItem);
-            }
-            //TODO re-use createSpec
-            BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, policyItem);
-            if (policyItem.getPlanYaml() != null) {
-                DeploymentPlan plan = makePlanFromYaml(policyItem.getPlanYaml());
-                encounteredCatalogTypes.add(policyItem.getSymbolicName());
-                return createPolicySpec(plan, itemLoader, encounteredCatalogTypes);
-            } else if (policyItem.getJavaType() != null) {
-                spec = PolicySpec.create((Class<Policy>)itemLoader.loadClass(policyItem.getJavaType()));
-            } else {
-                throw new IllegalStateException("Invalid policy item - neither yaml nor javaType: " + policyItem);
-            }
-        } else {
-            spec = PolicySpec.create(loader.loadClass(versionedId, Policy.class));
-        }
-        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
-        if (brooklynConfig != null) {
-            spec.configure(brooklynConfig);
-        }
-        return (SpecT) spec;
-    }
-    
-    private <T, SpecT> SpecT createLocationSpec(DeploymentPlan plan, BrooklynClassLoadingContext loader) {
-        // See #createPolicySpec; this impl is modeled on that.
-        // spec.catalogItemId is set by caller
-        Object locations = checkNotNull(plan.getCustomAttributes().get(LOCATIONS_KEY), "location config");
-        if (!(locations instanceof Iterable<?>)) {
-            throw new IllegalStateException("The value of " + LOCATIONS_KEY + " must be an Iterable.");
-        }
-
-        Object location = Iterables.getOnlyElement((Iterable<?>)locations);
-
-        return createLocationSpec(loader, location); 
-    }
-
-    @SuppressWarnings("unchecked")
-    private <T, SpecT> SpecT createLocationSpec(BrooklynClassLoadingContext loader, Object location) {
-        Map<String, Object> itemMap;
-        if (location instanceof String) {
-            itemMap = ImmutableMap.<String, Object>of("type", location);
-        } else if (location instanceof Map) {
-            itemMap = (Map<String, Object>) location;
-        } else {
-            throw new IllegalStateException("Location expected to be string or map. Unsupported object type " + location.getClass().getName() + " (" + location.toString() + ")");
-        }
-
-        String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type");
-        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
-        Maybe<Class<? extends Location>> javaClass = loader.tryLoadClass(type, Location.class);
-        if (javaClass.isPresent()) {
-            LocationSpec<?> spec = LocationSpec.create(javaClass.get());
-            if (brooklynConfig != null) {
-                spec.configure(brooklynConfig);
-            }
-            return (SpecT) spec;
-        } else {
-            Maybe<Location> loc = mgmt.getLocationRegistry().resolve(type, false, brooklynConfig);
-            if (loc.isPresent()) {
-                // TODO extensions?
-                Map<String, Object> locConfig = ((ConfigurationSupportInternal)loc.get().config()).getBag().getAllConfig();
-                Class<? extends Location> locType = loc.get().getClass();
-                Set<Object> locTags = loc.get().tags().getTags();
-                String locDisplayName = loc.get().getDisplayName();
-                return (SpecT) LocationSpec.create(locType)
-                        .configure(locConfig)
-                        .displayName(locDisplayName)
-                        .tags(locTags);
-            } else {
-                throw new IllegalStateException("No class or resolver found for location type "+type);
-            }
-        }
-    }
-
     @SuppressWarnings("unchecked")
     @Override
     /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
@@ -683,7 +505,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         else sourceYaml = new Yaml().dump(item);
         
         CatalogItemType itemType = TypeCoercions.coerce(getFirstAs(catalogMetadata, Object.class, "itemType", "item_type").orNull(), CatalogItemType.class);
-        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, "<load>:0", libraryBundles);
 
         String id = getFirstAs(catalogMetadata, String.class, "id").orNull();
         String version = getFirstAs(catalogMetadata, String.class, "version").orNull();
@@ -697,7 +518,7 @@ 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();
+        PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, libraryBundles, 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>")
@@ -785,7 +606,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         final Boolean catalogDeprecated = Boolean.valueOf(deprecated);
 
         // run again now that we know the ID
-        planInterpreter = new PlanInterpreterGuessingType(id, item, sourceYaml, itemType, loader, result).reconstruct();
+        planInterpreter = new PlanInterpreterGuessingType(id, item, sourceYaml, itemType, libraryBundles, result).reconstruct();
         if (!planInterpreter.isResolved()) {
             throw new IllegalStateException("Could not resolve plan once id and itemType are known (recursive reference?): "+sourceYaml);
         }
@@ -861,19 +682,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         final String id;
         final Map<?,?> item;
         final String itemYaml;
-        final BrooklynClassLoadingContext loader;
+        final Collection<CatalogBundle> libraryBundles;
         final List<CatalogItemDtoAbstract<?, ?>> itemsDefinedSoFar;
         
         CatalogItemType catalogItemType;
         String planYaml;
-        @SuppressWarnings("unused")
-        DeploymentPlan plan;
-        AbstractBrooklynObjectSpec<?,?> spec;
         boolean resolved = false;
         List<Exception> errors = MutableList.of();
         
         public PlanInterpreterGuessingType(@Nullable String id, Object item, String itemYaml, @Nullable CatalogItemType optionalCiType, 
-                BrooklynClassLoadingContext loader, List<CatalogItemDtoAbstract<?,?>> itemsDefinedSoFar) {
+                Collection<CatalogBundle> libraryBundles, List<CatalogItemDtoAbstract<?,?>> itemsDefinedSoFar) {
             // ID is useful to prevent recursive references (currently for entities only)
             this.id = id;
             
@@ -886,7 +704,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                 this.itemYaml = itemYaml;
             }
             this.catalogItemType = optionalCiType;
-            this.loader = loader;
+            this.libraryBundles = libraryBundles;
             this.itemsDefinedSoFar = itemsDefinedSoFar;
         }
 
@@ -964,11 +782,13 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
             
             // then try parsing plan - this will use loader
             try {
-                DeploymentPlan candidatePlan = makePlanFromYaml(candidateYaml);
-                spec = createSpec(id, candidateCiType, candidatePlan, loader);
+                CatalogItem<?, ?> itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
+                    .plan(candidateYaml)
+                    .libraries(libraryBundles)
+                    .build();
+                Object spec = EntityManagementUtils.createCatalogSpec(mgmt, itemToAttempt);
                 if (spec!=null) {
                     catalogItemType = candidateCiType;
-                    plan = candidatePlan;
                     planYaml = candidateYaml;
                     resolved = true;
                 }
@@ -994,8 +814,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
             if (type!=null && key!=null) {
                 try {
                     String cutDownYaml = key + ":\n" + makeAsIndentedList("type: "+type);
-                    DeploymentPlan candidatePlan = makePlanFromYaml(cutDownYaml);
-                    Object cutdownSpec = createSpec(id, candidateCiType, candidatePlan, loader);
+                    CatalogItem<?, ?> itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
+                            .plan(cutDownYaml)
+                            .libraries(libraryBundles)
+                            .build();
+                    Object cutdownSpec = EntityManagementUtils.createCatalogSpec(mgmt, itemToAttempt);
                     if (cutdownSpec!=null) {
                         catalogItemType = candidateCiType;
                         planYaml = candidateYaml;
@@ -1006,9 +829,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                     Exceptions.propagateIfFatal(e);
                 }
             }
+            // FIXME we should lookup type in the catalog on its own, then infer the type from that,
+            // and give proper errors (right now e.g. if there are no transformers then we bail out 
+            // with very little information)
             
             return false;
         }
+
+        private String getIdWithRandomDefault() {
+            return id != null ? id : Strings.makeRandomId(10);
+        }
         public Map<?,?> getItem() {
             return item;
         }
@@ -1057,11 +887,6 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
 //        return !isEntityPlan(plan) && plan.getCustomAttributes().containsKey(LOCATIONS_KEY);
 //    }
 
-    private DeploymentPlan makePlanFromYaml(String yaml) {
-        CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
-        return camp.pdp().parseDeploymentPlan(Streams.newReaderWithContents(yaml));
-    }
-
     //------------------------
     
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index d7ce547..1b150f1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -18,29 +18,27 @@
  */
 package org.apache.brooklyn.core.mgmt;
 
-import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 import java.util.concurrent.Callable;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.api.catalog.CatalogItem;
 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.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.internal.EntityLocal;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.camp.CampPlatform;
-import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
-import org.apache.brooklyn.camp.spi.Assembly;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
-import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.core.plan.PlanNotRecognizedException;
+import org.apache.brooklyn.core.plan.PlanToSpecFactory;
+import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
 import org.apache.brooklyn.effector.core.Effectors;
 import org.apache.brooklyn.entity.core.Entities;
 import org.apache.brooklyn.entity.core.EntityFunctions;
@@ -49,17 +47,17 @@ import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
 
 /** Utility methods for working with entities and applications */
 public class EntityManagementUtils {
@@ -79,55 +77,36 @@ public class EntityManagementUtils {
         return app;
     }
 
-    /** convenience for accessing camp */
-    public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) {
-        return BrooklynServerConfig.getCampPlatform(mgmt);
-    }
-    
-    /** as {@link #createApplication(ManagementContext, EntitySpec)} but for a YAML spec */
+    /** as {@link #createUnstarted(ManagementContext, EntitySpec)} but for a YAML spec */
     public static <T extends Application> T createUnstarted(ManagementContext mgmt, String yaml) {
-        AssemblyTemplate at = getCampPlatform(mgmt).get().pdp().registerDeploymentPlan( new StringReader(yaml) );
-        return createUnstarted(mgmt, at);
+        EntitySpec<T> spec = createEntitySpec(mgmt, yaml);
+        return createUnstarted(mgmt, spec);
     }
     
-    /** as {@link #createApplication(ManagementContext, EntitySpec)} but for an assembly template */
-    @SuppressWarnings("unchecked")
-    public static <T extends Application> T createUnstarted(ManagementContext mgmt, AssemblyTemplate at) {
-        CampPlatform camp = getCampPlatform(mgmt).get();
-        AssemblyTemplateInstantiator instantiator;
-        try {
-            instantiator = at.getInstantiator().newInstance();
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
+    public static <T extends Application> EntitySpec<T> createEntitySpec(ManagementContext mgmt, String yaml) {
+        Collection<String> types = new ArrayList<String>();
+        for (PlanToSpecTransformer c : PlanToSpecFactory.all(mgmt)) {
+            try {
+                return c.createApplicationSpec(yaml);
+            } catch (PlanNotRecognizedException e) {
+                types.add(c.getName());
+            }
         }
-        Assembly assembly;
-        if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
-            
-            EntitySpec<?> spec = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, true);
-            Entity app = mgmt.getEntityManager().createEntity(spec);
-            Entities.startManagement((Application)app, mgmt);
-            return (T) app;
-        } else {
-            // currently, all brooklyn plans should produce the above; currently this will always throw Unsupported  
+        throw new PlanNotRecognizedException("Invalid plan, tried parsing with " + types);
+    }
+
+    public static AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(ManagementContext mgmt, CatalogItem<?, ?> item) {
+        Collection<String> types = new ArrayList<String>();
+        for (PlanToSpecTransformer c : PlanToSpecFactory.all(mgmt)) {
             try {
-                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) {
-                Exceptions.propagateIfFatal(e);
-                throw new IllegalArgumentException("Invalid plan: "+at, e);
+                return c.createCatalogSpec(item);
+            } catch (PlanNotRecognizedException e) {
+                types.add(c.getName());
             }
         }
+        throw new PlanNotRecognizedException("Invalid plan, tried parsing with " + types);
     }
-    
+
     /** container for operation which creates something and which wants to return both
      * the items created and any pending create/start task */
     public static class CreationResult<T,U> {
@@ -159,10 +138,6 @@ public class EntityManagementUtils {
         return start(createUnstarted(mgmt, appSpec));
     }
 
-    public static CreationResult<? extends Application,Void> createStarting(ManagementContext mgmt, AssemblyTemplate at) {
-        return start(createUnstarted(mgmt, at));
-    }
-
     public static <T extends Application> CreationResult<T,Void> start(T app) {
         Task<Void> task = Entities.invokeEffector((EntityLocal)app, app, Startable.START,
             // locations already set in the entities themselves;
@@ -180,51 +155,37 @@ public class EntityManagementUtils {
     /** adds entities from the given yaml, under the given parent; but does not start them */
     public static List<Entity> addChildrenUnstarted(final EntityLocal parent, String yaml) {
         log.debug("Creating child of "+parent+" from yaml:\n{}", yaml);
-        
+
         ManagementContext mgmt = parent.getApplication().getManagementContext();
-        CampPlatform camp = BrooklynServerConfig.getCampPlatform(mgmt).get();
-        
-        AssemblyTemplate at = camp.pdp().registerDeploymentPlan( new StringReader(yaml) );
 
-        AssemblyTemplateInstantiator instantiator;
-        try {
-            instantiator = at.getInstantiator().newInstance();
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-        if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
-            EntitySpec<?> specA = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, false);
+        EntitySpec<?> specA = createEntitySpec(mgmt, yaml);
 
-            // see whether we can promote children
-            List<EntitySpec<?>> specs = MutableList.of();
-            if (hasNoNameOrCustomKeysOrRoot(at, specA)) {
-                // we can promote
-                for (EntitySpec<?> specC: specA.getChildren()) {
-                    collapseSpec(specA, specC);
-                    specs.add(specC);
-                }
-            } else {
-                // if not promoting, set a nice name if needed
-                if (Strings.isEmpty(specA.getDisplayName())) {
-                    int size = specA.getChildren().size();
-                    String childrenCountString = size+" "+(size!=1 ? "children" : "child");
-                    specA.displayName("Dynamically added "+childrenCountString);
-                }
-                specs.add(specA);
+        // see whether we can promote children
+        List<EntitySpec<?>> specs = MutableList.of();
+        if (canPromote(specA)) {
+            // we can promote
+            for (EntitySpec<?> specC: specA.getChildren()) {
+                collapseSpec(specA, specC);
+                specs.add(specC);
             }
-
-            final List<Entity> children = MutableList.of();
-            for (EntitySpec<?> spec: specs) {
-                Entity child = (Entity)parent.addChild(spec);
-                Entities.manage(child);
-                children.add(child);
-            }
-            
-            return children;
         } else {
-            throw new IllegalStateException("Spec could not be parsed to supply a compatible instantiator");
+            // if not promoting, set a nice name if needed
+            if (Strings.isEmpty(specA.getDisplayName())) {
+                int size = specA.getChildren().size();
+                String childrenCountString = size+" "+(size!=1 ? "children" : "child");
+                specA.displayName("Dynamically added "+childrenCountString);
+            }
+            specs.add(specA);
         }
+
+        final List<Entity> children = MutableList.of();
+        for (EntitySpec<?> spec: specs) {
+            Entity child = (Entity)parent.addChild(spec);
+            Entities.manage(child);
+            children.add(child);
+        }
+
+        return children;
     }
 
     public static CreationResult<List<Entity>,List<String>> addChildrenStarting(final EntityLocal parent, String yaml) {
@@ -273,7 +234,8 @@ public class EntityManagementUtils {
 
         // NB: this clobbers child config; might prefer to deeply merge maps etc
         // (but this should not be surprising, as unwrapping is often parameterising the nested blueprint, so outer config should dominate) 
-        targetToBeExpanded.configure(sourceToBeCollapsed.getConfig());
+        Map<ConfigKey<?>, Object> configWithoutWrapperMarker = Maps.filterKeys(sourceToBeCollapsed.getConfig(), Predicates.not(Predicates.<ConfigKey<?>>equalTo(EntityManagementUtils.WRAPPER_APP_MARKER)));
+        targetToBeExpanded.configure(configWithoutWrapperMarker);
         targetToBeExpanded.configure(sourceToBeCollapsed.getFlags());
         
         // TODO copying tags to all entities is not ideal;
@@ -281,14 +243,26 @@ public class EntityManagementUtils {
         targetToBeExpanded.tags(sourceToBeCollapsed.getTags());
     }
 
-    /** worker method to help determine whether child/children can be promoted */
-    @Beta //where should this live long-term?
-    public static boolean hasNoNameOrCustomKeysOrRoot(AssemblyTemplate template, EntitySpec<?> spec) {
-        if (Strings.isNonEmpty(template.getName())) {
+    public static boolean canPromote(EntitySpec<?> spec) {
+        return canPromoteBasedOnName(spec) &&
+                isWrapperApp(spec) &&
+                //equivalent to no keys starting with "brooklyn."
+                spec.getEnrichers().isEmpty() &&
+                spec.getInitializers().isEmpty() &&
+                spec.getPolicies().isEmpty();
+    }
+
+    public static boolean isWrapperApp(EntitySpec<?> spec) {
+        return Boolean.TRUE.equals(spec.getConfig().get(EntityManagementUtils.WRAPPER_APP_MARKER));
+    }
+
+    private static boolean canPromoteBasedOnName(EntitySpec<?> spec) {
+        if (!Strings.isEmpty(spec.getDisplayName())) {
             if (spec.getChildren().size()==1) {
                 String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName();
-                if (Strings.isEmpty(childName) || childName.equals(template.getName())) {
+                if (Strings.isEmpty(childName) || childName.equals(spec.getDisplayName())) {
                     // if child has no name, or it's the same, could still promote
+                    return true;
                 } else {
                     return false;
                 }
@@ -299,25 +273,9 @@ public class EntityManagementUtils {
         } else if (spec.getChildren().size()>1) {
             // don't allow multiple children if a name is specified as a root
             return false;
+        } else {
+            return true;
         }
-        
-        Set<String> rootAttrs = template.getCustomAttributes().keySet();
-        for (String rootAttr: rootAttrs) {
-            if (rootAttr.equals("brooklyn.catalog") || rootAttr.equals("brooklyn.config")) {
-                // these do not block promotion
-                continue;
-            }
-            if (rootAttr.startsWith("brooklyn.")) {
-                // any others in 'brooklyn' namespace will block promotion
-                return false;
-            }
-            // location is allowed in both, and is copied on promotion
-            // (name also copied)
-            // others are root currently are ignored on promotion; they are usually metadata
-            // TODO might be nice to know what we are excluding
-        }
-        
-        return true;
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
new file mode 100644
index 0000000..2551220
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanNotRecognizedException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.plan;
+
+public class PlanNotRecognizedException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public PlanNotRecognizedException() {
+        super();
+    }
+
+    public PlanNotRecognizedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public PlanNotRecognizedException(String message) {
+        super(message);
+    }
+
+    public PlanNotRecognizedException(Throwable cause) {
+        super(cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java
new file mode 100644
index 0000000..5d21420
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.plan;
+
+import java.util.Collection;
+import java.util.ServiceLoader;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+
+import com.google.common.collect.Lists;
+
+public class PlanToSpecFactory {
+    public static PlanToSpecTransformer forMime(ManagementContext mgmt, String mime) {
+        Collection<PlanToSpecTransformer> transformers = all(mgmt);
+        for (PlanToSpecTransformer transformer : transformers) {
+            if (transformer.accepts(mime)) {
+                return transformer;
+            }
+        }
+        throw new IllegalStateException("PlanToSpecTransformer for type " + mime + " not found. Registered transformers are: " + transformers);
+    }
+
+    public static Collection<PlanToSpecTransformer> all(ManagementContext mgmt) {
+        Collection<PlanToSpecTransformer> transformers = Lists.newArrayList(ServiceLoader.load(PlanToSpecTransformer.class));
+        for(PlanToSpecTransformer t : transformers) {
+            t.injectManagementContext(mgmt);
+        }
+        return transformers;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
new file mode 100644
index 0000000..13cd3bb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.plan;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
+
+import com.google.common.annotations.Beta;
+
+public interface PlanToSpecTransformer extends ManagementContextInjectable {
+    String getName();
+    @Beta
+    boolean accepts(String mime);
+    <T extends Application> EntitySpec<T> createApplicationSpec(String plan);
+    AbstractBrooklynObjectSpec<?, ?> createCatalogSpec(CatalogItem<?, ?> item);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java b/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java
index 1b37281..84cdfdb 100644
--- a/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java
+++ b/core/src/main/java/org/apache/brooklyn/core/server/BrooklynServerConfig.java
@@ -25,12 +25,10 @@ import java.net.URI;
 import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.server.BrooklynServerConfig;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.os.Os;
 import org.slf4j.Logger;
@@ -123,9 +121,6 @@ public class BrooklynServerConfig {
     public static final ConfigKey<Boolean> OSGI_CACHE_CLEAN = ConfigKeys.newBooleanConfigKey("brooklyn.osgi.cache.clean",
         "Whether to delete the OSGi directory before and after use; if unset, it will delete if the node ID forms part of the cache dir path (which by default it does) to avoid file leaks");
 
-    public static final ConfigKey<CampPlatform> CAMP_PLATFORM = ConfigKeys.newConfigKey(CampPlatform.class, "brooklyn.camp.platform",
-        "Config set at brooklyn management platform to find the CampPlatform instance (bi-directional)");
-
     /** @see BrooklynServerPaths#getMgmtBaseDir(ManagementContext) */
     public static String getMgmtBaseDir(ManagementContext mgmt) {
         return BrooklynServerPaths.getMgmtBaseDir(mgmt);
@@ -173,15 +168,6 @@ public class BrooklynServerConfig {
     }
 
     /**
-     * @return the CAMP platform associated with a management context, if there is one.
-     */
-    public static Maybe<CampPlatform> getCampPlatform(ManagementContext mgmt) {
-        CampPlatform result = mgmt.getConfig().getConfig(BrooklynServerConfig.CAMP_PLATFORM);
-        if (result!=null) return Maybe.of(result);
-        return Maybe.absent("No CAMP Platform is registered with this Brooklyn management context.");
-    }
-
-    /**
      * @return {@link ManagementContext#getManagementNodeUri()}, located in this utility class for convenience.
      */
     public static Maybe<URI> getBrooklynWebUri(ManagementContext mgmt) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java
index 37f569e..b96e5e7 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogItemTest.java
@@ -25,28 +25,28 @@ import static org.testng.Assert.fail;
 
 import java.io.File;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.camp.BasicCampPlatform;
-import org.apache.brooklyn.camp.test.mock.web.MockWebPlatform;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogDto;
+import org.apache.brooklyn.core.catalog.internal.CatalogEntityItemDto;
+import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
+import org.apache.brooklyn.core.catalog.internal.CatalogLocationItemDto;
+import org.apache.brooklyn.core.catalog.internal.CatalogPolicyItemDto;
 import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
-import org.apache.brooklyn.core.test.camp.brooklyn.lite.CampPlatformWithJustBrooklynMgmt;
-import org.apache.brooklyn.core.test.camp.brooklyn.lite.TestAppAssemblyInstantiator;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.policy.core.AbstractPolicy;
 import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.policy.core.AbstractPolicy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Throwables;
@@ -67,8 +67,6 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
         catalogPersistenceWasEnabled = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY);
         BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY);
         super.setUp();
-        BasicCampPlatform platform = new CampPlatformWithJustBrooklynMgmt(origManagementContext);
-        MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class);
         origApp.createAndManageChild(EntitySpec.create(TestEntity.class));
     }
 
@@ -110,13 +108,20 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
 
     @Test
     public void testAddAndRebindEntity() throws Exception {
+        String symbolicName = "rebind-yaml-catalog-item-test";
         String yaml = 
-                "name: rebind-yaml-catalog-item-test\n" +
+                "name: " + symbolicName + "\n" +
                 "brooklyn.catalog:\n" +
                 "  version: " + TEST_VERSION + "\n" +
                 "services:\n" +
                 "- type: io.camp.mock:AppServer";
-        addItem(origManagementContext, yaml);
+        CatalogEntityItemDto item =
+            CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION)
+                .displayName(symbolicName)
+                .plan(yaml)
+                .build();
+        origManagementContext.getCatalog().addItem(item);
+        LOG.info("Added item to catalog: {}, id={}", item, item.getId());
         rebindAndAssertCatalogsAreEqual();
     }
 
@@ -129,7 +134,9 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
     @Test
     public void testAddAndRebindPolicy() {
         // Doesn't matter that SamplePolicy doesn't exist
-        String yaml = "name: Test Policy\n" +
+        String symbolicName = "Test Policy";
+        String yaml =
+                "name: " + symbolicName + "\n" +
                 "brooklyn.catalog:\n" +
                 "  id: sample_policy\n" +
                 "  version: " + TEST_VERSION + "\n" +
@@ -138,27 +145,39 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
                 "  brooklyn.config:\n" +
                 "    cfg1: 111\n" +
                 "    cfg2: 222";
-        addItem(origManagementContext, yaml);
+        CatalogPolicyItemDto item =
+                CatalogItemBuilder.newPolicy(symbolicName, TEST_VERSION)
+                    .displayName(symbolicName)
+                    .plan(yaml)
+                    .build();
+        origManagementContext.getCatalog().addItem(item);
+        LOG.info("Added item to catalog: {}, id={}", item, item.getId());
         rebindAndAssertCatalogsAreEqual();
     }
 
     @Test
     public void testAddAndRebindAndDeleteLocation() {
+        String symbolicName = "sample_location";
         String yaml = Joiner.on("\n").join(ImmutableList.of(
                 "name: Test Location",
                 "brooklyn.catalog:",
-                "  id: sample_location",
+                "  id: " + symbolicName,
                 "  version: " + TEST_VERSION,
                 "brooklyn.locations:",
                 "- type: "+LocalhostMachineProvisioningLocation.class.getName(),
                 "  brooklyn.config:",
                 "    cfg1: 111",
                 "    cfg2: 222"));
-        CatalogItem<?, ?> added = addItem(origManagementContext, yaml);
-        assertEquals(added.getCatalogItemType(), CatalogItemType.LOCATION);
+        CatalogLocationItemDto item =
+                CatalogItemBuilder.newLocation(symbolicName, TEST_VERSION)
+                    .displayName(symbolicName)
+                    .plan(yaml)
+                    .build();
+        origManagementContext.getCatalog().addItem(item);
+        assertEquals(item.getCatalogItemType(), CatalogItemType.LOCATION);
         rebindAndAssertCatalogsAreEqual();
         
-        deleteItem(newManagementContext, added.getSymbolicName(), added.getVersion());
+        deleteItem(newManagementContext, item.getSymbolicName(), item.getVersion());
         
         switchOriginalToNewManagementContext();
         rebindAndAssertCatalogsAreEqual();
@@ -203,15 +222,20 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
         //The test is not reliable on Windows (doesn't catch the pre-fix problem) -
         //the store is unable to delete still locked files so the bug doesn't manifest.
         //TODO investigate if locked files not caused by unclosed streams!
+        String symbolicName = "rebind-yaml-catalog-item-test";
         String yaml = 
-                "name: rebind-yaml-catalog-item-test\n" +
+                "name: " + symbolicName + "\n" +
                 "brooklyn.catalog:\n" +
                 "  version: " + TEST_VERSION + "\n" +
                 "services:\n" +
                 "- type: io.camp.mock:AppServer";
-        addItem(origManagementContext, yaml);
-        
         BasicBrooklynCatalog catalog = (BasicBrooklynCatalog) origManagementContext.getCatalog();
+        CatalogEntityItemDto item =
+                CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION)
+                    .displayName(symbolicName)
+                    .plan(yaml)
+                    .build();
+        catalog.addItem(item);
         String catalogXml = catalog.toXmlString();
         catalog.reset(CatalogDto.newDtoFromXmlContents(catalogXml, "Test reset"));
         rebindAndAssertCatalogsAreEqual();
@@ -219,30 +243,29 @@ public class RebindCatalogItemTest extends RebindTestFixtureWithApp {
 
     @Test
     public void testRebindAfterItemDeprecated() {
+        String symbolicName = "rebind-yaml-catalog-item-test";
         String yaml =
-                "name: rebind-yaml-catalog-item-test\n" +
+                "name: " + symbolicName + "\n" +
                 "brooklyn.catalog:\n" +
                 "  version: " + TEST_VERSION + "\n" +
                 "services:\n" +
                 "- type: io.camp.mock:AppServer";
-        CatalogItem<?, ?> catalogItem = addItem(origManagementContext, yaml);
-        assertNotNull(catalogItem, "catalogItem");
+        CatalogEntityItemDto item =
+                CatalogItemBuilder.newEntity(symbolicName, TEST_VERSION)
+                    .displayName(symbolicName)
+                    .plan(yaml)
+                    .build();
+        origManagementContext.getCatalog().addItem(item);
+        assertNotNull(item, "catalogItem");
         BasicBrooklynCatalog catalog = (BasicBrooklynCatalog) origManagementContext.getCatalog();
         
-        catalogItem.setDeprecated(true);
-        catalog.persist(catalogItem);
+        item.setDeprecated(true);
+        catalog.persist(item);
         rebindAndAssertCatalogsAreEqual();
         CatalogItem<?, ?> catalogItemAfterRebind = newManagementContext.getCatalog().getCatalogItem("rebind-yaml-catalog-item-test", TEST_VERSION);
         assertTrue(catalogItemAfterRebind.isDeprecated(), "Expected item to be deprecated");
     }
 
-    protected CatalogItem<?, ?> addItem(ManagementContext mgmt, String yaml) {
-        CatalogItem<?, ?> added = Iterables.getOnlyElement(mgmt.getCatalog().addItems(yaml));
-        LOG.info("Added item to catalog: {}, id={}", added, added.getId());
-        assertCatalogContains(mgmt.getCatalog(), added);
-        return added;
-    }
-    
     protected void deleteItem(ManagementContext mgmt, String symbolicName, String version) {
         mgmt.getCatalog().deleteCatalogItem(symbolicName, version);
         LOG.info("Deleted item from catalog: {}:{}", symbolicName, version);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
index 7831c1a..62db79f 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogWhenCatalogPersistenceDisabledTest.java
@@ -22,17 +22,16 @@ import static org.testng.Assert.assertEquals;
 
 import java.io.File;
 
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
-import org.apache.brooklyn.core.test.camp.brooklyn.lite.CampPlatformWithJustBrooklynMgmt;
 import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
 
 import com.google.common.collect.Iterables;
 
@@ -47,7 +46,6 @@ public class RebindCatalogWhenCatalogPersistenceDisabledTest extends RebindTestF
         catalogPersistenceWasPreviouslyEnabled = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY);
         BrooklynFeatureEnablement.disable(BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY);
         super.setUp();
-        new CampPlatformWithJustBrooklynMgmt(origManagementContext);
         origApp.createAndManageChild(EntitySpec.create(TestEntity.class));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java
deleted file mode 100644
index 95fa64d..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampPlatformWithJustBrooklynMgmt.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.test.camp.brooklyn.lite;
-
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.camp.BasicCampPlatform;
-import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.server.BrooklynServerConfig;
-
-public class CampPlatformWithJustBrooklynMgmt extends BasicCampPlatform implements HasBrooklynManagementContext {
-
-    private ManagementContext mgmt;
-
-    public CampPlatformWithJustBrooklynMgmt(ManagementContext mgmt) {
-        this.mgmt = mgmt;
-        ((BrooklynProperties)mgmt.getConfig()).put(BrooklynServerConfig.CAMP_PLATFORM, this);
-    }
-    
-    @Override
-    public ManagementContext getBrooklynManagementContext() {
-        return mgmt;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java
deleted file mode 100644
index f109737..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/CampYamlLiteTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.test.camp.brooklyn.lite;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.ResourceUtils;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.stream.Streams;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.camp.spi.Assembly;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.pdp.PdpYamlTest;
-import org.apache.brooklyn.camp.test.mock.web.MockWebPlatform;
-import org.apache.brooklyn.core.catalog.CatalogPredicates;
-import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
-import org.apache.brooklyn.core.catalog.internal.CatalogDto;
-import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.AddChildrenEffector;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.factory.ApplicationBuilder;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-/** Tests of lightweight CAMP integration. Since the "real" integration is in brooklyn-camp project,
- * but some aspects of CAMP we want to be able to test here. */
-public class CampYamlLiteTest {
-    private static final String TEST_VERSION = "0.1.2";
-
-    private static final Logger log = LoggerFactory.getLogger(CampYamlLiteTest.class);
-    
-    protected LocalManagementContext mgmt;
-    protected CampPlatformWithJustBrooklynMgmt platform;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        mgmt = LocalManagementContextForTests.newInstanceWithOsgi();
-        platform = new CampPlatformWithJustBrooklynMgmt(mgmt);
-        MockWebPlatform.populate(platform, TestAppAssemblyInstantiator.class);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (mgmt!=null) mgmt.terminate();
-    }
-    
-    /** based on {@link PdpYamlTest} for parsing,
-     * then creating a {@link TestAppAssembly} */
-    @Test
-    public void testYamlServiceMatchAndBrooklynInstantiate() throws Exception {
-        Reader input = new InputStreamReader(getClass().getResourceAsStream("test-app-service-blueprint.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-        log.info("AT is:\n"+at.toString());
-        Assert.assertEquals(at.getName(), "sample");
-        Assert.assertEquals(at.getPlatformComponentTemplates().links().size(), 1);
-        
-        // now use brooklyn to instantiate - note it won't be faithful, but it will set some config keys
-        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-        
-        TestApplication app = ((TestAppAssembly)assembly).getBrooklynApp();
-        Assert.assertEquals( app.getConfig(TestEntity.CONF_NAME), "sample" );
-        Map<String, String> map = app.getConfig(TestEntity.CONF_MAP_THING);
-        Assert.assertEquals( map.get("desc"), "Tomcat sample JSP and servlet application." );
-        
-        Assert.assertEquals( app.getChildren().size(), 1 );
-        Entity svc = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertEquals( svc.getConfig(TestEntity.CONF_NAME), "Hello WAR" );
-        map = svc.getConfig(TestEntity.CONF_MAP_THING);
-        Assert.assertEquals( map.get("type"), MockWebPlatform.APPSERVER.getType() );
-        // desc ensures we got the information from the matcher, as this value is NOT in the yaml
-        Assert.assertEquals( map.get("desc"), MockWebPlatform.APPSERVER.getDescription() );
-    }
-
-    /** based on {@link PdpYamlTest} for parsing,
-     * then creating a {@link TestAppAssembly} */
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Test
-    public void testAddChildrenEffector() throws Exception {
-        String childYaml = Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml"));
-        AddChildrenEffector newEff = new AddChildrenEffector(ConfigBag.newInstance()
-            .configure(AddChildrenEffector.EFFECTOR_NAME, "add_tomcat")
-            .configure(AddChildrenEffector.BLUEPRINT_YAML, childYaml)
-            .configure(AddChildrenEffector.EFFECTOR_PARAMETER_DEFS, MutableMap.of("war", (Object)MutableMap.of(
-                "defaultValue", "foo.war"))) ) ;
-        TestApplication app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).addInitializer(newEff), mgmt);
-
-        // test adding, with a parameter
-        Task<List> task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.of("war", "foo.bar"));
-        List result = task.get();
-        
-        Entity newChild = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.bar");
-        
-        Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId());
-        Entities.unmanage(newChild);
-        
-        // and test default value
-        task = app.invoke(Effectors.effector(List.class, "add_tomcat").buildAbstract(), MutableMap.<String,Object>of());
-        result = task.get();
-        
-        newChild = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertEquals(newChild.getConfig(ConfigKeys.newStringConfigKey("war")), "foo.war");
-        
-        Assert.assertEquals(Iterables.getOnlyElement(result), newChild.getId());
-        Entities.unmanage(newChild);
-    }
-
-    @Test
-    public void testYamlServiceForCatalog() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        CatalogItem<?, ?> realItem = Iterables.getOnlyElement(mgmt.getCatalog().addItems(Streams.readFullyString(getClass().getResourceAsStream("test-app-service-blueprint.yaml"))));
-        Iterable<CatalogItem<Object, Object>> retrievedItems = mgmt.getCatalog()
-                .getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo("catalog-name")));
-        
-        Assert.assertEquals(Iterables.size(retrievedItems), 1, "Wrong retrieved items: "+retrievedItems);
-        CatalogItem<Object, Object> retrievedItem = Iterables.getOnlyElement(retrievedItems);
-        Assert.assertEquals(retrievedItem, realItem);
-
-        Collection<CatalogBundle> bundles = retrievedItem.getLibraries();
-        Assert.assertEquals(bundles.size(), 1);
-        CatalogBundle bundle = Iterables.getOnlyElement(bundles);
-        Assert.assertEquals(bundle.getUrl(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL);
-        Assert.assertEquals(bundle.getVersion(), "0.1.0");
-
-        EntitySpec<?> spec1 = (EntitySpec<?>) mgmt.getCatalog().createSpec(retrievedItem);
-        assertNotNull(spec1);
-        Assert.assertEquals(spec1.getConfig().get(TestEntity.CONF_NAME), "sample");
-        
-        // TODO other assertions, about children
-    }
-
-    @Test
-    public void testRegisterCustomEntityWithBundleWhereEntityIsFromCoreAndIconFromBundle() throws IOException {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id";
-        String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
-        String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl);
-
-        mgmt.getCatalog().addItems(yaml);
-
-        assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl);
-    }
-
-    @Test
-    public void testResetXmlWithCustomEntity() throws IOException {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id";
-        String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
-        String yaml = getSampleMyCatalogAppYaml(symbolicName, bundleUrl);
-
-        LocalManagementContext mgmt2 = LocalManagementContextForTests.newInstanceWithOsgi();
-        try {
-            CampPlatformWithJustBrooklynMgmt platform2 = new CampPlatformWithJustBrooklynMgmt(mgmt2);
-            MockWebPlatform.populate(platform2, TestAppAssemblyInstantiator.class);
-
-            mgmt2.getCatalog().addItems(yaml);
-            String xml = ((BasicBrooklynCatalog) mgmt2.getCatalog()).toXmlString();
-            ((BasicBrooklynCatalog) mgmt.getCatalog()).reset(CatalogDto.newDtoFromXmlContents(xml, "copy of temporary catalog"));
-        } finally {
-            mgmt2.terminate();
-        }
-
-        assertMgmtHasSampleMyCatalogApp(symbolicName, bundleUrl);
-    }
-
-    private String getSampleMyCatalogAppYaml(String symbolicName, String bundleUrl) {
-        return "brooklyn.catalog:\n" +
-                "  id: " + symbolicName + "\n" +
-                "  name: My Catalog App\n" +
-                "  description: My description\n" +
-                "  icon_url: classpath:/brooklyn/osgi/tests/icon.gif\n" +
-                "  version: " + TEST_VERSION + "\n" +
-                "  libraries:\n" +
-                "  - url: " + bundleUrl + "\n" +
-                "\n" +
-                "services:\n" +
-                "- type: io.camp.mock:AppServer\n";
-    }
-
-    private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {
-        CatalogItem<?, ?> item = mgmt.getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertNotNull(item, "failed to load item with id=" + symbolicName + " from catalog. Entries were: " +
-                Joiner.on(",").join(mgmt.getCatalog().getCatalogItems()));
-        assertEquals(item.getSymbolicName(), symbolicName);
-
-        // stored as yaml, not java
-        assertNotNull(item.getPlanYaml());
-        Assert.assertTrue(item.getPlanYaml().contains("io.camp.mock:AppServer"));
-
-        // and let's check we have libraries
-        Collection<CatalogBundle> libs = item.getLibraries();
-        assertEquals(libs.size(), 1);
-        CatalogBundle bundle = Iterables.getOnlyElement(libs);
-        assertEquals(bundle.getUrl(), bundleUrl);
-
-        // now let's check other things on the item
-        assertEquals(item.getDisplayName(), "My Catalog App");
-        assertEquals(item.getDescription(), "My description");
-        assertEquals(item.getIconUrl(), "classpath:/brooklyn/osgi/tests/icon.gif");
-
-        // and confirm we can resolve ICON
-        byte[] iconData = Streams.readFully(ResourceUtils.create(CatalogUtils.newClassLoadingContext(mgmt, item)).getResourceFromUrl(item.getIconUrl()));
-        assertEquals(iconData.length, 43);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java
deleted file mode 100644
index bc9e9bb..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssembly.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.test.camp.brooklyn.lite;
-
-import org.apache.brooklyn.camp.spi.Assembly;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-
-public class TestAppAssembly extends Assembly {
-
-    private TestApplication brooklynApp;
-
-    public TestAppAssembly(TestApplication brooklynApp) {
-        this.brooklynApp = brooklynApp;
-    }
-    
-    public TestApplication getBrooklynApp() {
-        return brooklynApp;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6ed695e5/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java b/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java
deleted file mode 100644
index d55cedf..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/camp/brooklyn/lite/TestAppAssemblyInstantiator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.test.camp.brooklyn.lite;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.camp.CampPlatform;
-import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
-import org.apache.brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
-import org.apache.brooklyn.camp.spi.AbstractResource;
-import org.apache.brooklyn.camp.spi.Assembly;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
-import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
-import org.apache.brooklyn.camp.spi.instantiate.BasicAssemblyTemplateInstantiator;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-
-/** simple illustrative instantiator which always makes a {@link TestApplication}, populated with {@link TestEntity} children,
- * all setting {@link TestEntity#CONF_NAME} for the name in the plan and in the service specs
- * <p>
- * the "real" instantiator for brooklyn is in brooklyn-camp project, not visible here, so let's have something we can test */
-public class TestAppAssemblyInstantiator extends BasicAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
-
-    @Override
-    public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) {
-        if (!(platform instanceof HasBrooklynManagementContext)) {
-            throw new IllegalStateException("Instantiator can only be used with CAMP platforms with a Brooklyn management context");
-        }
-        ManagementContext mgmt = ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
-        
-        TestApplication app = (TestApplication) mgmt.getEntityManager().createEntity( createSpec(template, platform, null, false) );
-        mgmt.getEntityManager().manage(app);
-
-        return new TestAppAssembly(app);
-    }
-
-    @Override
-    public EntitySpec<?> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrap) {
-        EntitySpec<TestApplication> app = EntitySpec.create(TestApplication.class)
-            .configure(TestEntity.CONF_NAME, template.getName())
-            .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", template.getType(), "desc", template.getDescription()));
-        applyBrooklynConfig(template, app);
-        
-        for (ResolvableLink<PlatformComponentTemplate> t: template.getPlatformComponentTemplates().links()) {
-            EntitySpec<TestEntity> spec = EntitySpec.create(TestEntity.class)
-                .configure(TestEntity.CONF_NAME, t.getName())
-                .configure(TestEntity.CONF_MAP_THING, MutableMap.of("type", t.resolve().getType(), "desc", t.resolve().getDescription()));
-            applyBrooklynConfig(t.resolve(), app);
-            app.child(spec);
-        }
-        
-        return app;
-    }
-
-    @SuppressWarnings("rawtypes")
-    private void applyBrooklynConfig(AbstractResource template, EntitySpec<TestApplication> app) {
-        Object bc = template.getCustomAttributes().get("brooklyn.config");
-        if (bc instanceof Map)
-            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);
-    }
-
-}



[4/4] incubator-brooklyn git commit: This closes #846

Posted by he...@apache.org.
This closes #846


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

Branch: refs/heads/master
Commit: fb6a4a1d064dbf5d9d1adccbd898bf0e291eb58c
Parents: 0f6041e a47d5aa
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Aug 19 15:35:06 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Aug 19 15:35:06 2015 +0100

----------------------------------------------------------------------
 core/pom.xml                                    |  16 +-
 .../api/AssemblyTemplateSpecInstantiator.java   |  35 ---
 .../catalog/internal/BasicBrooklynCatalog.java  | 243 +++---------------
 .../core/mgmt/EntityManagementUtils.java        | 201 ++++++---------
 .../core/plan/PlanNotRecognizedException.java   |  37 +++
 .../brooklyn/core/plan/PlanToSpecFactory.java   |  46 ++++
 .../core/plan/PlanToSpecTransformer.java        |  49 ++++
 .../core/server/BrooklynServerConfig.java       |  14 -
 .../core/mgmt/rebind/RebindCatalogItemTest.java |  93 ++++---
 ...talogWhenCatalogPersistenceDisabledTest.java |   8 +-
 .../lite/CampPlatformWithJustBrooklynMgmt.java  |  41 ---
 .../camp/brooklyn/lite/CampYamlLiteTest.java    | 255 -------------------
 .../camp/brooklyn/lite/TestAppAssembly.java     |  36 ---
 .../lite/TestAppAssemblyInstantiator.java       |  90 -------
 .../lite/test-app-service-blueprint.yaml        |  38 ---
 usage/camp/pom.xml                              |  12 +
 .../camp/brooklyn/BrooklynCampConstants.java    |   3 +-
 .../api/AssemblyTemplateSpecInstantiator.java   |  35 +++
 .../BrooklynAssemblyTemplateInstantiator.java   |  51 ++--
 .../BrooklynComponentTemplateResolver.java      |  12 +-
 .../brooklyn/spi/creation/CampCatalogUtils.java | 244 ++++++++++++++++++
 .../spi/creation/CampToSpecTransformer.java     |  92 +++++++
 ...che.brooklyn.core.plan.PlanToSpecTransformer |  19 ++
 .../brooklyn/catalog/CatalogYamlCombiTest.java  |   7 +-
 .../lite/CampPlatformWithJustBrooklynMgmt.java  |  41 +++
 .../brooklyn/test/lite/CampYamlLiteTest.java    | 254 ++++++++++++++++++
 .../brooklyn/test/lite/TestAppAssembly.java     |  36 +++
 .../test/lite/TestAppAssemblyInstantiator.java  |  90 +++++++
 .../test/lite/test-app-service-blueprint.yaml   |  38 +++
 .../brooklyn/launcher/BrooklynLauncher.java     |  46 +---
 .../resources/AbstractBrooklynRestResource.java |   4 -
 .../rest/resources/ApplicationResource.java     |  83 +++---
 32 files changed, 1265 insertions(+), 1004 deletions(-)
----------------------------------------------------------------------