brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [2/4] incubator-brooklyn git commit: This closes #760. Makes YAML pluggable.
Date Wed, 19 Aug 2015 14:35:34 GMT
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 <svetoslav.neykov@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 <svetoslav.neykov@cloudsoftcorp.com>
> Date:   Tue Jul 21 15:01:51 2015 +0300
>
>     Decrease API surface in CampCatalogUtils
>
> commit 4e24d5f93d250dbbbcf579f2a406f63e1c315798
> Author: Svetoslav Neykov <svetoslav.neykov@cloudsoftcorp.com>
> Date:   Tue Jul 21 13:17:42 2015 +0300
>
>     Deduplicate code
>
> commit a953e059066aa53323db0ed027366a4b5994ecfc
> Author: Svetoslav Neykov <svetoslav.neykov@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 <svetoslav.neykov@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 <svetoslav.neykov@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 <alex.heneveld@cloudsoftcorp.com>
Authored: Wed Aug 19 11:02:12 2015 +0100
Committer: Alex Heneveld <alex.heneveld@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);
-    }
-
-}



Mime
View raw message