You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/05 22:56:05 UTC

[01/20] incubator-brooklyn git commit: Package rename: fix sandbox refs to Catalog

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 846143cda -> 7bc08a05f


Package rename: fix sandbox refs to Catalog

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

Branch: refs/heads/master
Commit: 4b80b27dafd61841bcc58988ac8d2056f3849351
Parents: f968473
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 5 14:51:03 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 5 14:51:03 2015 +0100

----------------------------------------------------------------------
 .../extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java  | 2 +-
 .../java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java     | 2 +-
 .../main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4b80b27d/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java b/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java
index 5af9622..0db1841 100644
--- a/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java
+++ b/sandbox/extra/src/main/java/brooklyn/entity/salt/SaltStackMaster.java
@@ -20,7 +20,7 @@ package brooklyn.entity.salt;
 
 import java.util.List;
 
-import brooklyn.catalog.Catalog;
+import org.apache.brooklyn.catalog.Catalog;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.ConfigKeys;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4b80b27d/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java b/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
index 48ab1aa..c91b78c 100644
--- a/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
+++ b/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
@@ -22,7 +22,7 @@ import java.util.List;
 
 import com.google.common.reflect.TypeToken;
 
-import brooklyn.catalog.Catalog;
+import org.apache.brooklyn.catalog.Catalog;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.group.DynamicCluster;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4b80b27d/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java b/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
index 076b6f5..40aa330 100644
--- a/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
+++ b/sandbox/nosql/src/main/java/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.entity.nosql.hazelcast;
 
-import brooklyn.catalog.Catalog;
+import org.apache.brooklyn.catalog.Catalog;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.SoftwareProcess;


[12/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
deleted file mode 100644
index 0a02838..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
+++ /dev/null
@@ -1,130 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.proxy.ProxySslConfig;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.util.task.Tasks;
-
-import com.google.common.collect.Iterables;
-
-@Test
-public class MapReferenceYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(MapReferenceYamlTest.class);
-
-    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-reference-map-template.yaml", extras));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-reference-map-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Assert.assertEquals(Iterables.size(app.getChildren()), 3, "Expected app to have child entity");
-        Iterable<BasicEntity> basicEntities = Iterables.filter(app.getChildren(), BasicEntity.class);
-        Iterable<TestEntity> testEntities = Iterables.filter(app.getChildren(), TestEntity.class);
-        Assert.assertEquals(Iterables.size(basicEntities), 2, "Expected app to have two basic entities");
-        Assert.assertEquals(Iterables.size(testEntities), 1, "Expected app to have one test entity");
-
-        return Iterables.getOnlyElement(testEntities);
-    }
-
-    @Test
-    public void testSingleEntity() throws Exception {
-        setupAndCheckTestEntityInBasicYamlWith();
-    }
-
-    @Test
-    public void testBrooklynConfigWithMapFunction() throws Exception {
-        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confMapThing.obj:",
-            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
-            "      object:",
-            "        $brooklyn:object:",
-            "          type: brooklyn.entity.proxy.ProxySslConfig",
-            "      one: $brooklyn:entity(\"one\")",
-            "      two: $brooklyn:entity(\"two\")");
-
-        Map<?,?> testMap = (Map<?,?>) Entities.submit(testEntity, Tasks.builder().body(new Callable<Object>() {
-            @Override
-            public Object call() throws Exception {
-                return testEntity.getConfig(TestEntity.CONF_MAP_THING_OBJECT);
-            }
-        }).build()).get();
-        Object frog = testMap.get("frog");
-        Object one = testMap.get("one");
-        Object two = testMap.get("two");
-        Object object = testMap.get("object");
-
-        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
-        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
-        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig: " + object);
-        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: " + one);
-        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: " + two);
-    }
-
-    @Test
-    public void testBrooklynConfigWithPlainMapFunction() throws Exception {
-        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confMapPlain:",
-            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
-            "      object:",
-            "        $brooklyn:object:",
-            "          type: brooklyn.entity.proxy.ProxySslConfig",
-            "      one: $brooklyn:entity(\"one\")",
-            "      two: $brooklyn:entity(\"two\")");
-
-        Map<?,?> testMap = (Map<?,?>) Entities.submit(testEntity, Tasks.builder().body(new Callable<Object>() {
-            @Override
-            public Object call() throws Exception {
-                return testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
-            }
-        }).build()).get();
-        Object frog = testMap.get("frog");
-        Object one = testMap.get("one");
-        Object two = testMap.get("two");
-        Object object = testMap.get("object");
-
-        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
-        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
-        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig: " + object);
-        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: " + one);
-        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: " + two);
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
deleted file mode 100644
index 6f5a968..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ObjectsYamlTest.java
+++ /dev/null
@@ -1,280 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.proxy.ProxySslConfig;
-import brooklyn.entity.trait.Configurable;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.ManagementContextInjectable;
-import brooklyn.management.Task;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.flags.TypeCoercions;
-
-import com.google.common.collect.Lists;
-
-@Test
-public class ObjectsYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(ObjectsYamlTest.class);
-
-    private static final AtomicBoolean managementContextInjected = new AtomicBoolean(false);
-    private static final List<String> configKeys = Lists.newLinkedList();
-
-    public static class TestObject implements ManagementContextInjectable {
-        private String string;
-        private Integer number;
-        private Object object;
-
-        public TestObject() { }
-
-        public String getString() { return string; }
-        public void setString(String string) { this.string = string; }
-
-        public Integer getNumber() { return number; }
-        public void setNumber(Integer number) { this.number = number; }
-
-        public Object getObject() { return object; }
-        public void setObject(Object object) { this.object = object; }
-
-        @Override
-        public void injectManagementContext(ManagementContext managementContext) {
-            log.info("Detected injection of {}", managementContext);
-            managementContextInjected.set(true);
-        }
-    }
-
-    public static class ConfigurableObject implements Configurable {
-        public static final ConfigKey<Integer> INTEGER = ConfigKeys.newIntegerConfigKey("config.number");
-        @SetFromFlag("object")
-        public static final ConfigKey<Object> OBJECT = ConfigKeys.newConfigKey(Object.class, "config.object");
-
-        @SetFromFlag("flag")
-        private String string;
-
-        private Integer number;
-        private Object object;
-        private Double value;
-        BasicConfigurationSupport configSupport = new BasicConfigurationSupport();
-        
-        public ConfigurableObject() { }
-
-        public String getString() { return string; }
-
-        public Integer getNumber() { return number; }
-
-        public Object getObject() { return object; }
-
-        public Double getDouble() { return value; }
-        public void setDouble(Double value) { this.value = value; }
-
-        @Override
-        public <T> T setConfig(ConfigKey<T> key, T value) {
-            return config().set(key, value);
-        }
-        
-        @Override
-        public ConfigurationSupport config() {
-            return configSupport;
-        }
-        
-        private class BasicConfigurationSupport implements ConfigurationSupport {
-            private final ConfigBag bag = new ConfigBag();
-            
-            @Override
-            public <T> T get(ConfigKey<T> key) {
-                return bag.get(key);
-            }
-
-            @Override
-            public <T> T get(HasConfigKey<T> key) {
-                return get(key.getConfigKey());
-            }
-
-            @Override
-            public <T> T set(ConfigKey<T> key, T val) {
-                log.info("Detected configuration injection for {}: {}", key.getName(), val);
-                configKeys.add(key.getName());
-                if ("config.number".equals(key.getName())) number = TypeCoercions.coerce(val, Integer.class);
-                if ("config.object".equals(key.getName())) object = val;
-                T old = bag.get(key);
-                bag.configure(key, val);
-                return old;
-            }
-
-            @Override
-            public <T> T set(HasConfigKey<T> key, T val) {
-                return set(key.getConfigKey(), val);
-            }
-
-            @Override
-            public <T> T set(ConfigKey<T> key, Task<T> val) {
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public <T> T set(HasConfigKey<T> key, Task<T> val) {
-                return set(key.getConfigKey(), val);
-            }
-        }
-    }
-
-    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
-        managementContextInjected.set(false);
-        configKeys.clear();
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-
-        return (TestEntity)entity;
-    }
-
-    @Test
-    public void testSingleEntity() throws Exception {
-        setupAndCheckTestEntityInBasicYamlWith();
-    }
-
-    @Test
-    public void testBrooklynObject() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confObject:",
-            "      $brooklyn:object:",
-            "        type: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
-            "        object.fields:",
-            "          number: 7",
-            "          object:",
-            "            $brooklyn:object:",
-            "              type: brooklyn.entity.proxy.ProxySslConfig",
-            "          string: \"frog\"");
-
-        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
-
-        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
-        Assert.assertTrue(managementContextInjected.get());
-        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
-        Assert.assertEquals(((TestObject) testObject).getString(), "frog");
-
-        Object testObjectObject = ((TestObject) testObject).getObject();
-        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
-    }
-
-    @Test
-    public void testBrooklynConfigurableObject() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confObject:",
-            "      $brooklyn:object:",
-            "        type: io.brooklyn.camp.brooklyn.ObjectsYamlTest$ConfigurableObject",
-            "        object.fields:",
-            "          double: 1.4",
-            "        brooklyn.config:",
-            "          flag: frog",
-            "          config.number: 7",
-            "          object:",
-            "            $brooklyn:object:",
-            "              type: brooklyn.entity.proxy.ProxySslConfig");
-
-        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
-
-        Assert.assertTrue(testObject instanceof ConfigurableObject, "Expected a ConfigurableObject: "+testObject);
-        Assert.assertEquals(((ConfigurableObject) testObject).getDouble(), Double.valueOf(1.4));
-        Assert.assertEquals(((ConfigurableObject) testObject).getString(), "frog");
-        Assert.assertEquals(((ConfigurableObject) testObject).getNumber(), Integer.valueOf(7));
-
-        Object testObjectObject = ((ConfigurableObject) testObject).getObject();
-        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
-
-        Assert.assertTrue(configKeys.contains(ConfigurableObject.INTEGER.getName()), "Expected INTEGER key: "+configKeys);
-        Assert.assertTrue(configKeys.contains(ConfigurableObject.OBJECT.getName()), "Expected OBJECT key: "+configKeys);
-    }
-
-    @Test
-    public void testBrooklynObjectPrefix() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confListPlain:",
-            "    - $brooklyn:object:",
-            "        objectType: brooklyn.entity.proxy.ProxySslConfig",
-            "    - $brooklyn:object:",
-            "        object_type: brooklyn.entity.proxy.ProxySslConfig",
-            "    - $brooklyn:object:",
-            "        type: brooklyn.entity.proxy.ProxySslConfig");
-
-        List<?> testList = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
-
-        Assert.assertEquals(testList.size(), 3);
-        for (Object entry : testList) {
-            Assert.assertTrue(entry instanceof ProxySslConfig, "Expected a ProxySslConfig: "+entry);
-        }
-    }
-
-    @Test
-    public void testBrooklynObjectWithFunction() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
-            "  brooklyn.config:",
-            "    test.confObject:",
-            "      $brooklyn:object:",
-            "        type: io.brooklyn.camp.brooklyn.ObjectsYamlTest$TestObject",
-            "        object.fields:",
-            "          number: 7",
-            "          object:",
-            "            $brooklyn:object:",
-            "              type: brooklyn.entity.proxy.ProxySslConfig",
-            "          string:",
-            "            $brooklyn:formatString(\"%s\", \"frog\")");
-
-        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
-
-        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
-        Assert.assertTrue(managementContextInjected.get());
-        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
-        Assert.assertEquals(((TestObject) testObject).getString(), "frog");
-
-        Object testObjectObject = ((TestObject) testObject).getObject();
-        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/PoliciesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/PoliciesYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/PoliciesYamlTest.java
deleted file mode 100644
index 7ca9602..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/PoliciesYamlTest.java
+++ /dev/null
@@ -1,215 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.policy.Policy;
-import brooklyn.test.Asserts;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.test.policy.TestPolicy;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-@Test
-public class PoliciesYamlTest extends AbstractYamlTest {
-    static final Logger log = LoggerFactory.getLogger(PoliciesYamlTest.class);
-
-    @Test
-    public void testWithAppPolicy() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-app-with-policy.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-app-with-policy");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Assert.assertEquals(app.getPolicies().size(), 1);
-        Policy policy = app.getPolicies().iterator().next();
-        Assert.assertTrue(policy instanceof TestPolicy);
-        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_NAME), "Name from YAML");
-        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
-        Map<?, ?> leftoverProperties = ((TestPolicy) policy).getLeftoverProperties();
-        Assert.assertEquals(leftoverProperties.get("policyLiteralValue1"), "Hello");
-        Assert.assertEquals(leftoverProperties.get("policyLiteralValue2"), "World");
-        Assert.assertEquals(leftoverProperties.size(), 2);
-    }
-    
-    @Test
-    public void testWithEntityPolicy() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-with-policy.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-entity-with-policy");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Assert.assertEquals(app.getPolicies().size(), 0);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity child = app.getChildren().iterator().next();
-        Assert.assertEquals(child.getPolicies().size(), 1);
-        Policy policy = child.getPolicies().iterator().next();
-        Assert.assertNotNull(policy);
-        Assert.assertTrue(policy instanceof TestPolicy, "policy=" + policy + "; type=" + policy.getClass());
-        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_NAME), "Name from YAML");
-        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
-        Assert.assertEquals(((TestPolicy) policy).getLeftoverProperties(),
-                ImmutableMap.of("policyLiteralValue1", "Hello", "policyLiteralValue2", "World"));
-        Assert.assertEquals(policy.getConfig(TestPolicy.TEST_ATTRIBUTE_SENSOR), TestEntity.NAME);
-    }
-    
-    @Test
-    public void testChildWithPolicy() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
-                    "  brooklyn.config:",
-                    "    test.confName: parent entity",
-                    "  brooklyn.children:",
-                    "  - serviceType: brooklyn.test.entity.TestEntity",
-                    "    name: Child Entity",
-                    "    brooklyn.policies:",
-                    "    - policyType: brooklyn.test.policy.TestPolicy",
-                    "      brooklyn.config:",
-                    "        test.confName: Name from YAML",
-                    "        test.attributeSensor: $brooklyn:sensor(\"brooklyn.test.entity.TestEntity\", \"test.name\")"));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity firstEntity = app.getChildren().iterator().next();
-        Assert.assertEquals(firstEntity.getChildren().size(), 1);
-        final Entity child = firstEntity.getChildren().iterator().next();
-        Assert.assertEquals(child.getChildren().size(), 0);
-
-        Assert.assertEquals(app.getPolicies().size(), 0);
-        Assert.assertEquals(firstEntity.getPolicies().size(), 0);
-        
-        Asserts.eventually(new Supplier<Integer>() {
-            @Override
-            public Integer get() {
-                return child.getPolicies().size();
-            }
-        }, Predicates.<Integer> equalTo(1));
-        
-        Policy policy = child.getPolicies().iterator().next();
-        Assert.assertTrue(policy instanceof TestPolicy);
-        Assert.assertEquals(policy.getConfig(TestPolicy.TEST_ATTRIBUTE_SENSOR), TestEntity.NAME);
-    }
-    
-    @Test
-    public void testMultiplePolicyReferences() throws Exception {
-        final Entity app = createAndStartApplication(loadYaml("test-referencing-policies.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-referencing-policies");
-        
-        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
-        
-        Assert.assertEquals(app.getChildren().size(), 2);
-        for (Entity child : app.getChildren()) {
-            if (child.getDisplayName().equals("entity 1"))
-                entity1 = child;
-            if (child.getDisplayName().equals("entity 2"))
-                entity2 = child;
-        }
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-        
-        Assert.assertEquals(entity1.getChildren().size(), 2);
-        for (Entity child : entity1.getChildren()) {
-            if (child.getDisplayName().equals("child 1"))
-                child1 = child;
-            if (child.getDisplayName().equals("child 2"))
-                child2 = child;
-        }
-        Assert.assertNotNull(child1);
-        Assert.assertNotNull(child2);
-        
-        Assert.assertEquals(child1.getChildren().size(), 2);
-        for (Entity child : child1.getChildren()) {
-            if (child.getDisplayName().equals("grandchild 1"))
-               grandchild1 = child;
-            if (child.getDisplayName().equals("grandchild 2"))
-                grandchild2 = child;
-        }
-        Assert.assertNotNull(grandchild1);
-        Assert.assertNotNull(grandchild2);
-        
-        ImmutableSet<Policy> policies = new ImmutableSet.Builder<Policy>()
-                .add(getPolicy(app))
-                .add(getPolicy(entity1))
-                .add(getPolicy(entity2))
-                .add(getPolicy(child1))
-                .add(getPolicy(child2))
-                .add(getPolicy(grandchild1))
-                .add(getPolicy(grandchild2))
-                .build();
-        
-        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY2, entity2)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD1, child1)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD2, child2)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD1, grandchild1)
-                .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD2, grandchild2)
-                .build();
-        
-        for (Policy policy : policies)
-            checkReferences(policy, keyToEntity);
-        
-    }
-    
-    private void checkReferences(final Policy policy, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
-        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
-            final Entity entity = keyToEntity.get(key); // Grab an entity whose execution context we can use
-            Entity fromConfig = ((EntityInternal)entity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
-                @Override
-                public Entity call() throws Exception {
-                    return (Entity) policy.getConfig(key);
-                }
-            }).get();
-            Assert.assertEquals(fromConfig, keyToEntity.get(key));
-        }
-    }
-    
-    private Policy getPolicy(Entity entity) {
-        Assert.assertEquals(entity.getPolicies().size(), 1);
-        Policy policy = entity.getPolicies().iterator().next();
-        Assert.assertTrue(policy instanceof TestReferencingPolicy);
-        return policy;
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencedYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencedYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencedYamlTest.java
deleted file mode 100644
index 6c10779..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencedYamlTest.java
+++ /dev/null
@@ -1,180 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicApplication;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.management.osgi.OsgiStandaloneTest;
-
-import com.google.common.collect.Iterables;
-
-public class ReferencedYamlTest extends AbstractYamlTest {
-    
-    @Test
-    public void testReferenceEntityYamlAsPlatformComponent() throws Exception {
-        String entityName = "Reference child name";
-        Entity app = createAndStartApplication(
-            "services:",
-            "- name: " + entityName,
-            "  type: classpath://yaml-ref-entity.yaml");
-        
-        checkChildEntitySpec(app, entityName);
-    }
-
-    @Test
-    public void testAnonymousReferenceEntityYamlAsPlatformComponent() throws Exception {
-        Entity app = createAndStartApplication(
-            "services:",
-            "- type: classpath://yaml-ref-entity.yaml");
-        
-        checkChildEntitySpec(app, "service");
-    }
-
-    @Test
-    public void testReferenceAppYamlAsPlatformComponent() throws Exception {
-        Entity app = createAndStartApplication(
-            "services:",
-            "- name: Reference child name",
-            "  type: classpath://yaml-ref-app.yaml");
-        
-        Assert.assertEquals(app.getChildren().size(), 0);
-        Assert.assertEquals(app.getDisplayName(), "Reference child name");
-
-        //child is a proxy so equality test won't do
-        Assert.assertEquals(app.getEntityType().getName(), BasicApplication.class.getName());
-    }
-
-    @Test
-    public void testReferenceYamlAsChild() throws Exception {
-        String entityName = "Reference child name";
-        Entity createAndStartApplication = createAndStartApplication(
-            "services:",
-            "- type: brooklyn.entity.basic.BasicEntity",
-            "  brooklyn.children:",
-            "  - name: " + entityName,
-            "    type: classpath://yaml-ref-entity.yaml");
-        
-        checkGrandchildEntitySpec(createAndStartApplication, entityName);
-    }
-
-    @Test
-    public void testAnonymousReferenceYamlAsChild() throws Exception {
-        Entity createAndStartApplication = createAndStartApplication(
-            "services:",
-            "- type: brooklyn.entity.basic.BasicEntity",
-            "  brooklyn.children:",
-            "  - type: classpath://yaml-ref-entity.yaml");
-        
-        checkGrandchildEntitySpec(createAndStartApplication, "service");
-    }
-
-    @Test
-    public void testCatalogReferencingYamlUrl() throws Exception {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: yaml.reference",
-            "  version: " + TEST_VERSION,
-            "services:",
-            "- type: classpath://yaml-ref-entity.yaml");
-        
-        String entityName = "YAML -> catalog item -> yaml url";
-        Entity app = createAndStartApplication(
-            "services:",
-            "- name: " + entityName,
-            "  type: " + ver("yaml.reference"));
-        
-        checkChildEntitySpec(app, entityName);
-    }
-
-    @Test
-    public void testYamlUrlReferencingCatalog() throws Exception {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: yaml.basic",
-            "  version: " + TEST_VERSION,
-            "services:",
-            "- type: brooklyn.entity.basic.BasicEntity");
-        
-        String entityName = "YAML -> yaml url -> catalog item";
-        Entity app = createAndStartApplication(
-            "services:",
-            "- name: " + entityName,
-            "  type: classpath://yaml-ref-catalog.yaml");
-        
-        checkChildEntitySpec(app, entityName);
-    }
-
-    /**
-     * Tests that a YAML referenced by URL from a catalog item
-     * will have access to the catalog item's bundles.
-     */
-    @Test
-    public void testCatalogLeaksBundlesToReferencedYaml() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String parentCatalogId = "my.catalog.app.id.url.parent";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + parentCatalogId,
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "services:",
-            "- type: classpath://yaml-ref-bundle-without-libraries.yaml");
-
-        Entity app = createAndStartApplication(
-            "services:",
-                "- type: " + ver(parentCatalogId));
-        
-        Collection<Entity> children = app.getChildren();
-        Assert.assertEquals(children.size(), 1);
-        Entity child = Iterables.getOnlyElement(children);
-        Assert.assertEquals(child.getEntityType().getName(), "brooklyn.osgi.tests.SimpleEntity");
-
-        deleteCatalogEntity(parentCatalogId);
-    }
-
-    private void checkChildEntitySpec(Entity app, String entityName) {
-        Collection<Entity> children = app.getChildren();
-        Assert.assertEquals(children.size(), 1);
-        Entity child = Iterables.getOnlyElement(children);
-        Assert.assertEquals(child.getDisplayName(), entityName);
-        Assert.assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
-    }
-
-    private void checkGrandchildEntitySpec(Entity createAndStartApplication, String entityName) {
-        Collection<Entity> children = createAndStartApplication.getChildren();
-        Assert.assertEquals(children.size(), 1);
-        Entity child = Iterables.getOnlyElement(children);
-        Collection<Entity> grandChildren = child.getChildren();
-        Assert.assertEquals(grandChildren.size(), 1);
-        Entity grandChild = Iterables.getOnlyElement(grandChildren);
-        Assert.assertEquals(grandChild.getDisplayName(), entityName);
-        Assert.assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
deleted file mode 100644
index 02d778a..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
+++ /dev/null
@@ -1,66 +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 io.brooklyn.camp.brooklyn;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.event.basic.BasicConfigKey;
-
-import com.google.common.reflect.TypeToken;
-
-@ImplementedBy(ReferencingYamlTestEntityImpl.class)
-public interface ReferencingYamlTestEntity extends Entity {
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_APP = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.app")
-            .build();
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.entity1")
-            .build();    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY1_ALT = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.entity1a")
-            .build();    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.entity2")
-            .build();
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_CHILD1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.child1")
-            .build();
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_CHILD2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.child2")
-            .build(); 
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_GRANDCHILD1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.grandchild1")
-            .build();
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_GRANDCHILD2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.grandchild2")
-            .build(); 
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Entity> TEST_REFERENCE_BOGUS = BasicConfigKey.builder(new TypeToken<Entity>(){})
-            .name("test.reference.bogus")
-            .build(); 
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
deleted file mode 100644
index 1bf83f4..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
+++ /dev/null
@@ -1,25 +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 io.brooklyn.camp.brooklyn;
-
-import brooklyn.entity.basic.AbstractApplication;
-
-public class ReferencingYamlTestEntityImpl extends AbstractApplication implements ReferencingYamlTestEntity {
-   
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
deleted file mode 100644
index a049de4..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
+++ /dev/null
@@ -1,87 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-
-import java.io.Reader;
-
-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 brooklyn.entity.Entity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.trait.Startable;
-import brooklyn.management.ManagementContext;
-import brooklyn.test.EntityTestUtils;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.stream.Streams;
-
-public class ReloadBrooklynPropertiesTest {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(ReloadBrooklynPropertiesTest.class);
-    
-    private ManagementContext brooklynMgmt;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        brooklynMgmt = new BrooklynCampPlatformLauncherNoServer().launch().getBrooklynMgmt();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void teardown() {
-        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
-    }
-    
-    @Test
-    public void testReloadBrooklynPropertiesNonDeploy() {
-        CampPlatform platform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
-        Assert.assertNotNull(platform);
-        brooklynMgmt.reloadBrooklynProperties();
-        CampPlatform reloadedPlatform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
-        Assert.assertEquals(reloadedPlatform, platform);
-    }
-    
-    @Test
-    public void testReloadBrooklynPropertiesDeploy() {
-        brooklynMgmt.reloadBrooklynProperties();
-        CampPlatform reloadedPlatform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
-        Assert.assertNotNull(reloadedPlatform);
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("test-entity-basic-template.yaml"));
-        AssemblyTemplate template = reloadedPlatform.pdp().registerDeploymentPlan(input);
-        try {
-            Assembly assembly = template.getInstantiator().newInstance().instantiate(template, reloadedPlatform);
-            LOG.info("Test - created " + assembly);
-            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-            LOG.info("App - " + app);
-            Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-            EntityTestUtils.assertAttributeEqualsEventually(app, Startable.SERVICE_UP, true);
-        } catch (Exception e) {
-            LOG.warn("Unable to instantiate " + template + " (rethrowing): " + e);
-            throw Exceptions.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java
deleted file mode 100644
index 1028859..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfig.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 io.brooklyn.camp.brooklyn;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.entity.trait.Startable;
-import brooklyn.event.basic.BasicConfigKey;
-
-@ImplementedBy(TestEntityWithInitConfigImpl.class)
-public interface TestEntityWithInitConfig extends Entity, Startable, EntityLocal, EntityInternal {
-    public static final ConfigKey<Entity> TEST_ENTITY = BasicConfigKey.builder(Entity.class)
-            .name("test.entity")
-            .build();
-    public Entity getEntityCachedOnInit();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
deleted file mode 100644
index 0cd516f..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
+++ /dev/null
@@ -1,59 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Collection;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.location.Location;
-
-public class TestEntityWithInitConfigImpl extends AbstractEntity implements TestEntityWithInitConfig {
-
-    private static final Logger LOG = LoggerFactory.getLogger(TestEntityWithInitConfigImpl.class);
-    private Entity entityCachedOnInit;
-    
-    @Override
-    public void init() {
-        super.init();
-        entityCachedOnInit = getConfig(TEST_ENTITY);
-    }
-    
-    @Override
-    public void start(Collection<? extends Location> locations) {
-        LOG.trace("Starting {}", this);
-    }
-
-    @Override
-    public void stop() {
-        LOG.trace("Stopping {}", this);
-    }
-
-    @Override
-    public void restart() {
-        LOG.trace("Restarting {}", this);
-    }
-
-    public Entity getEntityCachedOnInit() {
-        return entityCachedOnInit;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingEnricher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingEnricher.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingEnricher.java
deleted file mode 100644
index 5a95eb8..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingEnricher.java
+++ /dev/null
@@ -1,34 +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 io.brooklyn.camp.brooklyn;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.entity.Entity;
-import brooklyn.event.basic.BasicConfigKey;
-
-public class TestReferencingEnricher extends AbstractEnricher {
-    public static final ConfigKey<Entity> TEST_APPLICATION = new BasicConfigKey<Entity>(Entity.class, "test.reference.app");
-    public static final ConfigKey<Entity> TEST_ENTITY_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity1");
-    public static final ConfigKey<Entity> TEST_ENTITY_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity2");
-    public static final ConfigKey<Entity> TEST_CHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child1");
-    public static final ConfigKey<Entity> TEST_CHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child2");
-    public static final ConfigKey<Entity> TEST_GRANDCHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild1");
-    public static final ConfigKey<Entity> TEST_GRANDCHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild2");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingPolicy.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingPolicy.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingPolicy.java
deleted file mode 100644
index 1050402..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestReferencingPolicy.java
+++ /dev/null
@@ -1,34 +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 io.brooklyn.camp.brooklyn;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.policy.basic.AbstractPolicy;
-
-public class TestReferencingPolicy extends AbstractPolicy {
-    public static final ConfigKey<Entity> TEST_APPLICATION = new BasicConfigKey<Entity>(Entity.class, "test.reference.app");
-    public static final ConfigKey<Entity> TEST_ENTITY_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity1");
-    public static final ConfigKey<Entity> TEST_ENTITY_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity2");
-    public static final ConfigKey<Entity> TEST_CHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child1");
-    public static final ConfigKey<Entity> TEST_CHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child2");
-    public static final ConfigKey<Entity> TEST_GRANDCHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild1");
-    public static final ConfigKey<Entity> TEST_GRANDCHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild2");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
deleted file mode 100644
index 4e42d8d..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
+++ /dev/null
@@ -1,86 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Map;
-
-import org.testng.Assert;
-
-import com.google.common.base.Preconditions;
-
-import brooklyn.entity.Effector;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.effector.EffectorBody;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.entity.proxying.EntityInitializer;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.util.config.ConfigBag;
-
-public class TestSensorAndEffectorInitializer implements EntityInitializer {
-
-    public static final String EFFECTOR_SAY_HELLO = "sayHello";
-    public static final String SENSOR_LAST_HELLO = "lastHello";
-    public static final String SENSOR_HELLO_DEFINED = "sensorHelloDefined";
-    public static final String SENSOR_HELLO_DEFINED_EMITTED = "sensorHelloDefinedEmitted";
-
-    protected String helloWord() { return "Hello"; }
-    
-    @Override
-    public void apply(EntityLocal entity) {
-        Effector<String> eff = Effectors.effector(String.class, EFFECTOR_SAY_HELLO).parameter(String.class, "name").impl(
-            new EffectorBody<String>() {
-                @Override
-                public String call(ConfigBag parameters) {
-                    Object name = parameters.getStringKey("name");
-                    entity().setAttribute(Sensors.newStringSensor(SENSOR_LAST_HELLO), ""+name);
-                    return helloWord()+" "+name;
-                }
-            }).build();
-        ((EntityInternal)entity).getMutableEntityType().addEffector(eff);
-        
-        ((EntityInternal)entity).getMutableEntityType().addSensor(Sensors.newStringSensor(SENSOR_HELLO_DEFINED));
-        
-        AttributeSensor<String> emitted = Sensors.newStringSensor(SENSOR_HELLO_DEFINED_EMITTED);
-        ((EntityInternal)entity).getMutableEntityType().addSensor(emitted);
-        entity.setAttribute(emitted, "1");
-    }
-
-    public static class TestConfigurableInitializer extends TestSensorAndEffectorInitializer {
-        public static final String HELLO_WORD = "helloWord";
-        final String helloWord;
-        public TestConfigurableInitializer(Map<String,String> params) {
-            Preconditions.checkNotNull(params);
-            if (params.containsKey(HELLO_WORD)) {
-                helloWord = params.get(HELLO_WORD);
-                Assert.assertEquals(params.size(), 1);
-            } else {
-                helloWord = "Hello";
-                Assert.assertEquals(params.size(), 0);
-            }
-        }
-        
-        @Override
-        protected String helloWord() {
-            return helloWord;
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
deleted file mode 100644
index dd1b647..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
+++ /dev/null
@@ -1,113 +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 io.brooklyn.camp.brooklyn;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Effector;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityPredicates;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.management.Task;
-import brooklyn.test.EntityTestUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-import brooklyn.util.text.StringPredicates;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-@Test
-public class VanillaBashNetcatYamlTest extends AbstractYamlTest {
-
-    private static final Logger log = LoggerFactory.getLogger(VanillaBashNetcatYamlTest.class);
-
-    private static final AttributeSensor<String> SENSOR_OUTPUT_ALL = Sensors.newStringSensor("output.all");
-    final static Effector<String> EFFECTOR_SAY_HI = Effectors.effector(String.class, "sayHiNetcat").buildAbstract();
-    
-    @Test(groups="Integration")
-    public void testInvocationSensorAndEnricher() throws Exception {
-        Preconditions.checkArgument(Networking.isPortAvailable(4321), "port 4321 must not be in use (no leaked nc instances) for this test to succeed!");
-        
-        Entity app = createAndStartApplication(loadYaml("vanilla-bash-netcat-w-client.yaml"));
-        waitForApplicationTasks(app);
-        
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        Assert.assertEquals(app.getDisplayName(), "Simple Netcat with Client");
-        
-        // comparing by plan ID is one common way
-        Iterable<Entity> netcatI = Iterables.filter(app.getChildren(), EntityPredicates.configEqualTo(BrooklynCampConstants.PLAN_ID, "netcat-server"));
-        Assert.assertTrue(netcatI.iterator().hasNext(), "no 'netcat-server' child of app: "+app.getChildren());
-        Entity netcat = Iterables.getOnlyElement(netcatI);
-        
-        // make sure netcat is running
-        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.RUNNING));
-        
-        // find the pinger, now comparing by name
-        Iterable<Entity> pingerI = Iterables.filter(app.getChildren(), EntityPredicates.displayNameEqualTo("Simple Pinger"));
-        Assert.assertTrue(pingerI.iterator().hasNext(), "no 'Simple Pinger' child of app: "+app.getChildren());
-        Entity pinger = Iterables.getOnlyElement(pingerI);
-
-        // invoke effector
-        Task<String> ping;
-        ping = pinger.invoke(EFFECTOR_SAY_HI, MutableMap.<String,Object>of());
-        Assert.assertEquals(ping.get().trim(), "hello");
-        // and check we get the right result 
-        EntityTestUtils.assertAttributeEventually(netcat, SENSOR_OUTPUT_ALL, StringPredicates.containsLiteral("hi netcat"));
-        log.info("invoked ping from "+pinger+" to "+netcat+", 'all' sensor shows:\n"+
-                netcat.getAttribute(SENSOR_OUTPUT_ALL));
-
-        // netcat should now fail and restart
-        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.not(Predicates.equalTo(Lifecycle.RUNNING)));
-        log.info("detected failure, state is: "+netcat.getAttribute(Attributes.SERVICE_STATE_ACTUAL));
-        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.RUNNING));
-        log.info("detected recovery, state is: "+netcat.getAttribute(Attributes.SERVICE_STATE_ACTUAL));
-
-        // invoke effector again, now with a parameter
-        ping = pinger.invoke(EFFECTOR_SAY_HI, MutableMap.<String,Object>of("message", "yo yo yo"));
-        Assert.assertEquals(ping.get().trim(), "hello");
-        // checking right result
-        EntityTestUtils.assertAttributeEventually(netcat, SENSOR_OUTPUT_ALL, StringPredicates.containsLiteral("yo yo yo"));
-        log.info("invoked ping again from "+pinger+" to "+netcat+", 'all' sensor shows:\n"+
-                netcat.getAttribute(SENSOR_OUTPUT_ALL));
-        
-        // and it's propagated to the app
-        EntityTestUtils.assertAttributeEventually(app, Sensors.newStringSensor("output.last"), StringPredicates.containsLiteral("yo yo yo"));
-        
-        log.info("after all is said and done, app is:");
-        Entities.dumpInfo(app);
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/WrapAppTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/WrapAppTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/WrapAppTest.java
deleted file mode 100644
index b2db240..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/WrapAppTest.java
+++ /dev/null
@@ -1,93 +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 io.brooklyn.camp.brooklyn;
-
-import java.io.StringReader;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.StartableApplication;
-
-public class WrapAppTest extends AbstractYamlTest {
-    private static final String NO_WRAP_APP_IMPLICIT =
-            "name: Empty App\n" +
-            "services:\n" +
-            "   - type: brooklyn.test.entity.TestApplication";
-        
-    private static final String NO_WRAP_APP_EXPLICIT =
-            "name: Empty App\n" +
-            "wrappedApp: false\n" +
-            "services:\n" +
-            "   - type: brooklyn.test.entity.TestApplication";
-        
-    private static final String WRAP_APP_IMPLICIT =
-            "name: Empty App\n" +
-            "services:\n" +
-            "   - type: brooklyn.test.entity.TestApplication\n" +
-            "   - type: brooklyn.test.entity.TestApplication";
-        
-    private static final String WRAP_APP_EXPLICIT =
-            "name: Empty App\n" +
-            "wrappedApp: true\n" +
-            "services:\n" +
-            "   - type: brooklyn.test.entity.TestApplication";
-    
-    private static final String WRAP_ENTITY =
-            "name: Empty App\n" +
-            "services:\n" +
-            "   - type: brooklyn.test.entity.TestEntity";
-    
-    @Test
-    public void testNoWrapAppImplicit() throws Exception {
-        StartableApplication app = createApp(NO_WRAP_APP_IMPLICIT);
-        Assert.assertTrue(app.getChildren().size() == 0);
-    }
-    
-    @Test
-    public void testNoWrapAppExplicit() throws Exception {
-        StartableApplication app = createApp(NO_WRAP_APP_EXPLICIT);
-        Assert.assertTrue(app.getChildren().size() == 0);
-    }
-    
-    @Test
-    public void testWrapAppImplicit() throws Exception {
-        StartableApplication app = createApp(WRAP_APP_IMPLICIT);
-        Assert.assertTrue(app.getChildren().size() == 2);
-    }
-    
-    @Test
-    public void testWrapAppExplicit() throws Exception {
-        StartableApplication app = createApp(WRAP_APP_EXPLICIT);
-        Assert.assertTrue(app.getChildren().size() == 1);
-    }
-    
-    @Test
-    public void testWrapEntity() throws Exception {
-        StartableApplication app = createApp(WRAP_ENTITY);
-        Assert.assertTrue(app.getChildren().size() == 1);
-    }
-    
-    private StartableApplication createApp(String yaml) throws Exception {
-        StringReader in = new StringReader(yaml);
-        StartableApplication app = (StartableApplication)createAndStartApplication(in);
-        in.close();
-        return app;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
deleted file mode 100644
index 3110f43..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
+++ /dev/null
@@ -1,109 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.StringReader;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.config.BrooklynServerConfig;
-import brooklyn.entity.Entity;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.management.osgi.OsgiTestResources;
-import brooklyn.test.entity.LocalManagementContextForTests;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.os.Os;
-import brooklyn.util.stream.ReaderInputStream;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.io.ByteStreams;
-
-public class AbstractCatalogXmlTest extends AbstractYamlTest {
-    
-    private String catalogUrl;
-    
-    public AbstractCatalogXmlTest(String catalogUrl) {
-        this.catalogUrl = catalogUrl;
-    }
-    
-    @Override
-    protected LocalManagementContext newTestManagementContext() {
-        ResourceUtils ru = new ResourceUtils(this);
-        File jar = createJar(ru);
-        File catalog = createCatalog(ru, jar);
-
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put(BrooklynServerConfig.BROOKLYN_CATALOG_URL, catalog.toURI().toString());
-        return LocalManagementContextForTests.builder(true)
-                .useProperties(properties)
-                .disableOsgi(false)
-                .build();
-    }
-
-    protected Entity startApp(String type) throws Exception {
-        String yaml = "name: simple-app-yaml\n" +
-                "location: localhost\n" +
-                "services: \n" +
-                "  - type: " + type;
-        return createAndStartApplication(yaml);
-    }
-
-    private File createCatalog(ResourceUtils ru, File tmpJar) {
-        String catalogTemplate = ru.getResourceAsString(catalogUrl);
-        String catalog = catalogTemplate.replace("${osgi-entities-path}", tmpJar.toURI().toString());
-        File catalogTmp = Os.newTempFile("simple-catalog-", ".xml");
-        copy(catalog, catalogTmp);
-        return catalogTmp;
-    }
-
-    private File createJar(ResourceUtils ru) {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-        File tmpJar = Os.newTempFile("osgi-entities-", ".jar");
-        InputStream in = ru.getResourceFromUrl("classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-        copy(in, tmpJar);
-        return tmpJar;
-    }
-
-    private void copy(String src, File dst) {
-        try {
-            copy(new ReaderInputStream(new StringReader(src), "UTF-8"), dst);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    private void copy(InputStream in, File tmpJar) {
-        try {
-            OutputStream out = new FileOutputStream(tmpJar);
-            ByteStreams.copy(in, out);
-            Streams.closeQuietly(in);
-            Streams.closeQuietly(out);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-}


[14/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
deleted file mode 100644
index 67a2009..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlTest.java
+++ /dev/null
@@ -1,182 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.Entities;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.entity.LocalManagementContextForTests;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public abstract class AbstractYamlTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractYamlTest.class);
-    protected static final String TEST_VERSION = "0.1.2";
-
-    private ManagementContext brooklynMgmt;
-    protected BrooklynCampPlatform platform;
-    protected BrooklynCampPlatformLauncherNoServer launcher;
-    private boolean forceUpdate;
-    
-    public AbstractYamlTest() {
-        super();
-    }
-
-    protected ManagementContext mgmt() { return brooklynMgmt; }
-    
-    @BeforeMethod(alwaysRun = true)
-    public void setUp() {
-        forceUpdate = false;
-        launcher = new BrooklynCampPlatformLauncherNoServer() {
-            @Override
-            protected LocalManagementContext newMgmtContext() {
-                return newTestManagementContext();
-            }
-        };
-        launcher.launch();
-        brooklynMgmt = launcher.getBrooklynMgmt();
-        platform = launcher.getCampPlatform();
-    }
-
-    protected LocalManagementContext newTestManagementContext() {
-        // TODO they don't all need osgi, just a few do, so could speed it up by specifying when they do
-        return LocalManagementContextForTests.newInstanceWithOsgi();
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    public void tearDown() {
-        if (brooklynMgmt != null) Entities.destroyAll(brooklynMgmt);
-        if (launcher != null) launcher.stopServers();
-    }
-
-    protected void waitForApplicationTasks(Entity app) {
-        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
-        getLogger().info("Waiting on " + tasks.size() + " task(s)");
-        for (Task<?> t : tasks) {
-            t.blockUntilEnded();
-        }
-    }
-
-    protected Reader loadYaml(String yamlFileName, String ...extraLines) throws Exception {
-        String input = new ResourceUtils(this).getResourceAsString(yamlFileName).trim();
-        StringBuilder builder = new StringBuilder(input);
-        for (String l: extraLines)
-            builder.append("\n").append(l);
-        return new StringReader(builder.toString());
-    }
-    
-    protected Entity createAndStartApplication(String... multiLineYaml) throws Exception {
-        return createAndStartApplication(joinLines(multiLineYaml));
-    }
-    
-    protected Entity createAndStartApplication(String input) throws Exception {
-        return createAndStartApplication(new StringReader(input));
-    }
-
-    protected Entity createAndStartApplication(Reader input) throws Exception {
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-        Assembly assembly;
-        try {
-            assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-        } catch (Exception e) {
-            getLogger().warn("Unable to instantiate " + at + " (rethrowing): " + e);
-            throw e;
-        }
-        getLogger().info("Test - created " + assembly);
-        final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-        getLogger().info("App - " + app);
-        
-        // wait for app to have started
-        Set<Task<?>> tasks = brooklynMgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
-                BrooklynTaskTags.EFFECTOR_TAG, 
-                BrooklynTaskTags.tagForContextEntity(app), 
-                BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
-        Iterables.getOnlyElement(tasks).get();
-        
-        return app;
-    }
-
-    protected Entity createStartWaitAndLogApplication(Reader input) throws Exception {
-        Entity app = createAndStartApplication(input);
-        waitForApplicationTasks(app);
-
-        getLogger().info("App started:");
-        Entities.dumpInfo(app);
-        
-        return app;
-    }
-
-    protected void addCatalogItems(Iterable<String> catalogYaml) {
-        addCatalogItems(joinLines(catalogYaml));
-    }
-
-    protected void addCatalogItems(String... catalogYaml) {
-        addCatalogItems(joinLines(catalogYaml));
-    }
-
-    protected void addCatalogItems(String catalogYaml) {
-        mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
-    }
-
-    protected void deleteCatalogEntity(String catalogItem) {
-        mgmt().getCatalog().deleteCatalogItem(catalogItem, TEST_VERSION);
-    }
-
-    protected Logger getLogger() {
-        return LOG;
-    }
-
-    private String joinLines(Iterable<String> catalogYaml) {
-        return Joiner.on("\n").join(catalogYaml);
-    }
-
-    private String joinLines(String[] catalogYaml) {
-        return Joiner.on("\n").join(catalogYaml);
-    }
-
-    protected String ver(String id) {
-        return CatalogUtils.getVersionedId(id, TEST_VERSION);
-    }
-
-    public void forceCatalogUpdate() {
-        forceUpdate = true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AppYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AppYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AppYamlTest.java
deleted file mode 100644
index 26784ff..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AppYamlTest.java
+++ /dev/null
@@ -1,119 +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 io.brooklyn.camp.brooklyn;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.io.StringReader;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import com.google.api.client.repackaged.com.google.common.base.Joiner;
-import com.google.common.collect.Iterables;
-
-import brooklyn.entity.basic.BasicApplication;
-import brooklyn.test.entity.TestApplication;
-import brooklyn.test.entity.TestEntity;
-
-@Test
-public class AppYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(AppYamlTest.class);
-
-    @Test
-    public void testAutoWrapsEntityInApp() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestEntity");
-        
-        BasicApplication app = (BasicApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        @SuppressWarnings("unused")
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-    }
-    
-    @Test
-    public void testDoesNotAutoWrapApp() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestApplication");
-        
-        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        assertTrue(app.getChildren().isEmpty());
-    }
-    
-    @Test
-    public void testWrapsAppIfNameAtTopLevelAndOnApp() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "name: myTopLevelName",
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestApplication",
-                "  name: myEntityName");
-        
-        BasicApplication app = (BasicApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestApplication entity = (TestApplication) Iterables.getOnlyElement(app.getChildren());
-        assertEquals(app.getDisplayName(), "myTopLevelName");
-        assertEquals(entity.getDisplayName(), "myEntityName");
-    }
-    
-    @Test
-    public void testDoesNotWrapAppIfNoConflictingNameOnApp() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "name: myTopLevelName",
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestApplication");
-        
-        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        assertTrue(app.getChildren().isEmpty());
-        assertEquals(app.getDisplayName(), "myTopLevelName");
-    }
-    
-    @Test
-    public void testDoesNotWrapAppWithDefaultDisplayName() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "name: myTopLevelName",
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestApplication",
-                "  brooklyn.config:",
-                "    defaultDisplayName: myDefaultEntityName");
-        
-        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        assertTrue(app.getChildren().isEmpty());
-        assertEquals(app.getDisplayName(), "myTopLevelName");
-    }
-    
-    @Test
-    public void testUsesDefaultDisplayNameIfNoOther() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "services:",
-                "- serviceType: brooklyn.test.entity.TestApplication",
-                "  brooklyn.config:",
-                "    defaultDisplayName: myDefaultEntityName");
-        
-        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        assertTrue(app.getChildren().isEmpty());
-        assertEquals(app.getDisplayName(), "myDefaultEntityName");
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
deleted file mode 100644
index 61fe084..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
+++ /dev/null
@@ -1,76 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.Factory;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
-import brooklyn.policy.Policy;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.javalang.JavaClassNames;
-import brooklyn.util.time.Duration;
-
-public class BrooklynYamlTypeInstantiatorTest extends AbstractYamlTest {
-
-    protected BrooklynClassLoadingContext loader() {
-        return JavaBrooklynClassLoadingContext.create(mgmt());
-    }
-    
-    @Test
-    public void testLoadPolicySpecProgrammatically() {
-        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
-        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName())).prefix("some");
-        
-        Assert.assertTrue(decoL.getConfigMap().isEmpty());
-        Assert.assertEquals(decoL.getTypeName().get(), ServiceRestarter.class.getName());
-        Assert.assertEquals(decoL.getType(), ServiceRestarter.class);
-        
-        Object sl1 = decoL.newInstance();
-        Assert.assertTrue(sl1 instanceof ServiceRestarter);
-        
-        Policy sl2 = decoL.newInstance(Policy.class);
-        Assert.assertTrue(sl2 instanceof ServiceRestarter);
-    }
-    
-    @Test
-    public void testLoadPolicySpecWithBrooklynConfig() {
-        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
-        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName(),
-            "brooklyn.config", MutableMap.of("failOnRecurringFailuresInThisDuration", Duration.seconds(42)))).prefix("some");
-        Policy sl2 = decoL.newInstance(Policy.class);
-        Assert.assertEquals(sl2.getConfig(ServiceRestarter.FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION).toSeconds(), 42);
-    }
-
-    @Test(groups = "WIP")
-    public void testLoadPolicySpecWithFlag() {
-        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
-        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName(),
-            "failOnRecurringFailuresInThisDuration", Duration.seconds(42))).prefix("some");
-        Policy sl2 = decoL.newInstance(Policy.class);
-        Assert.assertEquals(sl2.getConfig(ServiceRestarter.FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION).toSeconds(), 42);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
deleted file mode 100644
index eaf3884..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
+++ /dev/null
@@ -1,281 +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 io.brooklyn.camp.brooklyn;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-
-import java.io.StringReader;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import com.google.api.client.repackaged.com.google.common.base.Joiner;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.net.HostAndPort;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.DoNothingSoftwareProcess;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.LocationPredicates;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.test.Asserts;
-import brooklyn.util.net.UserAndHostAndPort;
-
-public class ByonLocationsYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(ByonLocationsYamlTest.class);
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testByonSpec() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location: byon(user=myuser,mykey=myval,hosts=\"1.1.1.1\")",
-                "services:",
-                "- serviceType: brooklyn.entity.basic.BasicApplication");
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(app.getLocations(), 0);
-        
-        Set<SshMachineLocation> machines = loc.getAvailable();
-        SshMachineLocation machine = Iterables.getOnlyElement(machines);
-        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  22), ImmutableMap.of("mykey", "myval"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testByonMachine() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location:",
-                "  byon:",
-                "    hosts:",
-                "    - ssh: 1.1.1.1:8022",
-                "      privateAddresses: [10.0.0.1]",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval",
-                "services:",
-                "- serviceType: brooklyn.entity.basic.BasicApplication");
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(app.getLocations(), 0);
-        
-        Set<SshMachineLocation> machines = loc.getAvailable();
-        SshMachineLocation machine = Iterables.getOnlyElement(machines);
-        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8022), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval"));
-        assertEquals(machine.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testByonWindowsMachine() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location:",
-                "  byon:",
-                "    hosts:",
-                "    - winrm: 1.1.1.1:8985",
-                "      privateAddresses: [10.0.0.1]",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval",
-                "      osfamily: windows",
-                "services:",
-                "- serviceType: brooklyn.entity.basic.BasicApplication");
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        FixedListMachineProvisioningLocation<WinRmMachineLocation> loc = (FixedListMachineProvisioningLocation<WinRmMachineLocation>) Iterables.get(app.getLocations(), 0);
-        
-        Set<WinRmMachineLocation> machines = loc.getAvailable();
-        WinRmMachineLocation machine = Iterables.getOnlyElement(machines);
-        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8985), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval"));
-        assertEquals(machine.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testByonMultiMachine() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location:",
-                "  byon:",
-                "    hosts:",
-                "    - ssh: 1.1.1.1:8022",
-                "      privateAddresses: [10.0.0.1]",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval1",
-                "    - ssh: 1.1.1.2:8022",
-                "      privateAddresses: [10.0.0.2]",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval2",
-                "    - winrm: 1.1.1.3:8985",
-                "      privateAddresses: [10.0.0.3]",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval3",
-                "      osfamily: windows",
-                "services:",
-                "- serviceType: brooklyn.entity.basic.BasicApplication");
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
-        
-        Set<MachineLocation> machines = loc.getAvailable();
-        assertEquals(machines.size(), 3, "machines="+machines);
-        SshMachineLocation machine1 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval1"));
-        SshMachineLocation machine2 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval2"));
-        WinRmMachineLocation machine3 = (WinRmMachineLocation) Iterables.find(machines, Predicates.instanceOf(WinRmMachineLocation.class));
-
-        assertMachine(machine1, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8022), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval1"));
-        assertEquals(machine1.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
-
-        assertMachine(machine2, UserAndHostAndPort.fromParts("myuser", "1.1.1.2",  8022), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval2"));
-        assertEquals(machine2.getPrivateAddresses(), ImmutableSet.of("10.0.0.2"));
-
-        assertMachine(machine3, UserAndHostAndPort.fromParts("myuser", "1.1.1.3",  8985), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval3"));
-        assertEquals(machine3.getPrivateAddresses(), ImmutableSet.of("10.0.0.3"));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testByonPortMapping() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location:",
-                "  byon:",
-                "    hosts:",
-                "    - ssh: 1.1.1.1:22",
-                "      privateAddresses: [10.0.0.1]",
-                "      tcpPortMappings: {22: \"83.222.229.1:12001\", 8080: \"83.222.229.1:12002\"}",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval1",
-                "    - winrm: 1.1.1.2:8985",
-                "      privateAddresses: [10.0.0.2]",
-                "      tcpPortMappings: {8985: \"83.222.229.2:12003\", 8080: \"83.222.229.2:12004\"}",
-                "      password: mypassword",
-                "      user: myuser",
-                "      mykey: myval2",
-                "      osfamily: windows",
-                "services:",
-                "- serviceType: brooklyn.entity.basic.BasicApplication");
-
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
-        PortForwardManager pfm = (PortForwardManager) mgmt().getLocationRegistry().resolve("portForwardManager(scope=global)");
-        
-        Set<MachineLocation> machines = loc.getAvailable();
-        assertEquals(machines.size(), 2, "machines="+machines);
-        SshMachineLocation machine1 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval1"));
-        WinRmMachineLocation machine2 = (WinRmMachineLocation) Iterables.find(machines, Predicates.instanceOf(WinRmMachineLocation.class));
-
-        assertMachine(machine1, UserAndHostAndPort.fromParts("myuser", "83.222.229.1", 12001), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval1"));
-        assertEquals(machine1.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
-        assertEquals(pfm.lookup(machine1, 22), HostAndPort.fromParts("83.222.229.1", 12001));
-        assertEquals(pfm.lookup(machine1, 8080), HostAndPort.fromParts("83.222.229.1", 12002));
-        assertNull(pfm.lookup(machine1, 12345));
-        
-        assertMachine(machine2, UserAndHostAndPort.fromParts("myuser", "83.222.229.2",  12003), ImmutableMap.of(
-                SshMachineLocation.PASSWORD.getName(), "mypassword",
-                "mykey", "myval2"));
-        assertEquals(machine2.getPrivateAddresses(), ImmutableSet.of("10.0.0.2"));
-        assertEquals(pfm.lookup(machine2, 8985), HostAndPort.fromParts("83.222.229.2", 12003));
-        assertEquals(pfm.lookup(machine2, 8080), HostAndPort.fromParts("83.222.229.2", 12004));
-        assertNull(pfm.lookup(machine2, 12345));
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testPassesInboundPortsToMachineAndRemovesOnceMachineReleased() throws Exception {
-        String yaml = Joiner.on("\n").join(
-                "location:",
-                "  byon:",
-                "    hosts:",
-                "    - ssh: 1.1.1.1:22",
-                "      password: mypassword",
-                "      user: myuser",
-                "services:",
-                "- type: brooklyn.entity.basic.DoNothingSoftwareProcess",
-                "  brooklyn.config:",
-                "    requiredOpenLoginPorts: [22, 1024]");
-
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        DoNothingSoftwareProcess entity = (DoNothingSoftwareProcess) Iterables.find(Entities.descendants(app), Predicates.instanceOf(DoNothingSoftwareProcess.class));
-        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
-        
-        // Machine should have been given the inbound-ports
-        SshMachineLocation machine = Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
-        Asserts.assertEqualsIgnoringOrder((Iterable<?>)machine.config().get(CloudLocationConfig.INBOUND_PORTS), ImmutableList.of(22, 1024));
-        
-        // Stop the entity; should release the machine
-        entity.stop();
-        MachineLocation availableMachine = Iterables.getOnlyElement(loc.getAvailable());
-        assertEquals(availableMachine, machine);
-        assertNull(machine.config().get(CloudLocationConfig.INBOUND_PORTS));
-    }
-
-    private void assertMachine(SshMachineLocation machine, UserAndHostAndPort conn, Map<String, ?> config) {
-        assertEquals(machine.getAddress().getHostAddress(), conn.getHostAndPort().getHostText());
-        assertEquals(machine.getPort(), conn.getHostAndPort().getPort());
-        assertEquals(machine.getUser(), conn.getUser());
-        for (Map.Entry<String, ?> entry : config.entrySet()) {
-            Object actualVal = machine.getConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()));
-            assertEquals(actualVal, entry.getValue());
-        }
-    }
-    
-    private void assertMachine(WinRmMachineLocation machine, UserAndHostAndPort conn, Map<String, ?> config) {
-        assertEquals(machine.getAddress().getHostAddress(), conn.getHostAndPort().getHostText());
-        assertEquals(machine.getConfig(WinRmMachineLocation.WINRM_PORT), (Integer) conn.getHostAndPort().getPort());
-        assertEquals(machine.getUser(), conn.getUser());
-        for (Map.Entry<String, ?> entry : config.entrySet()) {
-            Object actualVal = machine.getConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()));
-            assertEquals(actualVal, entry.getValue());
-        }
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
deleted file mode 100644
index c90104f..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
+++ /dev/null
@@ -1,245 +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 io.brooklyn.camp.brooklyn;
-
-import java.io.File;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.event.Sensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.task.Tasks;
-
-import com.google.common.collect.Iterables;
-import com.google.common.io.Files;
-
-@Test
-public class DslAndRebindYamlTest extends AbstractYamlTest {
-    
-    private static final Logger log = LoggerFactory.getLogger(DslAndRebindYamlTest.class);
-    
-    protected ClassLoader classLoader = getClass().getClassLoader();
-    protected File mementoDir;
-    protected Set<ManagementContext> mgmtContexts = MutableSet.of();
-
-    @Override
-    protected LocalManagementContext newTestManagementContext() {
-        if (mementoDir!=null) throw new IllegalStateException("already created mgmt context");
-        mementoDir = Files.createTempDir();
-        LocalManagementContext mgmt = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
-        mgmtContexts.add(mgmt);
-        return mgmt;
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    @Override
-    public void tearDown() {
-        for (ManagementContext mgmt: mgmtContexts) Entities.destroyAll(mgmt);
-        super.tearDown();
-        mementoDir = null;
-        mgmtContexts.clear();
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-
-    public Application rebind(Application app) throws Exception {
-        RebindTestUtils.waitForPersisted(app);
-        // not strictly needed, but for good measure:
-        RebindTestUtils.checkCurrentMementoSerializable(app);
-        Application result = RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
-        mgmtContexts.add(result.getManagementContext());
-        return result;
-    }
-
-
-    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-        
-        return (TestEntity)entity;
-    }
-
-    public static <T> T getConfigInTask(final Entity entity, final ConfigKey<T> key) {
-        return Entities.submit(entity, Tasks.<T>builder().body(new Callable<T>() {
-            @Override
-            public T call() throws Exception {
-                return entity.getConfig(key);
-            }
-        }).build()).getUnchecked();
-    }
-    
-    @Test
-    public void testDslAttributeWhenReady() throws Exception {
-        Entity testEntity = entityWithAttributeWhenReady();
-        ((EntityInternal)testEntity).setAttribute(Sensors.newStringSensor("foo"), "bar");
-        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "bar");
-    }
-
-    @Test
-    public void testDslAttributeWhenReadyRebind() throws Exception {
-        Entity testEntity = entityWithAttributeWhenReady();
-        ((EntityInternal)testEntity).setAttribute(Sensors.newStringSensor("foo"), "bar");
-        Application app2 = rebind(testEntity.getApplication());
-        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
-        
-        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "bar");
-    }
-
-    private Entity entityWithAttributeWhenReady() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.confName: $brooklyn:component(\"x\").attributeWhenReady(\"foo\")");
-    }
-
-    private void doTestOnEntityWithSensor(Entity testEntity, Sensor<?> expectedSensor) throws Exception {
-        doTestOnEntityWithSensor(testEntity, expectedSensor, true);
-    }
-    private void doTestOnEntityWithSensor(Entity testEntity, Sensor<?> expectedSensor, boolean inTask) throws Exception {
-        @SuppressWarnings("rawtypes")
-        ConfigKey<Sensor> configKey = ConfigKeys.newConfigKey(Sensor.class, "test.sensor");
-        Sensor<?> s;
-        s = inTask ? getConfigInTask(testEntity, configKey) : testEntity.getConfig(configKey);
-        Assert.assertEquals(s, expectedSensor);
-        Application app2 = rebind(testEntity.getApplication());
-        Entity te2 = Iterables.getOnlyElement( app2.getChildren() );
-        s = inTask ? getConfigInTask(te2, configKey) : te2.getConfig(configKey);
-        Assert.assertEquals(s, expectedSensor);
-    }
-    
-    @Test
-    public void testDslSensorFromClass() throws Exception {
-        doTestOnEntityWithSensor(entityWithSensorFromClass(), Attributes.SERVICE_UP);
-        // without context it can still find it
-        doTestOnEntityWithSensor(entityWithSensorFromClass(), Attributes.SERVICE_UP, false);
-    }
-    @Test
-    public void testDslSensorLocal() throws Exception {
-        doTestOnEntityWithSensor(entityWithSensorLocal(), TestEntity.SEQUENCE);
-        // here without context it makes one up, so type info (and description etc) not present; 
-        // but context is needed to submit the DslDeferredSupplier object, so this would fail
-//        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, TestEntity.SEQUENCE.getName()), false);
-    }
-    @Test
-    public void testDslSensorAdHoc() throws Exception {
-        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, "sensor.foo"));
-        // here context has no impact, but it is needed to submit the DslDeferredSupplier object so this would fail
-//        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, "sensor.foo"), false);
-    }
-    
-    private Entity entityWithSensorFromClass() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.sensor: $brooklyn:sensor(\""+Attributes.class.getName()+"\", \""+Attributes.SERVICE_UP.getName()+"\")");
-    }
-
-    private Entity entityWithSensorLocal() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.sensor: $brooklyn:sensor(\""+TestEntity.SEQUENCE.getName()+"\")");
-    }
-
-    private Entity entityWithSensorAdHoc() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.sensor: $brooklyn:sensor(\"sensor.foo\")");
-    }
-
-
-    @Test
-    public void testDslConfigFromRoot() throws Exception {
-        Entity testEntity = entityWithConfigFromRoot();
-        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "bar");
-    }
-
-    @Test
-    public void testDslConfigFromRootRebind() throws Exception {
-        Entity testEntity = entityWithConfigFromRoot();
-        Application app2 = rebind(testEntity.getApplication());
-        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
-        
-        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "bar");
-    }
-
-    private Entity entityWithConfigFromRoot() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.confName: $brooklyn:component(\"x\").config(\"foo\")",
-            "brooklyn.config:",
-            "  foo: bar");
-    }
-
-
-    @Test
-    public void testDslFormatString() throws Exception {
-        Entity testEntity = entityWithFormatString();
-        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "hello world");
-    }
-
-    @Test
-    public void testDslFormatStringRebind() throws Exception {
-        Entity testEntity = entityWithFormatString();
-        Application app2 = rebind(testEntity.getApplication());
-        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
-        
-        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "hello world");
-    }
-
-    private Entity entityWithFormatString() throws Exception {
-        return setupAndCheckTestEntityInBasicYamlWith( 
-            "  id: x",
-            "  brooklyn.config:",
-            "    test.confName: $brooklyn:formatString(\"hello %s\", \"world\")");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
deleted file mode 100644
index 9b7bc7b..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
+++ /dev/null
@@ -1,103 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.EmptySoftwareProcess;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.Jsonya;
-
-@Test
-public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(EnrichersYamlTest.class);
-
-    @Test(groups="Integration")
-    public void testProvisioningProperties() throws Exception {
-        Entity app = createAndStartApplication(
-            "location: localhost",
-            "services:",
-            "- type: "+EmptySoftwareProcess.class.getName(),
-            "  provisioning.properties:",
-            "    minRam: 16384");
-        waitForApplicationTasks(app);
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        EmptySoftwareProcess entity = (EmptySoftwareProcess) app.getChildren().iterator().next();
-        Map<String, Object> pp = entity.getConfig(EmptySoftwareProcess.PROVISIONING_PROPERTIES);
-        Assert.assertEquals(pp.get("minRam"), 16384);
-    }
-
-    @Test(groups="Integration")
-    public void testProvisioningPropertiesViaJsonya() throws Exception {
-        Entity app = createAndStartApplication(
-            Jsonya.newInstance()
-                .put("location", "localhost")
-                .at("services").list()
-                .put("type", EmptySoftwareProcess.class.getName())
-                .at("provisioning.properties").put("minRam", 16384)
-                .root().toString());
-        waitForApplicationTasks(app);
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        EmptySoftwareProcess entity = (EmptySoftwareProcess) app.getChildren().iterator().next();
-        Map<String, Object> pp = entity.getConfig(EmptySoftwareProcess.PROVISIONING_PROPERTIES);
-        Assert.assertEquals(pp.get("minRam"), 16384);
-    }
-
-    // for https://github.com/brooklyncentral/brooklyn/issues/1377
-    @Test(groups="Integration")
-    public void testWithAppAndEntityLocations() throws Exception {
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: "+EmptySoftwareProcess.class.getName(),
-                "  location: localhost:(name=localhost on entity)",
-                "location: byon:(hosts=\"127.0.0.1\", name=loopback on app)");
-        waitForApplicationTasks(app);
-        Entities.dumpInfo(app);
-        
-        Assert.assertEquals(app.getLocations().size(), 1);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        
-        Location appLocation = app.getLocations().iterator().next();
-        Assert.assertEquals(appLocation.getDisplayName(), "loopback on app");
-        
-        Assert.assertEquals(entity.getLocations().size(), 2);
-        Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
-        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost on entity");
-        Location actualMachine = entityLocationIterator.next();
-        Assert.assertTrue(actualMachine instanceof SshMachineLocation, "wrong location: "+actualMachine);
-        // TODO this, below, probably should be 'localhost on entity', see #1377
-        Assert.assertEquals(actualMachine.getParent().getDisplayName(), "loopback on app");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
deleted file mode 100644
index 9001824..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
+++ /dev/null
@@ -1,134 +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 io.brooklyn.camp.brooklyn;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import brooklyn.event.basic.Sensors;
-import brooklyn.test.EntityTestUtils;
-import brooklyn.util.collections.CollectionFunctionals;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.math.MathPredicates;
-import brooklyn.util.text.StringPredicates;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-/** Tests some improvements to enricher classes to make them a bit more yaml friendly.
- * Called "SlightlySimpler" as it would be nice to make enrichers a lot more yaml friendly! */
-@Test
-public class EnrichersSlightlySimplerYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(EnrichersSlightlySimplerYamlTest.class);
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Test
-    public void testWithAppEnricher() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-app-with-enrichers-slightly-simpler.yaml"));
-        waitForApplicationTasks(app);
-        log.info("Started "+app+":");
-        Entities.dumpInfo(app);
-        
-        Entity cluster = Iterables.getOnlyElement( app.getChildren() );
-        Collection<Entity> leafs = ((DynamicCluster)cluster).getMembers();
-        Iterator<Entity> li = leafs.iterator();
-        
-        Entity e1 = li.next();
-        ((EntityInternal)e1).setAttribute(Sensors.newStringSensor("ip"), "127.0.0.1");
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Sensors.newStringSensor("url"), "http://127.0.0.1/");
-        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.MAIN_URI, URI.create("http://127.0.0.1/"));
-
-        int i=2;
-        while (li.hasNext()) {
-            Entity ei = li.next();
-            ((EntityInternal)ei).setAttribute(Sensors.newStringSensor("ip"), "127.0.0."+i);
-            i++;
-        }
-        
-        EntityTestUtils.assertAttributeEventually(cluster, Sensors.newSensor(Iterable.class, "urls.list"),
-            (Predicate)CollectionFunctionals.sizeEquals(3));
-        
-        EntityTestUtils.assertAttributeEventually(cluster, Sensors.newSensor(String.class, "urls.list.comma_separated.max_2"),
-            StringPredicates.matchesRegex("\"http:\\/\\/127[^\"]*\\/\",\"http:\\/\\/127[^\"]*\\/\""));
-
-        EntityTestUtils.assertAttributeEventually(cluster, Attributes.MAIN_URI, Predicates.notNull());
-        URI main = cluster.getAttribute(Attributes.MAIN_URI);
-        Assert.assertTrue(main.toString().matches("http:\\/\\/127.0.0..\\/"), "Wrong URI: "+main);
-        
-        EntityTestUtils.assertAttributeEventually(app, Attributes.MAIN_URI, Predicates.notNull());
-        main = app.getAttribute(Attributes.MAIN_URI);
-        Assert.assertTrue(main.toString().matches("http:\\/\\/127.0.0..\\/"), "Wrong URI: "+main);
-        
-        // TODO would we want to allow "all-but-usual" as the default if nothing specified
-    }
-    
-    @Test(groups="Integration")
-    public void testWebappWithAveragingEnricher() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-webapp-with-averaging-enricher.yaml"));
-        waitForApplicationTasks(app);
-        log.info("Started "+app+":");
-        Entities.dumpInfo(app);
-
-        List<JavaWebAppSoftwareProcess> appservers = MutableList.copyOf(Entities.descendants(app, JavaWebAppSoftwareProcess.class));
-        Assert.assertEquals(appservers.size(), 3);
-        
-        EntityInternal srv0 = (EntityInternal) appservers.get(0);
-        EntityInternal dwac = (EntityInternal) srv0.getParent();
-        EntityInternal cdwac = (EntityInternal) dwac.getParent();
-        
-        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), 20.0);
-        
-        EntityTestUtils.assertAttributeEventually(dwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            MathPredicates.equalsApproximately(20));
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            MathPredicates.equalsApproximately(20));
-
-        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), null);
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            Predicates.isNull());
-
-        ((EntityInternal) appservers.get(1)).setAttribute(Sensors.newDoubleSensor("my.load"), 10.0);
-        ((EntityInternal) appservers.get(2)).setAttribute(Sensors.newDoubleSensor("my.load"), 20.0);
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            MathPredicates.equalsApproximately(15));
-        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), 0.0);
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            MathPredicates.equalsApproximately(10));
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersYamlTest.java
deleted file mode 100644
index 4391ba9..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EnrichersYamlTest.java
+++ /dev/null
@@ -1,257 +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 io.brooklyn.camp.brooklyn;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.basic.Propagator;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityAdjuncts;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.policy.Enricher;
-import brooklyn.test.Asserts;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.test.policy.TestEnricher;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-@Test
-public class EnrichersYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(EnrichersYamlTest.class);
-
-    @Test
-    public void testWithAppEnricher() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-app-with-enricher.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-app-with-enricher");
-        
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(app).size(), 1);
-        final Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(app).iterator().next();
-        Assert.assertTrue(enricher instanceof TestEnricher, "enricher="+enricher);
-        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_NAME), "Name from YAML");
-        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
-        
-        Entity target = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
-            public Entity call() {
-                return enricher.getConfig(TestEnricher.TARGET_ENTITY);
-            }}).get();
-        Assert.assertNotNull(target);
-        Assert.assertEquals(target.getDisplayName(), "testentity");
-        Assert.assertEquals(target, app.getChildren().iterator().next());
-        Entity targetFromFlag = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
-            public Entity call() {
-                return enricher.getConfig(TestEnricher.TARGET_ENTITY_FROM_FLAG);
-            }}).get();
-        Assert.assertEquals(targetFromFlag, target);
-        Map<?, ?> leftoverProperties = ((TestEnricher) enricher).getLeftoverProperties();
-        Assert.assertEquals(leftoverProperties.get("enricherLiteralValue1"), "Hello");
-        Assert.assertEquals(leftoverProperties.get("enricherLiteralValue2"), "World");
-        Assert.assertEquals(leftoverProperties.size(), 2);
-    }
-    
-    @Test
-    public void testWithEntityEnricher() throws Exception {
-        final Entity app = createAndStartApplication(loadYaml("test-entity-with-enricher.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-entity-with-enricher");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(app).size(), 0);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        final Entity child = app.getChildren().iterator().next();
-        Asserts.eventually(new Supplier<Integer>() {
-            @Override
-            public Integer get() {
-                return EntityAdjuncts.getNonSystemEnrichers(child).size();
-            }
-        }, Predicates.<Integer> equalTo(1));        
-        final Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(child).iterator().next();
-        Assert.assertNotNull(enricher);
-        Assert.assertTrue(enricher instanceof TestEnricher, "enricher=" + enricher + "; type=" + enricher.getClass());
-        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_NAME), "Name from YAML");
-        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
-        
-        Assert.assertEquals(((TestEnricher) enricher).getLeftoverProperties(),
-                ImmutableMap.of("enricherLiteralValue1", "Hello", "enricherLiteralValue2", "World"));
-    }
-    
-    @Test
-    public void testPropagatingEnricher() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-propagating-enricher.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-propagating-enricher");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        TestEntity entity = (TestEntity)app.getChildren().iterator().next();
-        entity.setAttribute(TestEntity.NAME, "New Name");
-        Asserts.eventually(Entities.attributeSupplier(app, TestEntity.NAME), Predicates.<String>equalTo("New Name"));
-    }
-    
-    @Test
-    public void testPropogateChildSensor() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
-                    "  brooklyn.config:",
-                    "    test.confName: parent entity",
-                    "  id: parentId",
-                    "  brooklyn.enrichers:",
-                    "  - enricherType: brooklyn.enricher.basic.Propagator",
-                    "    brooklyn.config:",
-                    "      enricher.producer: $brooklyn:component(\"childId\")",
-                    "      enricher.propagating.propagatingAll: true",
-                    "  brooklyn.children:",
-                    "  - serviceType: brooklyn.test.entity.TestEntity",
-                    "    id: childId",
-                    "    brooklyn.config:",
-                    "      test.confName: Child Name"));
-        waitForApplicationTasks(app);
-        
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        final Entity parentEntity = app.getChildren().iterator().next();
-        Assert.assertTrue(parentEntity instanceof TestEntity, "Expected parent entity to be TestEntity, found:" + parentEntity);
-        Assert.assertEquals(parentEntity.getChildren().size(), 1);
-        Entity childEntity = parentEntity.getChildren().iterator().next();
-        Assert.assertTrue(childEntity instanceof TestEntity, "Expected child entity to be TestEntity, found:" + childEntity);
-        Asserts.eventually(new Supplier<Integer>() {
-            @Override
-            public Integer get() {
-                return EntityAdjuncts.getNonSystemEnrichers(parentEntity).size();
-            }
-        }, Predicates.<Integer>equalTo(1));
-        Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(parentEntity).iterator().next();
-        Asserts.assertTrue(enricher instanceof Propagator, "Expected enricher to be Propagator, found:" + enricher);
-        final Propagator propagator = (Propagator)enricher;
-        Entity producer = ((EntityInternal)parentEntity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
-            public Entity call() {
-                return propagator.getConfig(Propagator.PRODUCER);
-            }}).get();
-        Assert.assertEquals(producer, childEntity);
-        Asserts.assertTrue(Boolean.valueOf(propagator.getConfig(Propagator.PROPAGATING_ALL)), "Expected Propagator.PROPAGATING_ALL to be true");
-        ((TestEntity)childEntity).setAttribute(TestEntity.NAME, "New Name");
-        Asserts.eventually(Entities.attributeSupplier(parentEntity, TestEntity.NAME), Predicates.<String>equalTo("New Name"));
-    }
-    
-    @Test
-    public void testMultipleEnricherReferences() throws Exception {
-        final Entity app = createAndStartApplication(loadYaml("test-referencing-enrichers.yaml"));
-        waitForApplicationTasks(app);
-        
-        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
-        
-        Assert.assertEquals(app.getChildren().size(), 2);
-        for (Entity child : app.getChildren()) {
-            if (child.getDisplayName().equals("entity 1"))
-                entity1 = child;
-            if (child.getDisplayName().equals("entity 2"))
-                entity2 = child;
-        }
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-        
-        Assert.assertEquals(entity1.getChildren().size(), 2);
-        for (Entity child : entity1.getChildren()) {
-            if (child.getDisplayName().equals("child 1"))
-                child1 = child;
-            if (child.getDisplayName().equals("child 2"))
-                child2 = child;
-        }
-        Assert.assertNotNull(child1);
-        Assert.assertNotNull(child2);
-        
-        Assert.assertEquals(child1.getChildren().size(), 2);
-        for (Entity child : child1.getChildren()) {
-            if (child.getDisplayName().equals("grandchild 1"))
-               grandchild1 = child;
-            if (child.getDisplayName().equals("grandchild 2"))
-                grandchild2 = child;
-        }
-        Assert.assertNotNull(grandchild1);
-        Assert.assertNotNull(grandchild2);
-        
-        ImmutableSet<Enricher> enrichers = new ImmutableSet.Builder<Enricher>()
-                .add(getEnricher(app))
-                .add(getEnricher(entity1))
-                .add(getEnricher(entity2))
-                .add(getEnricher(child1))
-                .add(getEnricher(child2))
-                .add(getEnricher(grandchild1))
-                .add(getEnricher(grandchild2))
-                .build();
-        
-        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
-                .put(TestReferencingEnricher.TEST_APPLICATION, app)
-                .put(TestReferencingEnricher.TEST_ENTITY_1, entity1)
-                .put(TestReferencingEnricher.TEST_ENTITY_2, entity2)
-                .put(TestReferencingEnricher.TEST_CHILD_1, child1)
-                .put(TestReferencingEnricher.TEST_CHILD_2, child2)
-                .put(TestReferencingEnricher.TEST_GRANDCHILD_1, grandchild1)
-                .put(TestReferencingEnricher.TEST_GRANDCHILD_2, grandchild2)
-                .build();
-        
-        for (Enricher enricher : enrichers)
-            checkReferences(enricher, keyToEntity);
-    }
-    
-    private void checkReferences(final Enricher enricher, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
-        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
-            final Entity entity = keyToEntity.get(key); // Grab an entity whose execution context we can use
-            Entity fromConfig = ((EntityInternal)entity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
-                @Override
-                public Entity call() throws Exception {
-                    return (Entity) enricher.getConfig(key);
-                }
-            }).get();
-            Assert.assertEquals(fromConfig, keyToEntity.get(key));
-        }
-    }
-    
-    private Enricher getEnricher(Entity entity) {
-        List<Enricher> enrichers = EntityAdjuncts.getNonSystemEnrichers(entity);
-        Assert.assertEquals(enrichers.size(), 1, "Wrong number of enrichers: "+enrichers);
-        Enricher enricher = enrichers.iterator().next();
-        Assert.assertTrue(enricher instanceof TestReferencingEnricher, "Wrong enricher: "+enricher);
-        return enricher;
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
deleted file mode 100644
index f06d862..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
+++ /dev/null
@@ -1,71 +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 io.brooklyn.camp.brooklyn;
-
-import static org.testng.Assert.*;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.proxy.nginx.NginxController;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.tomcat.TomcatServer;
-
-public class EntitiesYamlIntegrationTest extends AbstractYamlTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EntitiesYamlIntegrationTest.class);
-
-    @Test(groups = "Integration")
-    public void testStartTomcatCluster() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-tomcat-cluster.yaml"));
-        waitForApplicationTasks(app);
-
-        assertNotNull(app);
-        assertEquals(app.getChildren().size(), 1);
-        final Entity entity = Iterables.getOnlyElement(app.getChildren());
-        assertTrue(entity instanceof ControlledDynamicWebAppCluster, "entity="+entity);
-        ControlledDynamicWebAppCluster cluster = (ControlledDynamicWebAppCluster) entity;
-
-        assertTrue(cluster.getController() instanceof NginxController, "controller="+cluster.getController());
-        Iterable<TomcatServer> tomcats = FluentIterable.from(cluster.getCluster().getMembers()).filter(TomcatServer.class);
-        assertEquals(Iterables.size(tomcats), 2);
-        for (TomcatServer tomcat : tomcats) {
-            assertTrue(tomcat.getAttribute(TomcatServer.SERVICE_UP), "serviceup");
-        }
-
-        EntitySpec<?> spec = entity.getConfig(DynamicCluster.MEMBER_SPEC);
-        assertNotNull(spec);
-        assertEquals(spec.getType(), TomcatServer.class);
-        assertEquals(spec.getConfig().get(DynamicCluster.QUARANTINE_FAILED_ENTITIES), Boolean.FALSE);
-        assertEquals(spec.getConfig().get(DynamicCluster.INITIAL_QUORUM_SIZE), 2);
-    }
-
-
-    @Override
-    protected Logger getLogger() {
-        return LOG;
-    }
-}


[18/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
deleted file mode 100644
index 699bc12..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
+++ /dev/null
@@ -1,193 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import io.brooklyn.camp.brooklyn.BrooklynCampConstants;
-import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-import io.brooklyn.camp.spi.PlatformComponentTemplate.Builder;
-import io.brooklyn.camp.spi.pdp.AssemblyTemplateConstructor;
-import io.brooklyn.camp.spi.pdp.Service;
-import io.brooklyn.camp.spi.resolve.PdpMatcher;
-
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.internal.BasicBrooklynCatalog;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Urls;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-public class BrooklynEntityMatcher implements PdpMatcher {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynEntityMatcher.class);
-    
-    protected final ManagementContext mgmt;
-
-    public BrooklynEntityMatcher(ManagementContext bmc) {
-        this.mgmt = bmc;
-    }
-
-    @Override
-    public boolean accepts(Object deploymentPlanItem) {
-        return lookupType(deploymentPlanItem) != null;
-    }
-
-    /** returns the type of the given plan item, 
-     * typically whether a Service can be matched to a Brooklyn entity,
-     * or null if not supported */
-    protected String lookupType(Object deploymentPlanItem) {
-        if (deploymentPlanItem instanceof Service) {
-            Service service = (Service)deploymentPlanItem;
-
-            String serviceType = service.getServiceType();
-            BrooklynClassLoadingContext loader = BasicBrooklynCatalog.BrooklynLoaderTracker.getLoader();
-            if (loader == null) loader = JavaBrooklynClassLoadingContext.create(mgmt);
-            if (BrooklynComponentTemplateResolver.Factory.supportsType(loader, serviceType))
-                return serviceType;
-
-            String protocol = Urls.getProtocol(serviceType);
-            if (protocol != null) {
-                if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
-                    return serviceType;
-                } else {
-                    log.debug("The reference '" + serviceType + "' looks like a URL (running the CAMP Brooklyn entity-matcher) but the protocol '" + 
-                            protocol + "' isn't white listed " + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + ". " +
-                            "Not recognized as catalog item or java item as well!");
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public boolean apply(Object deploymentPlanItem, AssemblyTemplateConstructor atc) {
-        if (!(deploymentPlanItem instanceof Service)) return false;
-        
-        String type = lookupType(deploymentPlanItem);
-        if (type==null) return false;
-
-        log.debug("Item "+deploymentPlanItem+" being instantiated with "+type);
-
-        Object old = atc.getInstantiator();
-        if (old!=null && !old.equals(BrooklynAssemblyTemplateInstantiator.class)) {
-            log.warn("Can't mix Brooklyn entities with non-Brooklyn entities (at present): "+old);
-            return false;
-        }
-
-        // TODO should we build up a new type, BrooklynEntityComponentTemplate here
-        // complete w EntitySpec -- ie merge w BrooklynComponentTemplateResolver ?
-        
-        Builder<? extends PlatformComponentTemplate> builder = PlatformComponentTemplate.builder();
-        builder.type( type.indexOf(':')==-1 ? "brooklyn:"+type : type );
-        
-        // currently instantiator must be brooklyn at the ATC level
-        // optionally would be nice to support multiple/mixed instantiators, 
-        // ie at the component level, perhaps with the first one responsible for building the app
-        atc.instantiator(BrooklynAssemblyTemplateInstantiator.class);
-
-        String name = ((Service)deploymentPlanItem).getName();
-        if (!Strings.isBlank(name)) builder.name(name);
-        
-        // configuration
-        Map<String, Object> attrs = MutableMap.copyOf( ((Service)deploymentPlanItem).getCustomAttributes() );
-
-        if (attrs.containsKey("id"))
-            builder.customAttribute("planId", attrs.remove("id"));
-
-        Object location = attrs.remove("location");
-        if (location!=null)
-            builder.customAttribute("location", location);
-        Object locations = attrs.remove("locations");
-        if (locations!=null)
-            builder.customAttribute("locations", locations);
-
-        MutableMap<Object, Object> brooklynFlags = MutableMap.of();
-        Object origBrooklynFlags = attrs.remove(BrooklynCampReservedKeys.BROOKLYN_FLAGS);
-        if (origBrooklynFlags!=null) {
-            if (!(origBrooklynFlags instanceof Map))
-                throw new IllegalArgumentException("brooklyn.flags must be a map of brooklyn flags");
-            brooklynFlags.putAll((Map<?,?>)origBrooklynFlags);
-        }
-
-        addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CONFIG);
-        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_POLICIES);
-        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_ENRICHERS);
-        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS);
-        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
-        addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CATALOG);
-
-        brooklynFlags.putAll(attrs);
-        if (!brooklynFlags.isEmpty()) {
-            builder.customAttribute(BrooklynCampReservedKeys.BROOKLYN_FLAGS, brooklynFlags);
-        }
-
-        atc.add(builder.build());
-
-        return true;
-    }
-
-    /**
-     * Looks for the given key in the map of attributes and adds it to the given builder
-     * as a custom attribute with type List.
-     * @throws java.lang.IllegalArgumentException if map[key] is not an instance of List
-     */
-    private void addCustomListAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) {
-        Object items = attrs.remove(key);
-        if (items != null) {
-            if (items instanceof List) {
-                List<?> itemList = (List<?>) items;
-                if (!itemList.isEmpty()) {
-                    builder.customAttribute(key, Lists.newArrayList(itemList));
-                }
-            } else {
-                throw new IllegalArgumentException(key + " must be a list, is: " + items.getClass().getName());
-            }
-        }
-    }
-
-    /**
-     * Looks for the given key in the map of attributes and adds it to the given builder
-     * as a custom attribute with type Map.
-     * @throws java.lang.IllegalArgumentException if map[key] is not an instance of Map
-     */
-    private void addCustomMapAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) {
-        Object items = attrs.remove(key);
-        if (items != null) {
-            if (items instanceof Map) {
-                Map<?, ?> itemMap = (Map<?, ?>) items;
-                if (!itemMap.isEmpty()) {
-                    builder.customAttribute(key, Maps.newHashMap(itemMap));
-                }
-            } else {
-                throw new IllegalArgumentException(key + " must be a map, is: " + items.getClass().getName());
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
deleted file mode 100644
index 3495687..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
+++ /dev/null
@@ -1,142 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.management.ManagementContext;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.guava.Maybe.Absent;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.Iterables;
-
-public class BrooklynYamlLocationResolver {
-
-    protected final ManagementContext mgmt;
-
-    public BrooklynYamlLocationResolver(ManagementContext bmc) {
-        this.mgmt = bmc;
-    }
-
-    /** returns list of locations, if any were supplied, or null if none indicated */
-    @SuppressWarnings("unchecked")
-    public List<Location> resolveLocations(Map<? super String,?> attrs, boolean removeUsedAttributes) {
-        Object location = attrs.get("location");
-        Object locations = attrs.get("locations");
-
-        if (location==null && locations==null)
-            return null;
-        
-        Location locationFromString = null;
-        List<Location> locationsFromList = null;
-        
-        if (location!=null) {
-            if (location instanceof String) {
-                locationFromString = resolveLocationFromString((String)location);
-            } else if (location instanceof Map) {
-                locationFromString = resolveLocationFromMap((Map<?,?>)location);
-            } else {
-                throw new IllegalStateException("Illegal parameter for 'location'; must be a string or map (but got "+location+")");
-            }
-        }
-        
-        if (locations!=null) {
-            if (!(locations instanceof Iterable))
-                throw new IllegalStateException("Illegal parameter for 'locations'; must be an iterable (but got "+locations+")");
-            locationsFromList = resolveLocations( (Iterable<Object>)locations );
-        }
-        
-        if (locationFromString!=null && locationsFromList!=null) {
-            if (locationsFromList.size() != 1)
-                throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); "
-                    + "if both are supplied the list must have exactly one element being the same");
-            if (!locationFromString.equals( Iterables.getOnlyElement(locationsFromList) ))
-                throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); "
-                    + "different location specified in each");
-        } else if (locationFromString!=null) {
-            locationsFromList = Arrays.asList(locationFromString);
-        }
-        
-        return locationsFromList;
-    }
-
-    public List<Location> resolveLocations(Iterable<Object> locations) {
-        List<Location> result = MutableList.of();
-        for (Object l: locations) {
-            Location ll = resolveLocation(l);
-            if (ll!=null) result.add(ll);
-        }
-        return result;
-    }
-
-    public Location resolveLocation(Object location) {
-        if (location instanceof String) {
-            return resolveLocationFromString((String)location);
-        } else if (location instanceof Map) {
-            return resolveLocationFromMap((Map<?,?>)location);
-        }
-        // could support e.g. location definition
-        throw new IllegalStateException("Illegal parameter for 'location' ("+location+"); must be a string or map");
-    }
-    
-    /** resolves the location from the given spec string, either "Named Location", or "named:Named Location" format;
-     * returns null if input is blank (or null); otherwise guaranteed to resolve or throw error */
-    public Location resolveLocationFromString(String location) {
-        if (Strings.isBlank(location)) return null;
-        return resolveLocation(location, MutableMap.of());
-    }
-
-    public Location resolveLocationFromMap(Map<?,?> location) {
-        if (location.size() > 1) {
-            throw new IllegalStateException("Illegal parameter for 'location'; expected a single entry in map ("+location+")");
-        }
-        Object key = Iterables.getOnlyElement(location.keySet());
-        Object value = location.get(key);
-        
-        if (!(key instanceof String)) {
-            throw new IllegalStateException("Illegal parameter for 'location'; expected String key ("+location+")");
-        }
-        if (!(value instanceof Map)) {
-            throw new IllegalStateException("Illegal parameter for 'location'; expected config map ("+location+")");
-        }
-        return resolveLocation((String)key, (Map<?,?>)value);
-    }
-    
-    protected Location resolveLocation(String spec, Map<?,?> flags) {
-        LocationDefinition ldef = mgmt.getLocationRegistry().getDefinedLocationByName((String)spec);
-        if (ldef!=null)
-            // found it as a named location
-            return mgmt.getLocationRegistry().resolve(ldef, null, flags).get();
-        
-        Maybe<Location> l = mgmt.getLocationRegistry().resolve(spec, null, flags);
-        if (l.isPresent()) return l.get();
-        
-        RuntimeException exception = ((Absent<?>)l).getException();
-        throw new IllegalStateException("Illegal parameter for 'location' ("+spec+"); not resolvable: "+
-            Exceptions.collapseText( exception ), exception);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
deleted file mode 100644
index b78f359..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
+++ /dev/null
@@ -1,208 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.javalang.Reflections;
-import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-/** Assists in loading types referenced from YAML;
- * mainly as a way to share logic used in very different contexts. */
-public abstract class BrooklynYamlTypeInstantiator {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynYamlTypeInstantiator.class);
-    
-    protected final Factory factory;
-
-    @Beta
-    public static class Factory {
-        final BrooklynClassLoadingContext loader;
-        final Object contextForLogging;
-        
-        public Factory(BrooklynClassLoadingContext loader, Object contextForLogging) {
-            this.loader = loader;
-            this.contextForLogging = contextForLogging;
-        }
-        
-        public InstantiatorFromKey from(Map<?,?> data) {
-            return new InstantiatorFromKey(this, ConfigBag.newInstance(data));
-        }
-        
-        public InstantiatorFromKey from(ConfigBag data) {
-            return new InstantiatorFromKey(this, data);
-        }
-        
-        public InstantiatorFromName type(String typeName) {
-            return new InstantiatorFromName(this, typeName);
-        }
-
-    }
-        
-    public static class InstantiatorFromKey extends BrooklynYamlTypeInstantiator {
-        protected final ConfigBag data;
-        protected String typeKeyPrefix = null;
-        
-        /** Nullable only permitted for instances which do not do loading, e.g. LoaderFromKey#lookup */
-        protected InstantiatorFromKey(@Nullable Factory factory, ConfigBag data) {
-            super(factory);
-            this.data = data;
-        }
-        
-        public static Maybe<String> extractTypeName(String prefix, ConfigBag data) {
-            if (data==null) return Maybe.absent();
-            return new InstantiatorFromKey(null, data).prefix(prefix).getTypeName();
-        }
-        
-        public InstantiatorFromKey prefix(String prefix) {
-            typeKeyPrefix = prefix;
-            return this;
-        }
-
-        public Maybe<String> getTypeName() {
-            Maybe<Object> result = data.getStringKeyMaybe(getPreferredKeyName());
-            if (result.isAbsent() && typeKeyPrefix!=null) {
-                // try alternatives if a prefix was specified
-                result = data.getStringKeyMaybe(typeKeyPrefix+"Type");
-                if (result.isAbsent()) result = data.getStringKeyMaybe("type");
-            }
-            
-            if (result.isAbsent() || result.get()==null) 
-                return Maybe.absent("Missing key '"+getPreferredKeyName()+"'");
-            
-            if (result.get() instanceof String) return Maybe.of((String)result.get());
-            
-            throw new IllegalArgumentException("Invalid value "+result.get().getClass()+" for "+getPreferredKeyName()+"; "
-                + "expected String, got "+result.get());
-        }
-        
-        protected String getPreferredKeyName() {
-            if (typeKeyPrefix!=null) return typeKeyPrefix+"_type";
-            return "type";
-        }
-        
-        /** as {@link #newInstance(Class)} but inferring the type */
-        public Object newInstance() {
-            return newInstance(null);
-        }
-        
-        /** creates a new instance of the type referred to by this description,
-         * as a subtype of the type supplied here, 
-         * inferring a Map from <code>brooklyn.config</code> key.
-         * TODO in future also picking up recognized flags and config keys (those declared on the type).  
-         * <p>
-         * constructs the object using:
-         * <li> a constructor on the class taking a Map
-         * <li> a no-arg constructor, only if the inferred map is empty  
-         **/
-        public <T> T newInstance(@Nullable Class<T> supertype) {
-            Class<? extends T> type = getType(supertype);
-            Map<String, ?> cfg = getConfigMap();
-            Optional<? extends T> result = Reflections.invokeConstructorWithArgs(type, cfg);
-            if (result.isPresent()) 
-                return result.get();
-            
-            ConfigBag cfgBag = ConfigBag.newInstance(cfg);
-            result = Reflections.invokeConstructorWithArgs(type, cfgBag);
-            if (result.isPresent()) 
-                return result.get();
-            
-            if (cfg.isEmpty()) {
-                result = Reflections.invokeConstructorWithArgs(type);
-                if (result.isPresent()) 
-                    return result.get();
-            }
-            
-            throw new IllegalStateException("No known mechanism for constructing type "+type+" in "+factory.contextForLogging);
-        }
-
-        /** finds the map of config for the type specified;
-         * currently only gets <code>brooklyn.config</code>, returning empty map if none,
-         * but TODO in future should support recognized flags and config keys (those declared on the type),
-         * incorporating code in {@link BrooklynEntityMatcher}.
-         */
-        @SuppressWarnings("unchecked")
-        @Nonnull
-        public Map<String,?> getConfigMap() {
-            MutableMap<String,Object> result = MutableMap.of();
-            Object bc = data.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
-            if (bc!=null) {
-                if (bc instanceof Map)
-                    result.putAll((Map<? extends String, ?>) bc);
-                else
-                    throw new IllegalArgumentException("brooklyn.config key in "+factory.contextForLogging+" should be a map, not "+bc.getClass()+" ("+bc+")");
-            }
-            return result; 
-        }
-
-    }
-    
-    public static class InstantiatorFromName extends BrooklynYamlTypeInstantiator {
-        protected final String typeName;
-        protected InstantiatorFromName(Factory factory, String typeName) {
-            super(factory);
-            this.typeName = typeName;
-        }
-        
-        public Maybe<String> getTypeName() {
-            return Maybe.fromNullable(typeName);
-        }
-    }
-    
-    protected BrooklynYamlTypeInstantiator(Factory factory) {
-        this.factory = factory;
-    }
-        
-    public abstract Maybe<String> getTypeName();
-    
-    public BrooklynClassLoadingContext getClassLoadingContext() {
-        Preconditions.checkNotNull(factory, "No factory set; cannot use this instance for type loading");
-        return factory.loader;
-    }
-    
-    public Class<?> getType() {
-        return getType(Object.class);
-    }
-    
-    public <T> Class<? extends T> getType(@Nonnull Class<T> type) {
-        try {
-            return getClassLoadingContext().loadClass(getTypeName().get(), type);
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            log.debug("Unable to resolve " + type + " " + getTypeName().get() + " (rethrowing) in spec " + factory.contextForLogging);
-            throw Exceptions.propagate(e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
deleted file mode 100644
index 7d9a62a..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
+++ /dev/null
@@ -1,58 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.proxying.EntitySpec;
-
-import com.google.common.collect.Maps;
-
-/**
- * Captures the {@link EntitySpec} configuration defined in YAML. 
- * 
- * This class does not parse that output; it just stores it.
- */
-public class EntitySpecConfiguration {
-
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(EntitySpecConfiguration.class);
-
-    private Map<String, Object> specConfiguration;
-
-    public EntitySpecConfiguration(Map<String, ?> specConfiguration) {
-        this.specConfiguration = Maps.newHashMap(checkNotNull(specConfiguration, "specConfiguration"));
-    }
-
-    public Map<String, Object> getSpecConfiguration() {
-        return specConfiguration;
-    }
-    
-    /**
-     * Allows BrooklynComponentTemplateResolver to traverse the configuration and resolve any entity specs
-     */
-    public void setSpecConfiguration(Map<String, Object> specConfiguration) {
-       this.specConfiguration =  specConfiguration;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
deleted file mode 100644
index 8796d0d..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
+++ /dev/null
@@ -1,72 +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 io.brooklyn.camp.brooklyn.spi.creation.service;
-
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-
-import javax.annotation.Nullable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.util.text.Strings;
-
-/**
- * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code brooklyn:}
- * to Brooklyn {@link EntitySpec} instances.
- */
-public class BrooklynServiceTypeResolver implements ServiceTypeResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
-
-    @Override
-    public String getTypePrefix() { return DEFAULT_TYPE_PREFIX; }
-
-    @Override
-    public String getBrooklynType(String serviceType) {
-        String type = Strings.removeFromStart(serviceType, getTypePrefix() + ":").trim();
-        if (type == null) return null;
-        return type;
-    }
-
-    @Nullable
-    @Override
-    public CatalogItem<Entity,EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) {
-        String type = getBrooklynType(serviceType);
-        if (type != null) {
-            return CatalogUtils.getCatalogItemOptionalVersion(resolver.getManagementContext(), Entity.class,  type);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) {
-        new BrooklynEntityDecorationResolver.PolicySpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
-        new BrooklynEntityDecorationResolver.EnricherSpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
-        new BrooklynEntityDecorationResolver.InitializerResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
deleted file mode 100644
index d082b13..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
+++ /dev/null
@@ -1,78 +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 io.brooklyn.camp.brooklyn.spi.creation.service;
-
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.VanillaSoftwareProcess;
-import brooklyn.entity.brooklynnode.BrooklynNode;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.group.DynamicRegionsFabric;
-import brooklyn.entity.java.VanillaJavaApp;
-import brooklyn.entity.proxying.EntitySpec;
-
-import com.google.common.base.CaseFormat;
-import com.google.common.base.Converter;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code catalog:}
- * to Brooklyn {@link EntitySpec} instances.
- */
-public class CatalogServiceTypeResolver extends BrooklynServiceTypeResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
-
-    // TODO currently a hardcoded list of aliases; would like that to come from mgmt somehow
-    private static final Map<String, String> CATALOG_TYPES = ImmutableMap.<String, String>builder()
-            .put("cluster", DynamicCluster.class.getName())
-            .put("fabric", DynamicRegionsFabric.class.getName())
-            .put("vanilla", VanillaSoftwareProcess.class.getName())
-            .put("software-process", VanillaSoftwareProcess.class.getName())
-            .put("java-app", VanillaJavaApp.class.getName())
-            .put("brooklyn-node", BrooklynNode.class.getName())
-            .put("web-app-cluster","brooklyn.entity.webapp.ControlledDynamicWebAppCluster")
-            .build();
-
-    // Allow catalog-type or CatalogType as service type string
-    private static final Converter<String, String> FMT = CaseFormat.LOWER_HYPHEN.converterTo(CaseFormat.UPPER_CAMEL);
-
-    @Override
-    public String getTypePrefix() { return "catalog"; }
-
-    @Override
-    public String getBrooklynType(String serviceType) {
-        String type = super.getBrooklynType(serviceType);
-        if (type == null) return null;
-
-        for (String check : CATALOG_TYPES.keySet()) {
-            if (type.equals(check) || type.equals(FMT.convert(check))) {
-                return CATALOG_TYPES.get(check);
-            }
-        }
-
-        return type;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
deleted file mode 100644
index c9ff893..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
+++ /dev/null
@@ -1,62 +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 io.brooklyn.camp.brooklyn.spi.creation.service;
-
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.entity.Entity;
-import brooklyn.entity.chef.ChefConfig;
-import brooklyn.entity.chef.ChefEntity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.util.text.Strings;
-
-/**
- * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code chef:}
- * to Brooklyn {@link EntitySpec} instances.
- */
-public class ChefServiceTypeResolver extends BrooklynServiceTypeResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
-
-    @Override
-    public String getTypePrefix() { return "chef"; }
-
-    @Override
-    public String getBrooklynType(String serviceType) {
-        return ChefEntity.class.getName();
-    }
-
-    /** Chef items are not in the catalog. */
-    @Override
-    public CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) {
-        return null;
-    }
-
-    @Override
-    public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) {
-        spec.configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, Strings.removeFromStart(resolver.getDeclaredType(), "chef:"));
-        super.decorateSpec(resolver, spec);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
deleted file mode 100644
index f348ea8..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
+++ /dev/null
@@ -1,39 +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 io.brooklyn.camp.brooklyn.spi.creation.service;
-
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.proxying.EntitySpec;
-
-/**
- * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code java:}
- * to Brooklyn {@link EntitySpec} instances.
- */
-public class JavaServiceTypeResolver extends BrooklynServiceTypeResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
-
-    @Override
-    public String getTypePrefix() { return "java"; }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
deleted file mode 100644
index 21b48d6..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
+++ /dev/null
@@ -1,73 +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 io.brooklyn.camp.brooklyn.spi.creation.service;
-
-import java.util.ServiceLoader;
-
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-
-/**
- * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template.
- * <p>
- * The {@link #getTypePrefix()} method returns a string that should match the beginning of the
- * service type. The resolver implementation will use the rest of the service type information
- * to create and decorate an approprate {@link EntitySpec entity}.
- * <p>
- * The resolvers are loaded using the {@link ServiceLoader} mechanism, allowing external libraries
- * to add extra service type implementations that will be picked up at runtime.
- *
- * @see BrooklynServiceTypeResolver
- * @see ChefServiceTypeResolver
- */
-public interface ServiceTypeResolver {
-
-    String DEFAULT_TYPE_PREFIX = "brooklyn";
-
-    /**
-     * The service type prefix the resolver is responsible for.
-     */
-    String getTypePrefix();
-
-    /**
-     * The name of the Java type that Brooklyn will instantiate to create the
-     * service. This can be generated from parts of the service type information
-     * or may be a fixed value.
-     */
-    String getBrooklynType(String serviceType);
-
-    /**
-     * Returns the {@link CatalogItem} if there is one for the given type.
-     * <p>
-     * If no type, callers should fall back to default classloading.
-     */
-    CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType);
-
-    /**
-     * Takes the provided {@link EntitySpec} and decorates it appropriately for the service type.
-     * <p>
-     * This includes setting configuration and adding policies, enrichers and initializers.
-     *
-     * @see BrooklynServiceTypeResolver#decorateSpec(BrooklynComponentTemplateResolver, EntitySpec)
-     */
-    <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
deleted file mode 100644
index 4f65a77..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
+++ /dev/null
@@ -1,99 +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 io.brooklyn.camp.brooklyn.spi.dsl;
-
-import java.io.Serializable;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.management.Task;
-import brooklyn.management.TaskFactory;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.task.DeferredSupplier;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/** provide an object suitable to resolve chained invocations in a parsed YAML / Deployment Plan DSL,
- * which also implements {@link DeferredSupplier} so that they can be resolved when needed
- * (e.g. when entity-lookup and execution contexts are available).
- * <p>
- * implementations of this abstract class are expected to be immutable,
- * as instances must support usage in multiple {@link Assembly} instances 
- * created from a single {@link AssemblyTemplate}  
- * <p>
- * subclasses which return a deferred value are typically only
- * resolvable in the context of a {@link Task} on an {@link Entity}; 
- * these should be only used as the value of a {@link ConfigKey} set in the YAML,
- * and should not accessed until after the components / entities are created 
- * and are being started.
- * (TODO the precise semantics of this are under development.)
- * <p>
- **/
-public abstract class BrooklynDslDeferredSupplier<T> implements DeferredSupplier<T>, TaskFactory<Task<T>>, Serializable {
-
-    private static final long serialVersionUID = -8789624905412198233L;
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynDslDeferredSupplier.class);
-    
-    // TODO json of this object should *be* this, not wrapped this ($brooklyn:literal is a bit of a hack, though it might work!)
-    @JsonInclude
-    @JsonProperty(value="$brooklyn:literal")
-    // currently marked transient because it's only needed for logging
-    private transient Object dsl = "(gone)";
-    
-    public BrooklynDslDeferredSupplier() {
-        PlanInterpretationNode sourceNode = BrooklynDslInterpreter.currentNode();
-        dsl = sourceNode!=null ? sourceNode.getOriginalValue() : null;
-    }
-    
-    /** returns the current entity; for use in implementations of {@link #get()} */
-    protected final static EntityInternal entity() {
-        // rely on implicit ThreadLocal for now
-        return (EntityInternal) EffectorTasks.findEntity();
-    }
-
-    @Override
-    public final synchronized T get() {
-        try {
-            if (log.isDebugEnabled())
-                log.debug("Queuing task to resolve "+dsl);
-            T result = Entities.submit(entity(), newTask()).get();
-            if (log.isDebugEnabled())
-                log.debug("Resolved "+result+" from "+dsl);
-            return result;
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    @Override
-    public abstract Task<T> newTask();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
deleted file mode 100644
index d661403..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
+++ /dev/null
@@ -1,188 +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 io.brooklyn.camp.brooklyn.spi.dsl;
-
-import io.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.FunctionWithArgs;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.QuotedString;
-import io.brooklyn.camp.spi.resolve.PlanInterpreter;
-import io.brooklyn.camp.spi.resolve.PlanInterpreter.PlanInterpreterAdapter;
-import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
-import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode.Role;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.javalang.Reflections;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Optional;
-
-/**
- * {@link PlanInterpreter} which understands the $brooklyn DSL
- */
-public class BrooklynDslInterpreter extends PlanInterpreterAdapter {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynDslInterpreter.class);
-
-    @Override
-    public boolean isInterestedIn(PlanInterpretationNode node) {
-        return node.matchesPrefix("$brooklyn:") || node.getNewValue() instanceof FunctionWithArgs;
-    }
-
-    private static ThreadLocal<PlanInterpretationNode> currentNode = new ThreadLocal<PlanInterpretationNode>();
-    /** returns the current node, stored in a thread-local, to populate the dsl field of {@link BrooklynDslDeferredSupplier} instances */
-    public static PlanInterpretationNode currentNode() {
-        return currentNode.get();
-    }
-    /** sets the current node */
-    public static void currentNode(PlanInterpretationNode node) {
-        currentNode.set(node);
-    }
-    public static void currentNodeClear() {
-        currentNode.set(null);
-    }
-    
-    @Override
-    public void applyYamlPrimitive(PlanInterpretationNode node) {
-        String expression = node.getNewValue().toString();
-
-        try {
-            currentNode.set(node);
-            Object parsedNode = new DslParser(expression).parse();
-            if ((parsedNode instanceof FunctionWithArgs) && ((FunctionWithArgs)parsedNode).getArgs()==null) {
-                if (node.getRoleInParent() == Role.MAP_KEY) {
-                    node.setNewValue(parsedNode);
-                    // will be handled later
-                } else {
-                    throw new IllegalStateException("Invalid function-only expression '"+((FunctionWithArgs)parsedNode).getFunction()+"'");
-                }
-            } else {
-                node.setNewValue( evaluate(parsedNode, true) );
-            }
-        } catch (Exception e) {
-            log.warn("Error evaluating node (rethrowing) '"+expression+"': "+e);
-            Exceptions.propagateIfFatal(e);
-            throw new IllegalArgumentException("Error evaluating node '"+expression+"'", e);
-        } finally {
-            currentNodeClear();
-        }
-    }
-    
-    @Override
-    public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut,
-            PlanInterpretationNode key, PlanInterpretationNode value) {
-        if (key.getNewValue() instanceof FunctionWithArgs) {
-            try {
-                currentNode.set(node);
-
-                FunctionWithArgs f = (FunctionWithArgs) key.getNewValue();
-                if (f.getArgs()!=null)
-                    throw new IllegalStateException("Invalid map key function "+f.getFunction()+"; should not have arguments if taking arguments from map");
-
-                // means evaluation acts on values
-                List<Object> args = new ArrayList<Object>();
-                if (value.getNewValue() instanceof Iterable<?>) {
-                    for (Object vi: (Iterable<?>)value.getNewValue())
-                        args.add(vi);
-                } else {
-                    args.add(value.getNewValue());
-                }
-
-                try {
-                    // TODO in future we should support functions of the form 'Maps.clear', 'Maps.reset', 'Maps.remove', etc;
-                    // default approach only supported if mapIn has single item and mapOut is empty
-                    if (mapIn.size()!=1) 
-                        throw new IllegalStateException("Map-entry DSL syntax only supported with single item in map, not "+mapIn);
-                    if (mapOut.size()!=0) 
-                        throw new IllegalStateException("Map-entry DSL syntax only supported with empty output map-so-far, not "+mapOut);
-
-                    node.setNewValue( evaluate(new FunctionWithArgs(f.getFunction(), args), false) );
-                    return false;
-                } catch (Exception e) {
-                    log.warn("Error evaluating map-entry (rethrowing) '"+f.getFunction()+args+"': "+e);
-                    Exceptions.propagateIfFatal(e);
-                    throw new IllegalArgumentException("Error evaluating map-entry '"+f.getFunction()+args+"'", e);
-                }
-
-            } finally {
-                currentNodeClear();
-            }
-        }
-        return super.applyMapEntry(node, mapIn, mapOut, key, value);
-    }
-
-    public Object evaluate(Object f, boolean deepEvaluation) {
-        if (f instanceof FunctionWithArgs) {
-            return evaluateOn(BrooklynDslCommon.class, (FunctionWithArgs) f, deepEvaluation);
-        }
-        
-        if (f instanceof List) {
-            Object o = BrooklynDslCommon.class;
-            for (Object i: (List<?>)f) {
-                o = evaluateOn( o, (FunctionWithArgs)i, deepEvaluation );
-            }
-            return o;
-        }
-
-        if (f instanceof QuotedString) {
-            return ((QuotedString)f).unwrapped();
-        }
-
-        throw new IllegalArgumentException("Unexpected element in parse tree: '"+f+"' (type "+(f!=null ? f.getClass() : null)+")");
-    }
-    
-    public Object evaluateOn(Object o, FunctionWithArgs f, boolean deepEvaluation) {
-        if (f.getArgs()==null)
-            throw new IllegalStateException("Invalid function-only expression '"+f.getFunction()+"'");
-
-        Class<?> clazz;
-        if (o instanceof Class) {
-            clazz = (Class<?>)o;
-        } else {
-            clazz = o.getClass();
-        }
-        if (!(clazz.getPackage().getName().startsWith(BrooklynDslCommon.class.getPackage().getName())))
-            throw new IllegalArgumentException("Not permitted to invoke function on '"+clazz+"' (outside allowed package scope)");
-        
-        String fn = f.getFunction();
-        fn = Strings.removeFromStart(fn, "$brooklyn:");
-        try {
-            List<Object> args = new ArrayList<Object>();
-            for (Object arg: f.getArgs()) {
-                args.add( deepEvaluation ? evaluate(arg, true) : arg );
-            }
-            Optional<Object> v = Reflections.invokeMethodWithArgs(o, fn, args);
-            if (v.isPresent()) return v.get();
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            throw Exceptions.propagate(new InvocationTargetException(e, "Error invoking '"+fn+"' on '"+o+"'"));
-        }
-        
-        throw new IllegalArgumentException("No such function '"+fn+"' on "+o);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
deleted file mode 100644
index 7ad8abe..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
+++ /dev/null
@@ -1,44 +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 io.brooklyn.camp.brooklyn.spi.dsl;
-
-import brooklyn.util.task.DeferredSupplier;
-
-import com.google.common.collect.Iterables;
-
-public class DslUtils {
-
-    /** true iff none of the args are deferred / tasks */
-    public static boolean resolved(Iterable<Object> args) {
-        return resolved(Iterables.toArray(args, Object.class));
-    }
-
-    /** true iff none of the args are deferred / tasks */
-    public static boolean resolved(final Object... args) {
-        boolean allResolved = true;
-        for (Object arg: args) {
-            if (arg instanceof DeferredSupplier<?>) {
-                allResolved = false;
-                break;
-            }
-        }
-        return allResolved;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
deleted file mode 100644
index efcdd49..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ /dev/null
@@ -1,302 +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 io.brooklyn.camp.brooklyn.spi.dsl.methods;
-
-import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator;
-import io.brooklyn.camp.brooklyn.spi.creation.EntitySpecConfiguration;
-import io.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
-import io.brooklyn.camp.brooklyn.spi.dsl.DslUtils;
-import io.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.beanutils.BeanUtils;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.entity.trait.Configurable;
-import brooklyn.event.Sensor;
-import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.management.Task;
-import brooklyn.management.TaskAdaptable;
-import brooklyn.management.TaskFactory;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.ClassCoercionException;
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.javalang.Reflections;
-import brooklyn.util.task.DeferredSupplier;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/** static import functions which can be used in `$brooklyn:xxx` contexts */
-public class BrooklynDslCommon {
-
-    // Access specific entities
-
-    public static DslComponent entity(String id) {
-        return new DslComponent(Scope.GLOBAL, id);
-    }
-    public static DslComponent parent() {
-        return new DslComponent(Scope.PARENT, null);
-    }
-    public static DslComponent child(String id) {
-        return new DslComponent(Scope.CHILD, id);
-    }
-    public static DslComponent sibling(String id) {
-        return new DslComponent(Scope.SIBLING, id);
-    }
-    public static DslComponent descendant(String id) {
-        return new DslComponent(Scope.DESCENDANT, id);
-    }
-    public static DslComponent ancestor(String id) {
-        return new DslComponent(Scope.ANCESTOR, id);
-    }
-    // prefer the syntax above to the below now, but not deprecating the below
-    public static DslComponent component(String id) {
-        return component("global", id);
-    }
-    public static DslComponent component(String scope, String id) {
-        if (!DslComponent.Scope.isValid(scope)) {
-            throw new IllegalArgumentException(scope + " is not a valid scope");
-        }
-        return new DslComponent(DslComponent.Scope.fromString(scope), id);
-    }
-
-    // Access things on entities
-
-    public static BrooklynDslDeferredSupplier<?> config(String keyName) {
-        return new DslComponent(Scope.THIS, "").config(keyName);
-    }
-
-    public static BrooklynDslDeferredSupplier<?> attributeWhenReady(String sensorName) {
-        return new DslComponent(Scope.THIS, "").attributeWhenReady(sensorName);
-    }
-
-    /** Returns a {@link Sensor}, looking up the sensor on the context if available and using that,
-     * or else defining an untyped (Object) sensor */
-    public static BrooklynDslDeferredSupplier<Sensor<?>> sensor(String sensorName) {
-        return new DslComponent(Scope.THIS, "").sensor(sensorName);
-    }
-    
-    /** Returns a {@link Sensor} declared on the type (e.g. entity class) declared in the first argument. */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static Sensor<?> sensor(String clazzName, String sensorName) {
-        try {
-            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
-            Class<?> clazz = Class.forName(clazzName);
-            Sensor<?> sensor;
-            if (Entity.class.isAssignableFrom(clazz)) {
-                sensor = new EntityDynamicType((Class<? extends Entity>) clazz).getSensor(sensorName);
-            } else {
-                // Some non-entity classes (e.g. ServiceRestarter policy) declare sensors that other
-                // entities/policies/enrichers may wish to reference.
-                Map<String,Sensor<?>> sensors = EntityDynamicType.findSensors((Class)clazz, null);
-                sensor = sensors.get(sensorName);
-            }
-            if (sensor == null) {
-                // TODO could extend API to return a sensor of the given type; useful but makes API ambiguous in theory (unlikely in practise, but still...)
-                throw new IllegalArgumentException("Sensor " + sensorName + " not found on class " + clazzName);
-            }
-            return sensor;
-        } catch (ClassNotFoundException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    // Build complex things
-
-    public static EntitySpecConfiguration entitySpec(Map<String, Object> arguments) {
-        return new EntitySpecConfiguration(arguments);
-    }
-
-    /**
-     * Return an instance of the specified class with its fields set according
-     * to the {@link Map} or a {@link BrooklynDslDeferredSupplier} if the arguments are not
-     * yet fully resolved.
-     */
-    @SuppressWarnings("unchecked")
-    public static Object object(Map<String, Object> arguments) {
-        ConfigBag config = ConfigBag.newInstance(arguments);
-        String typeName = BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("object", config).orNull();
-        Map<String,Object> objectFields = (Map<String, Object>) config.getStringKeyMaybe("object.fields").or(MutableMap.of());
-        Map<String,Object> brooklynConfig = (Map<String, Object>) config.getStringKeyMaybe(BrooklynCampReservedKeys.BROOKLYN_CONFIG).or(MutableMap.of());
-        try {
-            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
-            Class<?> type = Class.forName(typeName);
-            if (!Reflections.hasNoArgConstructor(type)) {
-                throw new IllegalStateException(String.format("Cannot construct %s bean: No public no-arg constructor available", type));
-            }
-            if ((objectFields.isEmpty() || DslUtils.resolved(objectFields.values())) &&
-                    (brooklynConfig.isEmpty() || DslUtils.resolved(brooklynConfig.values()))) {
-                return DslObject.create(type, objectFields, brooklynConfig);
-            } else {
-                return new DslObject(type, objectFields, brooklynConfig);
-            }
-        } catch (ClassNotFoundException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    // String manipulation
-
-    /** Return the expression as a literal string without any further parsing. */
-    public static Object literal(Object expression) {
-        return expression;
-    }
-
-    /**
-     * Returns a formatted string or a {@link BrooklynDslDeferredSupplier} if the arguments
-     * are not yet fully resolved.
-     */
-    public static Object formatString(final String pattern, final Object...args) {
-        if (DslUtils.resolved(args)) {
-            // if all args are resolved, apply the format string now
-            return String.format(pattern, args);
-        } else {
-            return new DslFormatString(pattern, args);
-        }
-    }
-
-    /**
-     * Deferred execution of String formatting.
-     *
-     * @see DependentConfiguration#formatString(String, Object...)
-     */
-    protected static class DslFormatString extends BrooklynDslDeferredSupplier<String> {
-
-        private static final long serialVersionUID = -4849297712650560863L;
-
-        private String pattern;
-        private Object[] args;
-
-        public DslFormatString(String pattern, Object ...args) {
-            this.pattern = pattern;
-            this.args = args;
-        }
-
-        @Override
-        public Task<String> newTask() {
-            return DependentConfiguration.formatString(pattern, args);
-        }
-
-        @Override
-        public String toString() {
-            return "$brooklyn:formatString("+
-                JavaStringEscapes.wrapJavaString(pattern)+
-                (args==null || args.length==0 ? "" : ","+Strings.join(args, ","))+")";
-        }
-    }
-
-    /** @deprecated since 0.7.0; use {@link DslFormatString} */
-    @SuppressWarnings("serial")
-    @Deprecated
-    protected static class FormatString extends DslFormatString {
-        public FormatString(String pattern, Object[] args) {
-            super(pattern, args);
-        }
-    }
-
-    /** Deferred execution of Object creation. */
-    protected static class DslObject extends BrooklynDslDeferredSupplier<Object> {
-
-        private static final long serialVersionUID = 8878388748085419L;
-
-        private Class<?> type;
-        private Map<String,Object> fields, config;
-
-        public DslObject(Class<?> type, Map<String,Object> fields,  Map<String,Object> config) {
-            this.type = type;
-            this.fields = MutableMap.copyOf(fields);
-            this.config = MutableMap.copyOf(config);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public Task<Object> newTask() {
-            List<TaskAdaptable<Object>> tasks = Lists.newLinkedList();
-            for (Object value : Iterables.concat(fields.values(), config.values())) {
-                if (value instanceof TaskAdaptable) {
-                    tasks.add((TaskAdaptable<Object>) value);
-                } else if (value instanceof TaskFactory) {
-                    tasks.add(((TaskFactory<TaskAdaptable<Object>>) value).newTask());
-                }
-            }
-            Map<String,?> flags = MutableMap.<String,String>of("displayName", "building '"+type+"' with "+tasks.size()+" task"+(tasks.size()!=1?"s":""));
-            return DependentConfiguration.transformMultiple(flags, new Function<List<Object>, Object>() {
-                        @Override
-                        public Object apply(List<Object> input) {
-                            Iterator<Object> values = input.iterator();
-                            for (String name : fields.keySet()) {
-                                Object value = fields.get(name);
-                                if (value instanceof TaskAdaptable || value instanceof TaskFactory) {
-                                    fields.put(name, values.next());
-                                } else if (value instanceof DeferredSupplier) {
-                                    fields.put(name, ((DeferredSupplier<?>) value).get());
-                                }
-                            }
-                            for (String name : config.keySet()) {
-                                Object value = config.get(name);
-                                if (value instanceof TaskAdaptable || value instanceof TaskFactory) {
-                                    config.put(name, values.next());
-                                } else if (value instanceof DeferredSupplier) {
-                                    config.put(name, ((DeferredSupplier<?>) value).get());
-                                }
-                            }
-                            return create(type, fields, config);
-                        }
-                    }, tasks);
-        }
-
-        public static <T> T create(Class<T> type, Map<String,?> fields, Map<String,?> config) {
-            try {
-                T bean;
-                try {
-                    bean = (T) TypeCoercions.coerce(fields, type);
-                } catch (ClassCoercionException ex) {
-                    bean = Reflections.invokeConstructorWithArgs(type).get();
-                    BeanUtils.populate(bean, fields);
-                }
-                if (bean instanceof Configurable && config.size() > 0) {
-                    ConfigBag brooklyn = ConfigBag.newInstance(config);
-                    FlagUtils.setFieldsFromFlags(bean, brooklyn);
-                    FlagUtils.setAllConfigKeys((Configurable) bean, brooklyn, true);
-                }
-                return bean;
-            } catch (Exception e) {
-                throw Exceptions.propagate(e);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "$brooklyn:object(\""+type.getName()+"\")";
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
deleted file mode 100644
index 1cb52b3..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ /dev/null
@@ -1,320 +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 io.brooklyn.camp.brooklyn.spi.dsl.methods;
-
-import io.brooklyn.camp.brooklyn.BrooklynCampConstants;
-import io.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
-
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.EntityPredicates;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.Sensor;
-import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.event.basic.Sensors;
-import brooklyn.management.Task;
-import brooklyn.management.internal.EntityManagerInternal;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
-
-    private static final long serialVersionUID = -7715984495268724954L;
-    
-    private final String componentId;
-    private final DslComponent scopeComponent;
-    private final Scope scope;
-
-    public DslComponent(String componentId) {
-        this(Scope.GLOBAL, componentId);
-    }
-    
-    public DslComponent(Scope scope, String componentId) {
-        this(null, scope, componentId);
-    }
-    
-    public DslComponent(DslComponent scopeComponent, Scope scope, String componentId) {
-        Preconditions.checkNotNull(scope, "scope");
-        this.scopeComponent = scopeComponent;
-        this.componentId = componentId;
-        this.scope = scope;
-    }
-
-    // ---------------------------
-    
-    @Override
-    public Task<Entity> newTask() {
-        return TaskBuilder.<Entity>builder().name(toString()).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG)
-            .body(new EntityInScopeFinder(scopeComponent, scope, componentId)).build();
-    }
-    
-    protected static class EntityInScopeFinder implements Callable<Entity> {
-        protected final DslComponent scopeComponent;
-        protected final Scope scope;
-        protected final String componentId;
-
-        public EntityInScopeFinder(DslComponent scopeComponent, Scope scope, String componentId) {
-            this.scopeComponent = scopeComponent;
-            this.scope = scope;
-            this.componentId = componentId;
-        }
-
-        protected EntityInternal getEntity() {
-            if (scopeComponent!=null) {
-                return (EntityInternal)scopeComponent.get();
-            } else {
-                return entity();
-            }
-        }
-        
-        @Override
-        public Entity call() throws Exception {
-            Iterable<Entity> entitiesToSearch = null;
-            switch (scope) {
-                case THIS:
-                    return getEntity();
-                case PARENT:
-                    return getEntity().getParent();
-                case GLOBAL:
-                    entitiesToSearch = ((EntityManagerInternal)getEntity().getManagementContext().getEntityManager())
-                        .getAllEntitiesInApplication( entity().getApplication() );
-                    break;
-                case DESCENDANT:
-                    entitiesToSearch = Entities.descendants(getEntity());
-                    break;
-                case ANCESTOR:
-                    entitiesToSearch = Entities.ancestors(getEntity());
-                    break;
-                case SIBLING:
-                    entitiesToSearch = getEntity().getParent().getChildren();
-                    break;
-                case CHILD:
-                    entitiesToSearch = getEntity().getChildren();
-                    break;
-                default:
-                    throw new IllegalStateException("Unexpected scope "+scope);
-            }
-            
-            Optional<Entity> result = Iterables.tryFind(entitiesToSearch, EntityPredicates.configEqualTo(BrooklynCampConstants.PLAN_ID, componentId));
-            
-            if (result.isPresent())
-                return result.get();
-            
-            // TODO may want to block and repeat on new entities joining?
-            throw new NoSuchElementException("No entity matching id " + componentId+
-                (scope==Scope.GLOBAL ? "" : ", in scope "+scope+" wrt "+getEntity()+
-                (scopeComponent!=null ? " ("+scopeComponent+" from "+entity()+")" : "")));
-        }        
-    }
-    
-    // -------------------------------
-
-    // DSL words which move to a new component
-    
-    public DslComponent entity(String scopeOrId) {
-        return new DslComponent(this, Scope.GLOBAL, scopeOrId);
-    }
-    public DslComponent child(String scopeOrId) {
-        return new DslComponent(this, Scope.CHILD, scopeOrId);
-    }
-    public DslComponent sibling(String scopeOrId) {
-        return new DslComponent(this, Scope.SIBLING, scopeOrId);
-    }
-    public DslComponent descendant(String scopeOrId) {
-        return new DslComponent(this, Scope.DESCENDANT, scopeOrId);
-    }
-    public DslComponent ancestor(String scopeOrId) {
-        return new DslComponent(this, Scope.ANCESTOR, scopeOrId);
-    }
-    
-    @Deprecated /** @deprecated since 0.7.0 */
-    public DslComponent component(String scopeOrId) {
-        return new DslComponent(this, Scope.GLOBAL, scopeOrId);
-    }
-    
-    public DslComponent parent() {
-        return new DslComponent(this, Scope.PARENT, "");
-    }
-    
-    public DslComponent component(String scope, String id) {
-        if (!DslComponent.Scope.isValid(scope)) {
-            throw new IllegalArgumentException(scope + " is not a vlaid scope");
-        }
-        return new DslComponent(this, DslComponent.Scope.fromString(scope), id);
-    }
-
-    // DSL words which return things
-    
-    public BrooklynDslDeferredSupplier<?> attributeWhenReady(final String sensorName) {
-        return new AttributeWhenReady(this, sensorName);
-    }
-    // class simply makes the memento XML files nicer
-    protected static class AttributeWhenReady extends BrooklynDslDeferredSupplier<Object> {
-        private static final long serialVersionUID = 1740899524088902383L;
-        private final DslComponent component;
-        private final String sensorName;
-        public AttributeWhenReady(DslComponent component, String sensorName) {
-            this.component = Preconditions.checkNotNull(component);
-            this.sensorName = sensorName;
-        }
-        @SuppressWarnings("unchecked")
-        @Override
-        public Task<Object> newTask() {
-            Entity targetEntity = component.get();
-            Sensor<?> targetSensor = targetEntity.getEntityType().getSensor(sensorName);
-            if (!(targetSensor instanceof AttributeSensor<?>)) {
-                targetSensor = Sensors.newSensor(Object.class, sensorName);
-            }
-            return (Task<Object>) DependentConfiguration.attributeWhenReady(targetEntity, (AttributeSensor<?>)targetSensor);
-        }
-        @Override
-        public String toString() {
-            return (component.scope==Scope.THIS ? "" : component.toString()+".") +
-                "attributeWhenReady("+JavaStringEscapes.wrapJavaString(sensorName)+")";
-        }
-    }
-
-    public BrooklynDslDeferredSupplier<?> config(final String keyName) {
-        return new DslConfigSupplier(this, keyName);
-    }
-    protected final static class DslConfigSupplier extends BrooklynDslDeferredSupplier<Object> {
-        private final DslComponent component;
-        private final String keyName;
-        private static final long serialVersionUID = -4735177561947722511L;
-
-        public DslConfigSupplier(DslComponent component, String keyName) {
-            this.component = Preconditions.checkNotNull(component);
-            this.keyName = keyName;
-        }
-
-        @Override
-        public Task<Object> newTask() {
-            return Tasks.builder().name("retrieving config for "+keyName).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG).dynamic(false).body(new Callable<Object>() {
-                @Override
-                public Object call() throws Exception {
-                    Entity targetEntity = component.get();
-                    return targetEntity.getConfig(ConfigKeys.newConfigKey(Object.class, keyName));
-                }
-            }).build();
-        }
-
-        @Override
-        public String toString() {
-            return (component.scope==Scope.THIS ? "" : component.toString()+".") + 
-                "config("+JavaStringEscapes.wrapJavaString(keyName)+")";
-        }
-    }
-    
-    public BrooklynDslDeferredSupplier<Sensor<?>> sensor(final String sensorName) {
-        return new DslSensorSupplier(this, sensorName);
-    }
-    protected final static class DslSensorSupplier extends BrooklynDslDeferredSupplier<Sensor<?>> {
-        private final DslComponent component;
-        private final String sensorName;
-        private static final long serialVersionUID = -4735177561947722511L;
-
-        public DslSensorSupplier(DslComponent component, String sensorName) {
-            this.component = Preconditions.checkNotNull(component);
-            this.sensorName = sensorName;
-        }
-
-        @Override
-        public Task<Sensor<?>> newTask() {
-            return Tasks.<Sensor<?>>builder().name("looking up sensor for "+sensorName).dynamic(false).body(new Callable<Sensor<?>>() {
-                @Override
-                public Sensor<?> call() throws Exception {
-                    Entity targetEntity = component.get();
-                    Sensor<?> result = null;
-                    if (targetEntity!=null) {
-                        result = targetEntity.getEntityType().getSensor(sensorName);
-                    }
-                    if (result!=null) return result;
-                    return Sensors.newSensor(Object.class, sensorName);
-                }
-            }).build();
-        }
-
-        @Override
-        public String toString() {
-            return (component.scope==Scope.THIS ? "" : component.toString()+".") + 
-                "sensor("+JavaStringEscapes.wrapJavaString(sensorName)+")";
-        }
-    }
-
-    public static enum Scope {
-        GLOBAL ("global"),
-        CHILD ("child"),
-        PARENT ("parent"),
-        SIBLING ("sibling"),
-        DESCENDANT ("descendant"),
-        ANCESTOR("ancestor"),
-        THIS ("this");
-        
-        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, THIS);
-        
-        private final String name;
-        
-        private Scope(String name) {
-            this.name = name;
-        }
-        
-        public static Scope fromString(String name) {
-            return tryFromString(name).get();
-        }
-        
-        public static Maybe<Scope> tryFromString(String name) {
-            for (Scope scope : VALUES)
-                if (scope.name.toLowerCase().equals(name.toLowerCase()))
-                    return Maybe.of(scope);
-            return Maybe.absent(new IllegalArgumentException(name + " is not a valid scope"));
-        }
-        
-        public static boolean isValid(String name) {
-            for (Scope scope : VALUES)
-                if (scope.name.toLowerCase().equals(name.toLowerCase()))
-                    return true;
-            return false;
-        }
-    }
-
-
-    @Override
-    public String toString() {
-        return "$brooklyn:entity("+
-            (scopeComponent==null ? "" : JavaStringEscapes.wrapJavaString(scopeComponent.toString())+", ")+
-            (scope==Scope.GLOBAL ? "" : JavaStringEscapes.wrapJavaString(scope.toString())+", ")+
-            JavaStringEscapes.wrapJavaString(componentId)+
-            ")";
-    }
-
-}
\ No newline at end of file


[04/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage-cli

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/Main.java b/usage/cli/src/main/java/brooklyn/cli/Main.java
deleted file mode 100644
index 53aeb78..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/Main.java
+++ /dev/null
@@ -1,986 +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 brooklyn.cli;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.Console;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-import brooklyn.BrooklynVersion;
-import brooklyn.basic.BrooklynTypes;
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import org.apache.brooklyn.catalog.CatalogItem;
-import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
-import brooklyn.catalog.internal.CatalogInitialization;
-import brooklyn.cli.CloudExplorer.BlobstoreGetBlobCommand;
-import brooklyn.cli.CloudExplorer.BlobstoreListContainerCommand;
-import brooklyn.cli.CloudExplorer.BlobstoreListContainersCommand;
-import brooklyn.cli.CloudExplorer.ComputeDefaultTemplateCommand;
-import brooklyn.cli.CloudExplorer.ComputeGetImageCommand;
-import brooklyn.cli.CloudExplorer.ComputeListHardwareProfilesCommand;
-import brooklyn.cli.CloudExplorer.ComputeListImagesCommand;
-import brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
-import brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
-import brooklyn.cli.ItemLister.ListAllCommand;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
-import brooklyn.entity.rebind.persister.PersistMode;
-import brooklyn.entity.rebind.transformer.CompoundTransformer;
-import brooklyn.entity.trait.Startable;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.launcher.BrooklynServerDetails;
-import brooklyn.launcher.config.StopWhichAppsOnShutdown;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.management.ha.HighAvailabilityMode;
-import brooklyn.management.ha.OsgiManager;
-import brooklyn.rest.security.PasswordHasher;
-import brooklyn.rest.util.ShutdownHandler;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
-import brooklyn.util.exceptions.FatalRuntimeException;
-import brooklyn.util.exceptions.UserFacingException;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.javalang.Enums;
-import brooklyn.util.net.Networking;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-import brooklyn.util.text.Strings;
-import brooklyn.util.time.Duration;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyShell;
-import io.airlift.command.Cli;
-import io.airlift.command.Cli.CliBuilder;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
-
-/**
- * This class is the primary CLI for brooklyn.
- * Run with the `help` argument for help.
- * <p>
- * This class is designed for subclassing, with subclasses typically:
- * <li> providing their own static {@link #main(String...)} (of course) which need simply invoke 
- *      {@link #execCli(String[])} with the arguments 
- * <li> returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()}
- * <li> providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired
- * <li> providing any other CLI customisations by overriding {@link #cliBuilder()}
- *      (typically calling the parent and then customizing the builder)
- * <li> populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)}
- */
-public class Main extends AbstractMain {
-
-    private static final Logger log = LoggerFactory.getLogger(Main.class);
-
-    public static void main(String... args) {
-        log.debug("Launching Brooklyn via CLI, with "+Arrays.toString(args));
-        BrooklynVersion.INSTANCE.logSummary();
-        new Main().execCli(args);
-    }
-
-    @Command(name = "generate-password", description = "Generates a hashed web-console password")
-    public static class GeneratePasswordCommand extends BrooklynCommandCollectingArgs {
-
-        @Option(name = { "--user" }, title = "username", required = true)
-        public String user;
-
-        @Option(name = { "--stdin" }, title = "read password from stdin, instead of console", 
-                description = "Before using stdin, read http://stackoverflow.com/a/715681/1393883 for discussion of security!")
-        public boolean useStdin;
-
-        @Override
-        public Void call() throws Exception {
-            checkCanReadPassword();
-            
-            System.out.print("Enter password: ");
-            System.out.flush();
-            String password = readPassword();
-            if (Strings.isBlank(password)) {
-                throw new UserFacingException("Password must not be blank; aborting");
-            }
-            
-            System.out.print("Re-enter password: ");
-            System.out.flush();
-            String password2 = readPassword();
-            if (!password.equals(password2)) {
-                throw new UserFacingException("Passwords did not match; aborting");
-            }
-
-            String salt = Identifiers.makeRandomId(4);
-            String sha256password = PasswordHasher.sha256(salt, new String(password));
-            
-            System.out.println();
-            System.out.println("Please add the following to your brooklyn.properties:");
-            System.out.println();
-            System.out.println("brooklyn.webconsole.security.users="+user);
-            System.out.println("brooklyn.webconsole.security.user."+user+".salt="+salt);
-            System.out.println("brooklyn.webconsole.security.user."+user+".sha256="+sha256password);
-
-            return null;
-        }
-        
-        private void checkCanReadPassword() {
-            if (useStdin) {
-                // yes; always
-            } else {
-                Console console = System.console();
-                if (console == null) {
-                    throw new FatalConfigurationRuntimeException("No console; cannot get password securely; aborting");
-                }
-            }
-        }
-        
-        private String readPassword() throws IOException {
-            if (useStdin) {
-                return readLine(System.in);
-            } else {
-                return new String(System.console().readPassword());
-            }
-        }
-        
-        private String readLine(InputStream in) throws IOException {
-            StringBuilder result = new StringBuilder();
-            char c;
-            while ((c = (char)in.read()) != '\n') {
-                result.append(c);
-            }
-            return result.toString();
-        }
-    }
-    
-    @Command(name = "launch", description = "Starts a server, optionally with applications")
-    public static class LaunchCommand extends BrooklynCommandCollectingArgs {
-
-        @Option(name = { "--localBrooklynProperties" }, title = "local brooklyn.properties file",
-                description = "Load the given properties file, specific to this launch (appending to and overriding global properties)")
-        public String localBrooklynProperties;
-
-        @Option(name = { "--noGlobalBrooklynProperties" }, title = "do not use any global brooklyn.properties file found",
-            description = "Do not use the default global brooklyn.properties file found")
-        public boolean noGlobalBrooklynProperties = false;
-
-        @Option(name = { "-a", "--app" }, title = "application class or file",
-                description = "The Application to start. " +
-                        "For example, my.AppName, file://my/app.yaml, or classpath://my/AppName.groovy -- "
-                        + "note that a BROOKLYN_CLASSPATH environment variable may be required to "
-                        + "load classes from other locations")
-        public String app;
-
-        @Beta
-        @Option(name = { "-s", "--script" }, title = "script URI",
-                description = "EXPERIMENTAL. URI for a Groovy script to parse and load." +
-                        " This script will run before starting the app.")
-        public String script = null;
-
-        @Option(name = { "-l", "--location", "--locations" }, title = "location list",
-                description = "Specifies the locations where the application will be launched. " +
-                        "You can specify more than one location as a comma-separated list of values " +
-                        "(or as a JSON array, if the values are complex)")
-        public String locations;
-
-        @Option(name = { "--catalogInitial" }, title = "catalog initial bom URI",
-            description = "Specifies a catalog.bom URI to be used to populate the initial catalog, "
-                + "loaded on first run, or when persistence is off/empty or the catalog is reset")
-        public String catalogInitial;
-
-        @Option(name = { "--catalogReset" }, 
-            description = "Specifies that any catalog items which have been persisted should be cleared")
-        public boolean catalogReset;
-
-        @Option(name = { "--catalogAdd" }, title = "catalog bom URI to add",
-            description = "Specifies a catalog.bom to be added to the catalog")
-        public String catalogAdd;
-
-        @Option(name = { "--catalogForce" }, 
-            description = "Specifies that catalog items added via the CLI should be forcibly added, "
-                + "replacing any identical versions already registered (use with care!)")
-        public boolean catalogForce;
-
-        @Option(name = { "-p", "--port" }, title = "port number",
-                description = "Use this port for the brooklyn management web console and REST API; "
-                    + "default is 8081+ for http, 8443+ for https.")
-        public String port;
-
-        @Option(name = { "--https" },
-            description = "Launch the web console on https")
-        public boolean useHttps = false;
-        
-        @Option(name = { "-nc", "--noConsole" },
-                description = "Do not start the web console or REST API")
-        public boolean noConsole = false;
-
-        @Option(name = { "-b", "--bindAddress" },
-                description = "Specifies the IP address of the NIC to bind the Brooklyn Management Console to")
-        public String bindAddress = null;
-
-        @Option(name = { "-pa", "--publicAddress" },
-                description = "Specifies the IP address or hostname that the Brooklyn Management Console will be available on")
-        public String publicAddress = null;
-
-        @Option(name = { "--noConsoleSecurity" },
-                description = "Whether to disable authentication and security filters for the web console (for use when debugging on a secure network or bound to localhost)")
-        public Boolean noConsoleSecurity = false;
-
-        @Option(name = { "--startupContinueOnWebErrors" },
-            description = "Continue on web subsystem failures during startup "
-                + "(default is to abort if the web API fails to start, as management access is not normally possible)")
-        public boolean startupContinueOnWebErrors = false;
-
-        @Option(name = { "--startupFailOnPersistenceErrors" },
-            description = "Fail on persistence/HA subsystem failures during startup "
-                + "(default is to continue, so errors can be viewed via the API)")
-        public boolean startupFailOnPersistenceErrors = false;
-
-        @Option(name = { "--startupFailOnCatalogErrors" },
-            description = "Fail on catalog subsystem failures during startup "
-                + "(default is to continue, so errors can be viewed via the API)")
-        public boolean startupFailOnCatalogErrors = false;
-
-        @Option(name = { "--startupFailOnManagedAppsErrors" },
-            description = "Fail startup on errors deploying of managed apps specified via the command line "
-                + "(default is to continue, so errors can be viewed via the API)")
-        public boolean startupFailOnManagedAppsErrors = false;
-
-        @Beta
-        @Option(name = { "--startBrooklynNode" },
-                description = "Start a BrooklynNode entity representing this Brooklyn instance")
-        public boolean startBrooklynNode = false;
-
-        // Note in some cases, you can get java.util.concurrent.RejectedExecutionException
-        // if shutdown is not co-ordinated, looks like: {@linktourl https://gist.github.com/47066f72d6f6f79b953e}
-        @Beta
-        @Option(name = { "-sk", "--stopOnKeyPress" },
-                description = "Shutdown immediately on user text entry after startup (useful for debugging and demos)")
-        public boolean stopOnKeyPress = false;
-
-        final static String STOP_WHICH_APPS_ON_SHUTDOWN = "--stopOnShutdown";
-        protected final static String STOP_ALL = "all";
-        protected final static String STOP_ALL_IF_NOT_PERSISTED = "allIfNotPersisted";
-        protected final static String STOP_NONE = "none";
-        protected final static String STOP_THESE = "these";        
-        protected final static String STOP_THESE_IF_NOT_PERSISTED = "theseIfNotPersisted";
-        static { Enums.checkAllEnumeratedIgnoreCase(StopWhichAppsOnShutdown.class, STOP_ALL, STOP_ALL_IF_NOT_PERSISTED, STOP_NONE, STOP_THESE, STOP_THESE_IF_NOT_PERSISTED); }
-        
-        @Option(name = { STOP_WHICH_APPS_ON_SHUTDOWN },
-            allowedValues = { STOP_ALL, STOP_ALL_IF_NOT_PERSISTED, STOP_NONE, STOP_THESE, STOP_THESE_IF_NOT_PERSISTED },
-            description = "Which managed applications to stop on shutdown. Possible values are:\n"+
-                "all: stop all apps\n"+
-                "none: leave all apps running\n"+
-                "these: stop the apps explicitly started on this command line, but leave others started subsequently running\n"+
-                "theseIfNotPersisted: stop the apps started on this command line IF persistence is not enabled, otherwise leave all running\n"+
-                "allIfNotPersisted: stop all apps IF persistence is not enabled, otherwise leave all running")
-        public String stopWhichAppsOnShutdown = STOP_THESE_IF_NOT_PERSISTED;
-
-        @Option(name = { "--exitAndLeaveAppsRunningAfterStarting" },
-                description = "Once the application to start (from --app) is running exit the process, leaving any entities running. "
-                    + "Can be used in combination with --persist auto --persistenceDir <custom folder location> to attach to the running app at a later time.")
-        public boolean exitAndLeaveAppsRunningAfterStarting = false;
-
-        final static String PERSIST_OPTION = "--persist";
-        protected final static String PERSIST_OPTION_DISABLED = "disabled";
-        protected final static String PERSIST_OPTION_AUTO = "auto";
-        protected final static String PERSIST_OPTION_REBIND = "rebind";
-        protected final static String PERSIST_OPTION_CLEAN = "clean";
-        static { Enums.checkAllEnumeratedIgnoreCase(PersistMode.class, PERSIST_OPTION_DISABLED, PERSIST_OPTION_AUTO, PERSIST_OPTION_REBIND, PERSIST_OPTION_CLEAN); }
-        
-        // TODO currently defaults to disabled; want it to default to on, when we're ready
-        // TODO how to force a line-split per option?!
-        //      Looks like java.io.airlift.airline.UsagePrinter is splitting the description by word, and
-        //      wrapping it automatically.
-        //      See https://github.com/airlift/airline/issues/30
-        @Option(name = { PERSIST_OPTION }, 
-                allowedValues = { PERSIST_OPTION_DISABLED, PERSIST_OPTION_AUTO, PERSIST_OPTION_REBIND, PERSIST_OPTION_CLEAN },
-                title = "persistence mode",
-                description =
-                        "The persistence mode. Possible values are: \n"+
-                        "disabled: will not read or persist any state; \n"+
-                        "auto: will rebind to any existing state, or start up fresh if no state; \n"+
-                        "rebind: will rebind to the existing state, or fail if no state available; \n"+
-                        "clean: will start up fresh (removing any existing state)")
-        public String persist = PERSIST_OPTION_DISABLED;
-
-        @Option(name = { "--persistenceDir" }, title = "persistence dir",
-                description = "The directory to read/write persisted state (or container name if using an object store)")
-        public String persistenceDir;
-
-        @Option(name = { "--persistenceLocation" }, title = "persistence location",
-            description = "The location spec for an object store to read/write persisted state")
-        public String persistenceLocation;
-
-        final static String HA_OPTION = "--highAvailability";
-        protected final static String HA_OPTION_DISABLED = "disabled";
-        protected final static String HA_OPTION_AUTO = "auto";
-        protected final static String HA_OPTION_MASTER = "master";
-        protected final static String HA_OPTION_STANDBY = "standby";
-        protected final static String HA_OPTION_HOT_STANDBY = "hot_standby";
-        protected final static String HA_OPTION_HOT_BACKUP = "hot_backup";
-        static { Enums.checkAllEnumeratedIgnoreCase(HighAvailabilityMode.class, HA_OPTION_AUTO, HA_OPTION_DISABLED, HA_OPTION_MASTER, HA_OPTION_STANDBY, HA_OPTION_HOT_STANDBY, HA_OPTION_HOT_BACKUP); }
-        
-        @Option(name = { HA_OPTION }, allowedValues = { HA_OPTION_DISABLED, HA_OPTION_AUTO, HA_OPTION_MASTER, HA_OPTION_STANDBY, HA_OPTION_HOT_STANDBY, HA_OPTION_HOT_BACKUP },
-                title = "high availability mode",
-                description =
-                        "The high availability mode. Possible values are: \n"+
-                        "disabled: management node works in isolation - will not cooperate with any other standby/master nodes in management plane; \n"+
-                        "auto: will look for other management nodes, and will allocate itself as standby or master based on other nodes' states; \n"+
-                        "master: will startup as master - if there is already a master then fails immediately; \n"+
-                        "standby: will start up as lukewarm standby with no state - if there is not already a master then fails immediately, "
-                        + "and if there is a master which subsequently fails, this node can promote itself; \n"+
-                        "hot_standby: will start up as hot standby in read-only mode - if there is not already a master then fails immediately, "
-                        + "and if there is a master which subseuqently fails, this node can promote itself; \n"+
-                        "hot_backup: will start up as hot backup in read-only mode - no master is required, and this node will not become a master"
-                        )
-        public String highAvailability = HA_OPTION_AUTO;
-
-        @VisibleForTesting
-        protected ManagementContext explicitManagementContext;
-        
-        @Override
-        public Void call() throws Exception {
-            // Configure launcher
-            BrooklynLauncher launcher;
-            AppShutdownHandler shutdownHandler = new AppShutdownHandler();
-            failIfArguments();
-            try {
-                if (log.isDebugEnabled()) log.debug("Invoked launch command {}", this);
-                
-                if (!quiet) stdout.println(banner);
-    
-                if (verbose) {
-                    if (app != null) {
-                        stdout.println("Launching brooklyn app: " + app + " in " + locations);
-                    } else {
-                        stdout.println("Launching brooklyn server (no app)");
-                    }
-                }
-    
-                PersistMode persistMode = computePersistMode();
-                HighAvailabilityMode highAvailabilityMode = computeHighAvailabilityMode(persistMode);
-                
-                StopWhichAppsOnShutdown stopWhichAppsOnShutdownMode = computeStopWhichAppsOnShutdown();
-                
-                computeLocations();
-                
-                ResourceUtils utils = ResourceUtils.create(this);
-                GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader());
-    
-                // First, run a setup script if the user has provided one
-                if (script != null) {
-                    execGroovyScript(utils, loader, script);
-                }
-    
-                launcher = createLauncher();
-
-                CatalogInitialization catInit = new CatalogInitialization(catalogInitial, catalogReset, catalogAdd, catalogForce);
-                catInit.addPopulationCallback(new Function<CatalogInitialization,Void>() {
-                    @Override
-                    public Void apply(CatalogInitialization catInit) {
-                        try {
-                            populateCatalog(catInit.getManagementContext().getCatalog());
-                        } catch (Throwable e) {
-                            catInit.handleException(e, "overridden main class populate catalog");
-                        }
-                        
-                        // Force load of catalog (so web console is up to date)
-                        confirmCatalog(catInit);
-                        return null;
-                    }
-                });
-                catInit.setFailOnStartupErrors(startupFailOnCatalogErrors);
-                launcher.catalogInitialization(catInit);
-                
-                launcher.persistMode(persistMode);
-                launcher.persistenceDir(persistenceDir);
-                launcher.persistenceLocation(persistenceLocation);
-
-                launcher.highAvailabilityMode(highAvailabilityMode);
-
-                launcher.stopWhichAppsOnShutdown(stopWhichAppsOnShutdownMode);
-                launcher.shutdownHandler(shutdownHandler);
-                
-                computeAndSetApp(launcher, utils, loader);
-                
-                customize(launcher);
-                
-            } catch (FatalConfigurationRuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new FatalConfigurationRuntimeException("Fatal error configuring Brooklyn launch: "+e.getMessage(), e);
-            }
-            
-            // Launch server
-            try {
-                launcher.start();
-            } catch (FatalRuntimeException e) {
-                // rely on caller logging this propagated exception
-                throw e;
-            } catch (Exception e) {
-                // for other exceptions we log it, possibly redundantly but better too much than too little
-                Exceptions.propagateIfFatal(e);
-                log.error("Error launching brooklyn: "+Exceptions.collapseText(e), e);
-                try {
-                    launcher.terminate();
-                } catch (Exception e2) {
-                    log.warn("Subsequent error during termination: "+e2);
-                    log.debug("Details of subsequent error during termination: "+e2, e2);
-                }
-                Exceptions.propagate(e);
-            }
-            
-            BrooklynServerDetails server = launcher.getServerDetails();
-            ManagementContext ctx = server.getManagementContext();
-            
-            if (verbose) {
-                Entities.dumpInfo(launcher.getApplications());
-            }
-            
-            if (!exitAndLeaveAppsRunningAfterStarting) {
-                waitAfterLaunch(ctx, shutdownHandler);
-            }
-
-            // will call mgmt.terminate() in BrooklynShutdownHookJob
-            return null;
-        }
-
-        /** can be overridden by subclasses which need to customize the launcher and/or management */
-        protected void customize(BrooklynLauncher launcher) {
-        }
-        
-        protected void computeLocations() {
-            boolean hasLocations = !Strings.isBlank(locations);
-            if (app != null) {
-                if (hasLocations && isYamlApp()) {
-                    log.info("YAML app combined with command line locations; YAML locations will take precedence; this behaviour may change in subsequent versions");
-                } else if (!hasLocations && isYamlApp()) {
-                    log.info("No locations supplied; defaulting to locations defined in YAML (if any)");
-                } else if (!hasLocations) {
-                    log.info("No locations supplied; starting with no locations");
-                }
-            } else if (hasLocations) {
-                log.error("Locations specified without any applications; ignoring locations");
-            }
-        }
-
-        protected boolean isYamlApp() {
-            return app != null && app.endsWith(".yaml");
-        }
-
-        protected PersistMode computePersistMode() {
-            Maybe<PersistMode> persistMode = Enums.valueOfIgnoreCase(PersistMode.class, persist);
-            if (!persistMode.isPresent()) {
-                if (Strings.isBlank(persist)) {
-                    throw new FatalConfigurationRuntimeException("Persist mode must not be blank");
-                } else {
-                    throw new FatalConfigurationRuntimeException("Illegal persist setting: "+persist);
-                }
-            }
-   
-            if (persistMode.get() == PersistMode.DISABLED) {
-                if (Strings.isNonBlank(persistenceDir))
-                    throw new FatalConfigurationRuntimeException("Cannot specify persistenceDir when persist is disabled");
-                if (Strings.isNonBlank(persistenceLocation))
-                    throw new FatalConfigurationRuntimeException("Cannot specify persistenceLocation when persist is disabled");
-            }
-            return persistMode.get();
-        }
-
-        protected HighAvailabilityMode computeHighAvailabilityMode(PersistMode persistMode) {
-            Maybe<HighAvailabilityMode> highAvailabilityMode = Enums.valueOfIgnoreCase(HighAvailabilityMode.class, highAvailability);
-            if (!highAvailabilityMode.isPresent()) {
-                if (Strings.isBlank(highAvailability)) {
-                    throw new FatalConfigurationRuntimeException("High availability mode must not be blank");
-                } else {
-                    throw new FatalConfigurationRuntimeException("Illegal highAvailability setting: "+highAvailability);
-                }
-            }
-   
-            if (highAvailabilityMode.get() != HighAvailabilityMode.DISABLED) {
-                if (persistMode == PersistMode.DISABLED) {
-                    if (highAvailabilityMode.get() == HighAvailabilityMode.AUTO)
-                        return HighAvailabilityMode.DISABLED;
-                    throw new FatalConfigurationRuntimeException("Cannot specify highAvailability when persistence is disabled");
-                } else if (persistMode == PersistMode.CLEAN && 
-                        (highAvailabilityMode.get() == HighAvailabilityMode.STANDBY 
-                        || highAvailabilityMode.get() == HighAvailabilityMode.HOT_STANDBY
-                        || highAvailabilityMode.get() == HighAvailabilityMode.HOT_BACKUP)) {
-                    throw new FatalConfigurationRuntimeException("Cannot specify highAvailability "+highAvailabilityMode.get()+" when persistence is CLEAN");
-                }
-            }
-            return highAvailabilityMode.get();
-        }
-        
-        protected StopWhichAppsOnShutdown computeStopWhichAppsOnShutdown() {
-            boolean isDefault = STOP_THESE_IF_NOT_PERSISTED.equals(stopWhichAppsOnShutdown);
-            if (exitAndLeaveAppsRunningAfterStarting && isDefault) {
-                return StopWhichAppsOnShutdown.NONE;
-            } else {
-                return Enums.valueOfIgnoreCase(StopWhichAppsOnShutdown.class, stopWhichAppsOnShutdown).get();
-            }
-        }
-        
-        @VisibleForTesting
-        /** forces the launcher to use the given management context, when programmatically invoked;
-         * mainly used when testing to inject a safe (and fast) mgmt context */
-        public void useManagementContext(ManagementContext mgmt) {
-            explicitManagementContext = mgmt;
-        }
-
-        protected BrooklynLauncher createLauncher() {
-            BrooklynLauncher launcher;
-            launcher = BrooklynLauncher.newInstance();
-            launcher.localBrooklynPropertiesFile(localBrooklynProperties)
-                    .ignorePersistenceErrors(!startupFailOnPersistenceErrors)
-                    .ignoreCatalogErrors(!startupFailOnCatalogErrors)
-                    .ignoreWebErrors(startupContinueOnWebErrors)
-                    .ignoreAppErrors(!startupFailOnManagedAppsErrors)
-                    .locations(Strings.isBlank(locations) ? ImmutableList.<String>of() : JavaStringEscapes.unwrapJsonishListIfPossible(locations));
-            
-            launcher.webconsole(!noConsole);
-            if (useHttps) {
-                // true sets it; false (not set) leaves it blank and falls back to config key
-                // (no way currently to override config key, but that could be added)
-                launcher.webconsoleHttps(useHttps);
-            }
-            launcher.webconsolePort(port);
-            
-            if (noGlobalBrooklynProperties) {
-                log.debug("Configuring to disable global brooklyn.properties");
-                launcher.globalBrooklynPropertiesFile(null);
-            }
-            if (noConsoleSecurity) {
-                log.info("Configuring to disable console security");
-                launcher.installSecurityFilter(false);
-            }
-            if (startBrooklynNode) {
-                log.info("Configuring BrooklynNode entity startup");
-                launcher.startBrooklynNode(true);
-            }
-            if (Strings.isNonEmpty(bindAddress)) {
-                log.debug("Configuring bind address as "+bindAddress);
-                launcher.bindAddress(Networking.getInetAddressWithFixedName(bindAddress));
-            }
-            if (Strings.isNonEmpty(publicAddress)) {
-                log.debug("Configuring public address as "+publicAddress);
-                launcher.publicAddress(Networking.getInetAddressWithFixedName(publicAddress));
-            }
-            if (explicitManagementContext!=null) {
-                log.debug("Configuring explicit management context "+explicitManagementContext);
-                launcher.managementContext(explicitManagementContext);
-            }
-            return launcher;
-        }
-
-        /** method intended for subclassing, to add custom items to the catalog */
-        protected void populateCatalog(BrooklynCatalog catalog) {
-            // nothing else added here
-        }
-
-        protected void confirmCatalog(CatalogInitialization catInit) {
-            // Force load of catalog (so web console is up to date)
-            Stopwatch time = Stopwatch.createStarted();
-            BrooklynCatalog catalog = catInit.getManagementContext().getCatalog();
-            Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems();
-            for (CatalogItem<Object, Object> item: items) {
-                try {
-                    if (item.getCatalogItemType()==CatalogItemType.TEMPLATE) {
-                        // skip validation of templates, they might contain instructions,
-                        // and additionally they might contain multiple items in which case
-                        // the validation below won't work anyway (you need to go via a deployment plan)
-                    } else {
-                        Object spec = catalog.createSpec(item);
-                        if (spec instanceof EntitySpec) {
-                            BrooklynTypes.getDefinedEntityType(((EntitySpec<?>)spec).getType());
-                        }
-                        log.debug("Catalog loaded spec "+spec+" for item "+item);
-                    }
-                } catch (Throwable throwable) {
-                    catInit.handleException(throwable, item);
-                }
-            }
-            log.debug("Catalog (size "+Iterables.size(items)+") confirmed in "+Duration.of(time));                      
-            // nothing else added here
-        }
-        
-        /** convenience for subclasses to specify that an app should run,
-         * throwing the right (caught) error if another app has already been specified */
-        protected void setAppToLaunch(String className) {
-            if (app!=null) {
-                if (app.equals(className)) return;
-                throw new FatalConfigurationRuntimeException("Cannot specify app '"+className+"' when '"+app+"' is already specified; "
-                    + "remove one or more conflicting CLI arguments.");
-            }
-            app = className;
-        }
-        
-        protected void computeAndSetApp(BrooklynLauncher launcher, ResourceUtils utils, GroovyClassLoader loader)
-            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
-            if (app != null) {
-                // Create the instance of the brooklyn app
-                log.debug("Loading the user's application: {}", app);
-   
-                if (isYamlApp()) {
-                    log.debug("Loading application as YAML spec: {}", app);
-                    String content = utils.getResourceAsString(app);
-                    launcher.application(content);
-                } else {
-                    Object loadedApp = loadApplicationFromClasspathOrParse(utils, loader, app);
-                    if (loadedApp instanceof ApplicationBuilder) {
-                        launcher.application((ApplicationBuilder)loadedApp);
-                    } else if (loadedApp instanceof Application) {
-                        launcher.application((AbstractApplication)loadedApp);
-                    } else {
-                        throw new FatalConfigurationRuntimeException("Unexpected application type "+(loadedApp==null ? null : loadedApp.getClass())+", for app "+loadedApp);
-                    }
-                }
-            }
-        }
-        
-        protected void waitAfterLaunch(ManagementContext ctx, AppShutdownHandler shutdownHandler) throws IOException {
-            if (stopOnKeyPress) {
-                // Wait for the user to type a key
-                log.info("Server started. Press return to stop.");
-                // Read in another thread so we can use timeout on the wait.
-                Task<Void> readTask = ctx.getExecutionManager().submit(new Callable<Void>() {
-                    @Override
-                    public Void call() throws Exception {
-                        stdin.read();
-                        return null;
-                    }
-                });
-                while (!shutdownHandler.isRequested()) {
-                    try {
-                        readTask.get(Duration.ONE_SECOND);
-                        break;
-                    } catch (TimeoutException e) {
-                        //check if there's a shutdown request
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                        throw Exceptions.propagate(e);
-                    } catch (ExecutionException e) {
-                        throw Exceptions.propagate(e);
-                    }
-                }
-                log.info("Shutting down applications.");
-                stopAllApps(ctx.getApplications());
-            } else {
-                // Block forever so that Brooklyn doesn't exit (until someone does cntrl-c or kill)
-                log.info("Launched Brooklyn; will now block until shutdown command received via GUI/API (recommended) or process interrupt.");
-                shutdownHandler.waitOnShutdownRequest();
-            }
-        }
-
-        protected void execGroovyScript(ResourceUtils utils, GroovyClassLoader loader, String script) {
-            log.debug("Running the user provided script: {}", script);
-            String content = utils.getResourceAsString(script);
-            GroovyShell shell = new GroovyShell(loader);
-            shell.evaluate(content);
-        }
-
-        /**
-         * Helper method that gets an instance of a brooklyn {@link AbstractApplication} or an {@link ApplicationBuilder}.
-         * Guaranteed to be non-null result of one of those types (throwing exception if app not appropriate).
-         */
-        @SuppressWarnings("unchecked")
-        protected Object loadApplicationFromClasspathOrParse(ResourceUtils utils, GroovyClassLoader loader, String app)
-                throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
-            
-            Class<?> tempclazz;
-            log.debug("Loading application as class on classpath: {}", app);
-            try {
-                tempclazz = loader.loadClass(app, true, false);
-            } catch (ClassNotFoundException cnfe) { // Not a class on the classpath
-                log.debug("Loading \"{}\" as class on classpath failed, now trying as .groovy source file", app);
-                String content = utils.getResourceAsString(app);
-                tempclazz = loader.parseClass(content);
-            }
-            final Class<?> clazz = tempclazz;
-            
-            // Instantiate an app builder (wrapping app class in ApplicationBuilder, if necessary)
-            if (ApplicationBuilder.class.isAssignableFrom(clazz)) {
-                Constructor<?> constructor = clazz.getConstructor();
-                return (ApplicationBuilder) constructor.newInstance();
-            } else if (StartableApplication.class.isAssignableFrom(clazz)) {
-                EntitySpec<? extends StartableApplication> appSpec;
-                if (tempclazz.isInterface())
-                    appSpec = EntitySpec.create((Class<? extends StartableApplication>) clazz);
-                else
-                    appSpec = EntitySpec.create(StartableApplication.class, (Class<? extends StartableApplication>) clazz);
-                return new ApplicationBuilder(appSpec) {
-                    @Override protected void doBuild() {
-                    }};
-            } else if (AbstractApplication.class.isAssignableFrom(clazz)) {
-                // TODO If this application overrides init() then in trouble, as that won't get called!
-                // TODO grr; what to do about non-startable applications?
-                // without this we could return ApplicationBuilder rather than Object
-                Constructor<?> constructor = clazz.getConstructor();
-                return (AbstractApplication) constructor.newInstance();
-            } else if (AbstractEntity.class.isAssignableFrom(clazz)) {
-                // TODO Should we really accept any entity type, and just wrap it in an app? That's not documented!
-                return new ApplicationBuilder() {
-                    @Override protected void doBuild() {
-                        addChild(EntitySpec.create(Entity.class).impl((Class<? extends AbstractEntity>)clazz).additionalInterfaces(clazz.getInterfaces()));
-                    }};
-            } else if (Entity.class.isAssignableFrom(clazz)) {
-                return new ApplicationBuilder() {
-                    @Override protected void doBuild() {
-                        addChild(EntitySpec.create((Class<? extends Entity>)clazz));
-                    }};
-            } else {
-                throw new FatalConfigurationRuntimeException("Application class "+clazz+" must extend one of ApplicationBuilder or AbstractApplication");
-            }
-        }
-
-        @VisibleForTesting
-        protected void stopAllApps(Collection<? extends Application> applications) {
-            for (Application application : applications) {
-                try {
-                    if (application instanceof Startable) {
-                        ((Startable)application).stop();
-                    }
-                } catch (Exception e) {
-                    log.error("Error stopping "+application+": "+e, e);
-                }
-            }
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("app", app)
-                    .add("script", script)
-                    .add("location", locations)
-                    .add("port", port)
-                    .add("bindAddress", bindAddress)
-                    .add("noConsole", noConsole)
-                    .add("noConsoleSecurity", noConsoleSecurity)
-                    .add("startupFailOnPersistenceErrors", startupFailOnPersistenceErrors)
-                    .add("startupFailsOnCatalogErrors", startupFailOnCatalogErrors)
-                    .add("startupContinueOnWebErrors", startupContinueOnWebErrors)
-                    .add("startupFailOnManagedAppsErrors", startupFailOnManagedAppsErrors)
-                    .add("catalogInitial", catalogInitial)
-                    .add("catalogAdd", catalogAdd)
-                    .add("catalogReset", catalogReset)
-                    .add("catalogForce", catalogForce)
-                    .add("stopWhichAppsOnShutdown", stopWhichAppsOnShutdown)
-                    .add("stopOnKeyPress", stopOnKeyPress)
-                    .add("localBrooklynProperties", localBrooklynProperties)
-                    .add("persist", persist)
-                    .add("persistenceLocation", persistenceLocation)
-                    .add("persistenceDir", persistenceDir)
-                    .add("highAvailability", highAvailability)
-                    .add("exitAndLeaveAppsRunningAfterStarting", exitAndLeaveAppsRunningAfterStarting);
-        }
-    }
-
-    @Command(name = "copy-state", description = "Retrieves persisted state")
-    public static class CopyStateCommand extends BrooklynCommandCollectingArgs {
-
-        @Option(name = { "--localBrooklynProperties" }, title = "local brooklyn.properties file",
-                description = "local brooklyn.properties file, specific to this launch (appending to and overriding global properties)")
-        public String localBrooklynProperties;
-
-        @Option(name = { "--persistenceDir" }, title = "persistence dir",
-                description = "The directory to read persisted state (or container name if using an object store)")
-        public String persistenceDir;
-
-        @Option(name = { "--persistenceLocation" }, title = "persistence location",
-            description = "The location spec for an object store to read persisted state")
-        public String persistenceLocation;
-    
-        @Option(name = { "--destinationDir" }, required = true, title = "destination dir",
-                description = "The directory to copy persistence data to")
-            public String destinationDir;
-        
-        @Option(name = { "--destinationLocation" }, title = "persistence location",
-                description = "The location spec for an object store to copy data to")
-            public String destinationLocation;
-        
-        @Option(name = { "--transformations" }, title = "transformations",
-                description = "local transformations file, to be applied to the copy of the data before uploading it")
-        public String transformations;
-        
-        @Override
-        public Void call() throws Exception {
-            checkNotNull(destinationDir, "destinationDir"); // presumably because required=true this will never be null!
-            
-            // Configure launcher
-            BrooklynLauncher launcher;
-            failIfArguments();
-            try {
-                log.info("Retrieving and copying persisted state to "+destinationDir+(Strings.isBlank(destinationLocation) ? "" : " @ "+destinationLocation));
-                
-                if (!quiet) stdout.println(banner);
-    
-                PersistMode persistMode = PersistMode.AUTO;
-                HighAvailabilityMode highAvailabilityMode = HighAvailabilityMode.DISABLED;
-                
-                launcher = BrooklynLauncher.newInstance()
-                        .localBrooklynPropertiesFile(localBrooklynProperties)
-                        .brooklynProperties(OsgiManager.USE_OSGI, false)
-                        .persistMode(persistMode)
-                        .persistenceDir(persistenceDir)
-                        .persistenceLocation(persistenceLocation)
-                        .highAvailabilityMode(highAvailabilityMode);
-                
-            } catch (FatalConfigurationRuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new FatalConfigurationRuntimeException("Fatal error configuring Brooklyn launch: "+e.getMessage(), e);
-            }
-            
-            try {
-                launcher.copyPersistedState(destinationDir, destinationLocation, loadTransformer(transformations));
-            } catch (FatalRuntimeException e) {
-                // rely on caller logging this propagated exception
-                throw e;
-            } catch (Exception e) {
-                // for other exceptions we log it, possibly redundantly but better too much than too little
-                Exceptions.propagateIfFatal(e);
-                log.error("Error retrieving persisted state: "+Exceptions.collapseText(e), e);
-                Exceptions.propagate(e);
-            } finally {
-                try {
-                    launcher.terminate();
-                } catch (Exception e2) {
-                    log.warn("Subsequent error during termination: "+e2);
-                    log.debug("Details of subsequent error during termination: "+e2, e2);
-                }
-            }
-            
-            return null;
-        }
-
-        protected CompoundTransformer loadTransformer(String transformationsFileUrl) {
-            return BrooklynPersistenceUtils.loadTransformer(ResourceUtils.create(this), transformationsFileUrl);
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("localBrooklynProperties", localBrooklynProperties)
-                    .add("persistenceLocation", persistenceLocation)
-                    .add("persistenceDir", persistenceDir)
-                    .add("destinationDir", destinationDir);
-        }
-    }
-
-    /** method intended for overriding when a different {@link Cli} is desired,
-     * or when the subclass wishes to change any of the arguments */
-    @SuppressWarnings("unchecked")
-    @Override
-    protected CliBuilder<BrooklynCommand> cliBuilder() {
-        CliBuilder<BrooklynCommand> builder = Cli.<BrooklynCommand>builder(cliScriptName())
-                .withDescription("Brooklyn Management Service")
-                .withDefaultCommand(cliDefaultInfoCommand())
-                .withCommands(
-                        HelpCommand.class,
-                        cliInfoCommand(),
-                        GeneratePasswordCommand.class,
-                        CopyStateCommand.class,
-                        ListAllCommand.class,
-                        cliLaunchCommand()
-                );
-
-        builder.withGroup("cloud-compute")
-                .withDescription("Access compute details of a given cloud")
-                .withDefaultCommand(HelpCommand.class)
-                .withCommands(
-                        ComputeListImagesCommand.class,
-                        ComputeListHardwareProfilesCommand.class,
-                        ComputeListInstancesCommand.class,
-                        ComputeGetImageCommand.class,
-                        ComputeDefaultTemplateCommand.class,
-                        ComputeTerminateInstancesCommand.class);
-
-        builder.withGroup("cloud-blobstore")
-                .withDescription("Access blobstore details of a given cloud")
-                .withDefaultCommand(HelpCommand.class)
-                .withCommands(
-                        BlobstoreListContainersCommand.class, 
-                        BlobstoreListContainerCommand.class,
-                        BlobstoreGetBlobCommand.class);
-
-        return builder;
-    }
-    
-    /** method intended for overriding when a custom {@link LaunchCommand} is being specified  */
-    protected Class<? extends BrooklynCommand> cliLaunchCommand() {
-        return LaunchCommand.class;
-    }
-    
-    /** method intended for overriding when a custom {@link InfoCommand} is being specified  */
-    protected Class<? extends BrooklynCommand> cliInfoCommand() {
-        return InfoCommand.class;
-    }
-    
-    /** method intended for overriding when a custom {@link InfoCommand} is being specified  */
-    protected Class<? extends BrooklynCommand> cliDefaultInfoCommand() {
-        return DefaultInfoCommand.class;
-    }
-    
-    public static class AppShutdownHandler implements ShutdownHandler {
-        private CountDownLatch lock = new CountDownLatch(1);
-
-        @Override
-        public void onShutdownRequest() {
-            lock.countDown();
-        }
-        
-        public boolean isRequested() {
-            return lock.getCount() == 0;
-        }
-
-        public void waitOnShutdownRequest() {
-            try {
-                lock.await();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                return; // exit gracefully
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/lister/ClassFinder.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/lister/ClassFinder.java b/usage/cli/src/main/java/brooklyn/cli/lister/ClassFinder.java
deleted file mode 100644
index 2fb913b..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/lister/ClassFinder.java
+++ /dev/null
@@ -1,153 +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 brooklyn.cli.lister;
-
-import java.io.File;
-import java.lang.annotation.Annotation;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-import org.reflections.Reflections;
-import org.reflections.scanners.FieldAnnotationsScanner;
-import org.reflections.scanners.SubTypesScanner;
-import org.reflections.scanners.TypeAnnotationsScanner;
-import org.reflections.util.ConfigurationBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.basic.BrooklynObject;
-import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.SoftwareProcessImpl;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
-import brooklyn.policy.basic.AbstractPolicy;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.javalang.UrlClassLoader;
-import brooklyn.util.net.Urls;
-import brooklyn.util.os.Os;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class ClassFinder {
-
-    private static final Logger log = LoggerFactory.getLogger(ClassFinder.class);
-
-    private static final Collection<Class<?>> BORING = ImmutableList.<Class<?>>of(
-            Entity.class,
-            AbstractEntity.class,
-            SoftwareProcessImpl.class,
-            Application.class,
-            AbstractApplication.class,
-            Policy.class,
-            Enricher.class,
-            AbstractPolicy.class,
-            AbstractEnricher.class);
-
-    public static Predicate<Class<?>> notBoring() {
-        return new Predicate<Class<?>>() {
-            public boolean apply(Class<?> input) {
-                return (input != null && !BORING.contains(input));
-            }
-        };
-    }
-    
-    public static Predicate<Class<?>> withAnnotation(final Class<? extends Annotation> annotation) {
-        return new Predicate<Class<?>>() {
-            public boolean apply(Class<?> input) {
-                return (input != null && input.getAnnotation(annotation) != null);
-            }
-        };
-    }
-    
-    public static Predicate<? super Class<? extends BrooklynObject>> withClassNameMatching(final String typeRegex) {
-        return new Predicate<Class<?>>() {
-            public boolean apply(Class<?> input) {
-                return (input != null && input.getName() != null && input.getName().matches(typeRegex));
-            }
-        };
-    }
-
-    /** finds a jar at a url, or for directories, jars under a path */
-    @Beta
-    public static List<URL> toJarUrls(String url) throws MalformedURLException {
-        if (url==null) throw new NullPointerException("Cannot read from null");
-        if (url=="") throw new NullPointerException("Cannot read from empty string");
-        
-        List<URL> result = Lists.newArrayList();
-        
-        String protocol = Urls.getProtocol(url);
-        if (protocol!=null) {
-            // it's a URL - easy
-            if ("file".equals(protocol)) {
-                url = ResourceUtils.tidyFileUrl(url);
-            }
-            result.add(new URL(url));
-        } else {
-            // treat as file
-            String tidiedPath = Os.tidyPath(url);
-            File tidiedFile = new File(tidiedPath);
-            if (tidiedFile.isDirectory()) {
-                List<File> toscan = Lists.newLinkedList();
-                toscan.add(tidiedFile);
-                while (toscan.size() > 0) {
-                    File file = toscan.remove(0);
-                    if (file.isFile()) {
-                        if (file.getName().toLowerCase().endsWith(".jar")) {
-                            result.add(new URL("file://"+file.getAbsolutePath()));
-                        }
-                    } else if (file.isDirectory()) {
-                        for (File subfile : file.listFiles()) {
-                            toscan.add(subfile);
-                        }
-                    } else {
-                        log.info("Cannot read "+file+"; not a file or directory");
-                    }
-                }
-            } else {
-                result.add(tidiedFile.toURI().toURL());
-            }
-        }
-        
-        return result;
-    }
-
-    public static <T extends BrooklynObject> Set<Class<? extends T>> findClasses(Collection<URL> urls, Class<T> clazz) {
-        ClassLoader classLoader = new UrlClassLoader(urls.toArray(new URL[urls.size()]));
-        
-        Reflections reflections = new ConfigurationBuilder()
-                .addClassLoader(classLoader)
-                .addScanners(new SubTypesScanner(), new TypeAnnotationsScanner(), new FieldAnnotationsScanner())
-                .addUrls(urls)
-                .build();
-        
-        Set<Class<? extends T>> types = reflections.getSubTypesOf(clazz);
-        
-        return types;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/lister/ItemDescriptors.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/lister/ItemDescriptors.java b/usage/cli/src/main/java/brooklyn/cli/lister/ItemDescriptors.java
deleted file mode 100644
index 5ffd57d..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/lister/ItemDescriptors.java
+++ /dev/null
@@ -1,173 +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 brooklyn.cli.lister;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.basic.BrooklynDynamicType;
-import brooklyn.basic.BrooklynObject;
-import brooklyn.basic.BrooklynType;
-import brooklyn.basic.BrooklynTypes;
-import org.apache.brooklyn.catalog.Catalog;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Effector;
-import brooklyn.entity.EntityType;
-import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.event.Sensor;
-import brooklyn.location.LocationResolver;
-import brooklyn.rest.domain.EffectorSummary;
-import brooklyn.rest.domain.EntityConfigSummary;
-import brooklyn.rest.domain.SensorSummary;
-import brooklyn.rest.domain.SummaryComparators;
-import brooklyn.rest.transform.EffectorTransformer;
-import brooklyn.rest.transform.EntityTransformer;
-import brooklyn.rest.transform.SensorTransformer;
-import brooklyn.util.exceptions.RuntimeInterruptedException;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-public class ItemDescriptors {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ItemDescriptors.class);
-    
-    public static List<Map<String, Object>> toItemDescriptors(Iterable<? extends Class<? extends BrooklynObject>> types, boolean headingsOnly) {
-        return toItemDescriptors(types, headingsOnly, null);
-    }
-    
-    public static List<Map<String, Object>> toItemDescriptors(Iterable<? extends Class<? extends BrooklynObject>> types, boolean headingsOnly, final String sortField) {
-        List<Map<String, Object>> itemDescriptors = Lists.newArrayList();
-        
-        for (Class<? extends BrooklynObject> type : types) {
-            try {
-                Map<String, Object> itemDescriptor = toItemDescriptor(type, headingsOnly);
-                itemDescriptors.add(itemDescriptor);
-            } catch (Throwable throwable) {
-                if (throwable instanceof InterruptedException)
-                    throw new RuntimeInterruptedException((InterruptedException) throwable);
-                if (throwable instanceof RuntimeInterruptedException)
-                    throw (RuntimeInterruptedException) throwable;
-
-                LOG.warn("Could not load "+type+": "+throwable);
-            }
-        }
-        
-        if (!Strings.isNullOrEmpty(sortField)) {
-            Collections.sort(itemDescriptors, new Comparator<Map<String, Object>>() {
-                @Override public int compare(Map<String, Object> id1, Map<String, Object> id2) {
-                    Object o1 = id1.get(sortField);
-                    Object o2 = id2.get(sortField);
-                    if (o1 == null) {
-                        return o2 == null ? 0 : 1;
-                    }
-                    if (o2 == null) {
-                        return -1;
-                    }
-                    return o1.toString().compareTo(o2.toString());
-                }
-            });
-        }
-        
-        return itemDescriptors;
-    }
-    
-    public static Map<String,Object> toItemDescriptor(Class<? extends BrooklynObject> clazz, boolean headingsOnly) {
-        BrooklynDynamicType<?, ?> dynamicType = BrooklynTypes.getDefinedBrooklynType(clazz);
-        BrooklynType type = dynamicType.getSnapshot();
-        ConfigKey<?> version = dynamicType.getConfigKey(BrooklynConfigKeys.SUGGESTED_VERSION.getName());
-        
-        Map<String,Object> result = Maps.newLinkedHashMap();
-        
-        result.put("type", clazz.getName());
-        if (version != null) {
-            result.put("defaultVersion", version.getDefaultValue());
-        }
-        
-        Catalog catalogAnnotation = clazz.getAnnotation(Catalog.class);
-        if (catalogAnnotation != null) {
-            result.put("name", catalogAnnotation.name());
-            result.put("description", catalogAnnotation.description());
-            result.put("iconUrl", catalogAnnotation.iconUrl());
-        }
-        
-        Deprecated deprecatedAnnotation = clazz.getAnnotation(Deprecated.class);
-        if (deprecatedAnnotation != null) {
-            result.put("deprecated", true);
-        }
-        
-        if (!headingsOnly) {
-            Set<EntityConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
-            Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
-            Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());
-
-            for (ConfigKey<?> x: type.getConfigKeys()) {
-                config.add(EntityTransformer.entityConfigSummary(x, dynamicType.getConfigKeyField(x.getName())));
-            }
-            result.put("config", config);
-            
-            if (type instanceof EntityType) {
-                for (Sensor<?> x: ((EntityType)type).getSensors())
-                    sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
-                result.put("sensors", sensors);
-                
-                for (Effector<?> x: ((EntityType)type).getEffectors())
-                    effectors.add(EffectorTransformer.effectorSummaryForCatalog(x));
-                result.put("effectors", effectors);
-            }
-        }
-        
-        return result;
-    }
-    
-    public static Object toItemDescriptors(List<LocationResolver> resolvers) {
-        return toItemDescriptors(resolvers, false);
-    }
-    
-    public static Object toItemDescriptors(List<LocationResolver> resolvers, Boolean sort) {
-        List<Object> result = Lists.newArrayList();
-        for (LocationResolver resolver : resolvers) {
-            result.add(toItemDescriptor(resolver));
-        }
-        if (sort) {
-            Collections.sort(result, new Comparator<Object>() {
-                @Override public int compare(Object o1, Object o2) {
-                    String s1 = o1 == null ? "" : o1.toString();
-                    String s2 = o2 == null ? "" : o2.toString();
-                    return s1.compareTo(s2);
-                }
-            });
-        }
-        return result;
-    }
-
-    public static Object toItemDescriptor(LocationResolver resolver) {
-        // TODO Get javadoc of LocationResolver? Could use docklet? But that would give dependency here
-        // on com.sun.javadoc.*
-        return resolver.getPrefix();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/AbstractMain.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/AbstractMain.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/AbstractMain.java
new file mode 100644
index 0000000..1d34abe
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/AbstractMain.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.cli;
+
+import io.airlift.command.Arguments;
+import io.airlift.command.Cli;
+import io.airlift.command.Cli.CliBuilder;
+import io.airlift.command.Command;
+import io.airlift.command.Help;
+import io.airlift.command.Option;
+import io.airlift.command.OptionType;
+import io.airlift.command.ParseException;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import javax.inject.Inject;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.BrooklynVersion;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.cli.Main.LaunchCommand;
+
+import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
+import brooklyn.util.exceptions.FatalRuntimeException;
+import brooklyn.util.exceptions.UserFacingException;
+import brooklyn.util.text.Strings;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+
+/**
+ * This class is the primary CLI for brooklyn.
+ * Run with the `help` argument for help.
+ * <p>
+ * This class is designed for subclassing, with subclasses typically:
+ * <li> providing their own static {@link #main(String...)} (of course) which need simply invoke 
+ *      {@link #execCli(String[])} with the arguments 
+ * <li> returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()}
+ * <li> providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired
+ * <li> providing any other CLI customisations by overriding {@link #cliBuilder()}
+ *      (typically calling the parent and then customizing the builder)
+ * <li> populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)}
+ */
+public abstract class AbstractMain {
+
+    private static final Logger log = LoggerFactory.getLogger(AbstractMain.class);
+
+    // Launch banner
+    public static final String DEFAULT_BANNER =
+        " _                     _    _             \n" +
+        "| |__  _ __ ___   ___ | | _| |_   _ _ __ (R)\n" +
+        "| '_ \\| '__/ _ \\ / _ \\| |/ / | | | | '_ \\ \n" +
+        "| |_) | | | (_) | (_) |   <| | |_| | | | |\n" +
+        "|_.__/|_|  \\___/ \\___/|_|\\_\\_|\\__, |_| |_|\n" +
+        "                              |___/             "+BrooklynVersion.get()+"\n";
+
+    // Error codes
+    public static final int SUCCESS = 0;
+    public static final int PARSE_ERROR = 1;
+    public static final int EXECUTION_ERROR = 2;
+    public static final int CONFIGURATION_ERROR = 3;
+
+    /**
+     * Field intended for sub-classes (with their own {@code main()}) to customize the banner.
+     * All accesses to the banner are done through this field, to ensure consistent customization.
+     * 
+     * Note that a {@code getBanner()} method is not an option for supporting this, because
+     * it is accessed from static inner-classes (such as {@link InfoCommand}, so non-static
+     * methods are not an option (and one can't override static methods).
+     */
+    protected static volatile String banner = DEFAULT_BANNER;
+    
+    /** abstract superclass for commands defining global options, but not arguments,
+     * as that prevents Help from being injectable in the {@link HelpCommand} subclass */
+    public static abstract class BrooklynCommand implements Callable<Void> {
+
+        @Option(type = OptionType.GLOBAL, name = { "-v", "--verbose" }, description = "Verbose mode")
+        public boolean verbose = false;
+
+        @Option(type = OptionType.GLOBAL, name = { "-q", "--quiet" }, description = "Quiet mode")
+        public boolean quiet = false;
+
+        @VisibleForTesting
+        protected PrintStream stdout = System.out;
+        
+        @VisibleForTesting
+        protected PrintStream stderr = System.err;
+
+        @VisibleForTesting
+        protected InputStream stdin = System.in;
+
+        public ToStringHelper string() {
+            return Objects.toStringHelper(getClass())
+                    .add("verbose", verbose)
+                    .add("quiet", quiet);
+        }
+
+        @Override
+        public String toString() {
+            return string().toString();
+        }
+    }
+    
+    /** common superclass for commands, defining global options (in our super) and extracting the arguments */
+    public static abstract class BrooklynCommandCollectingArgs extends BrooklynCommand {
+
+        /** extra arguments */
+        @Arguments
+        public List<String> arguments = new ArrayList<String>();
+        
+        /** @return true iff there are arguments; it also sys.errs a warning in that case  */
+        protected boolean warnIfArguments() {
+            if (arguments.isEmpty()) return false;
+            stderr.println("Invalid subcommand arguments: "+Strings.join(arguments, " "));
+            return true;
+        }
+        
+        /** throw {@link ParseException} iff there are arguments */
+        protected void failIfArguments() {
+            if (arguments.isEmpty()) return ;
+            throw new ParseException("Invalid subcommand arguments '"+Strings.join(arguments, " ")+"'");
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("arguments", arguments);
+        }
+    }
+
+    @Command(name = "help", description = "Display help for available commands")
+    public static class HelpCommand extends BrooklynCommand {
+
+        @Inject
+        public Help help;
+
+        @Override
+        public Void call() throws Exception {
+            if (log.isDebugEnabled()) log.debug("Invoked help command: {}", this);
+            return help.call();
+        }
+    }
+
+    @Command(name = "info", description = "Display information about brooklyn")
+    public static class InfoCommand extends BrooklynCommandCollectingArgs {
+        
+        @Override
+        public Void call() throws Exception {
+            if (log.isDebugEnabled()) log.debug("Invoked info command: {}", this);
+            warnIfArguments();
+
+            System.out.println(banner);
+            System.out.println("Version:  " + BrooklynVersion.get());
+            if (BrooklynVersion.INSTANCE.isSnapshot()) {
+                System.out.println("Git SHA1: " + BrooklynVersion.INSTANCE.getSha1FromOsgiManifest());
+            }
+            System.out.println("Website:  http://brooklyn.incubator.apache.org");
+            System.out.println("Source:   https://github.com/apache/incubator-brooklyn");
+            System.out.println();
+            System.out.println("Copyright 2011-2015 The Apache Software Foundation.");
+            System.out.println("Licensed under the Apache 2.0 License");
+            System.out.println();
+
+            return null;
+        }
+    }
+
+    public static class DefaultInfoCommand extends InfoCommand {
+        @Override
+        public Void call() throws Exception {
+            super.call();
+            System.out.println("ERROR: No command specified.");
+            System.out.println();
+            throw new ParseException("No command specified.");
+        }
+    }
+
+    /** method intended for overriding when the script filename is different 
+     * @return the name of the script the user has invoked */
+    protected String cliScriptName() {
+        return "brooklyn";
+    }
+
+    /** 
+     * Build the commands.
+     */
+    protected abstract CliBuilder<BrooklynCommand> cliBuilder();
+    
+    protected void execCli(String ...args) {
+        execCli(cliBuilder().build(), args);
+    }
+    
+    protected void execCli(Cli<BrooklynCommand> parser, String ...args) {
+        try {
+            log.debug("Parsing command line arguments: {}", Arrays.asList(args));
+            BrooklynCommand command = parser.parse(args);
+            log.debug("Executing command: {}", command);
+            command.call();
+            System.exit(SUCCESS);
+        } catch (ParseException pe) { // looks like the user typed it wrong
+            System.err.println("Parse error: " + pe.getMessage()); // display
+                                                                   // error
+            System.err.println(getUsageInfo(parser)); // display cli help
+            System.exit(PARSE_ERROR);
+        } catch (FatalConfigurationRuntimeException e) {
+            log.error("Configuration error: "+e.getMessage(), e.getCause());
+            System.err.println("Configuration error: " + e.getMessage());
+            System.exit(CONFIGURATION_ERROR);
+        } catch (FatalRuntimeException e) { // anticipated non-configuration error
+            log.error("Startup error: "+e.getMessage(), e.getCause());
+            System.err.println("Startup error: "+e.getMessage());
+            System.exit(EXECUTION_ERROR);
+        } catch (Exception e) { // unexpected error during command execution
+            log.error("Execution error: " + e.getMessage(), e);
+            System.err.println("Execution error: " + e.getMessage());
+            if (!(e instanceof UserFacingException))
+                e.printStackTrace();
+            System.exit(EXECUTION_ERROR);
+        }
+    }
+
+    protected String getUsageInfo(Cli<BrooklynCommand> parser) {
+        StringBuilder help = new StringBuilder();
+        help.append("\n");
+        Help.help(parser.getMetadata(), Collections.<String>emptyList(), help);
+        return help.toString();
+    }
+
+}


[10/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
deleted file mode 100644
index dab6ac2f..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
+++ /dev/null
@@ -1,96 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import org.testng.Assert;
-import org.testng.TestListenerAdapter;
-import org.testng.TestNG;
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
-import brooklyn.management.osgi.OsgiStandaloneTest;
-import brooklyn.management.osgi.OsgiTestResources;
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-
-
-public class CatalogYamlTemplateTest extends AbstractYamlTest {
-    
-    private static final String SIMPLE_ENTITY_TYPE = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY;
-
-    @Test
-    public void testAddCatalogItem() throws Exception {
-        CatalogItem<?, ?> item = makeItem();
-        assertEquals(item.getCatalogItemType(), CatalogItemType.TEMPLATE);
-        Assert.assertTrue(item.getPlanYaml().indexOf("sample comment")>=0,
-            "YAML did not include original comments; it was:\n"+item.getPlanYaml());
-        Assert.assertFalse(item.getPlanYaml().indexOf("description")>=0,
-            "YAML included metadata which should have been excluded; it was:\n"+item.getPlanYaml());
-
-        deleteCatalogEntity("t1");
-    }
-
-    @Test
-    public void testAddCatalogItemAndCheckSource() throws Exception {
-        // this will fail with the Eclipse TestNG plugin -- use the static main instead to run in eclipse!
-        // see Yamls.KnownClassVersionException for details
-        
-        CatalogItem<?, ?> item = makeItem();
-        Assert.assertTrue(item.getPlanYaml().indexOf("sample comment")>=0,
-            "YAML did not include original comments; it was:\n"+item.getPlanYaml());
-        Assert.assertFalse(item.getPlanYaml().indexOf("description")>=0,
-            "YAML included metadata which should have been excluded; it was:\n"+item.getPlanYaml());
-
-        deleteCatalogEntity("t1");
-    }
-
-    private CatalogItem<?, ?> makeItem() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-        
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: t1",
-            "  item_type: template",
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item:",
-            "    services:",
-            "    # this sample comment should be included",
-            "    - type: " + SIMPLE_ENTITY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("t1", TEST_VERSION);
-        return item;
-    }
-
-    // convenience for running in eclipse when the TestNG plugin drags in old version of snake yaml
-    public static void main(String[] args) {
-        TestListenerAdapter tla = new TestListenerAdapter();
-        TestNG testng = new TestNG();
-        testng.setTestClasses(new Class[] { CatalogYamlTemplateTest.class });
-        testng.addListener(tla);
-        testng.run();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
deleted file mode 100644
index 0249c3f..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
+++ /dev/null
@@ -1,258 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.catalog.internal.BasicBrooklynCatalog;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicApplication;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.entity.basic.ConfigKeys;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-public class CatalogYamlVersioningTest extends AbstractYamlTest {
-    
-    private BrooklynCatalog catalog;
-    
-    @BeforeMethod(alwaysRun = true)
-    public void setUp() {
-        super.setUp();
-        catalog = mgmt().getCatalog();
-    }
-
-    @Test
-    public void testAddItem() {
-        String symbolicName = "sampleId";
-        String version = "0.1.0";
-        addCatalogEntity(symbolicName, version);
-        assertSingleCatalogItem(symbolicName, version);
-    }
-
-    @Test
-    public void testAddUnversionedItem() {
-        String symbolicName = "sampleId";
-        addCatalogEntity(symbolicName, null);
-        assertSingleCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
-    }
-
-    @Test
-    public void testAddSameVersionFailsWhenIconIsDifferent() {
-        String symbolicName = "sampleId";
-        String version = "0.1.0";
-        addCatalogEntity(symbolicName, version);
-        addCatalogEntity(symbolicName, version);
-        try {
-            addCatalogEntity(symbolicName, version, BasicEntity.class.getName(), "classpath:/another/icon.png");
-            fail("Expected to fail");
-        } catch (IllegalStateException e) {
-            assertEquals(e.getMessage(), "Updating existing catalog entries is forbidden: " + symbolicName + ":" + version + ". Use forceUpdate argument to override.");
-        }
-    }
-    
-    @Test
-    public void testAddSameVersionForce() {
-        String symbolicName = "sampleId";
-        String version = "0.1.0";
-        addCatalogEntity(symbolicName, version);
-        forceCatalogUpdate();
-        String expectedType = "brooklyn.entity.basic.BasicApplication";
-        addCatalogEntity(symbolicName, version, expectedType);
-        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, version);
-        assertTrue(item.getPlanYaml().contains(expectedType), "Version not updated");
-    }
-    
-    @Test
-    public void testGetLatest() {
-        String symbolicName = "sampleId";
-        String v1 = "0.1.0";
-        String v2 = "0.2.0";
-        addCatalogEntity(symbolicName, v1);
-        addCatalogEntity(symbolicName, v2);
-        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
-        assertEquals(item.getVersion(), v2);
-    }
-    
-    @Test
-    public void testGetLatestStable() {
-        String symbolicName = "sampleId";
-        String v1 = "0.1.0";
-        String v2 = "0.2.0-SNAPSHOT";
-        addCatalogEntity(symbolicName, v1);
-        addCatalogEntity(symbolicName, v2);
-        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
-        assertEquals(item.getVersion(), v1);
-    }
-
-    @Test
-    public void testDelete() {
-        String symbolicName = "sampleId";
-        String version = "0.1.0";
-        addCatalogEntity(symbolicName, version);
-        assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
-        catalog.deleteCatalogItem(symbolicName, version);
-        assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
-    }
-    
-    @Test
-    public void testDeleteDefault() {
-        String symbolicName = "sampleId";
-        addCatalogEntity(symbolicName, null);
-        assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
-        catalog.deleteCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
-        assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
-    }
-    
-    @Test
-    public void testList() {
-        String symbolicName = "sampleId";
-        String v1 = "0.1.0";
-        String v2 = "0.2.0-SNAPSHOT";
-        addCatalogEntity(symbolicName, v1);
-        addCatalogEntity(symbolicName, v2);
-        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
-        assertEquals(Iterables.size(items), 2);
-    }
-    
-    @Test
-    public void testVersionedReference() throws Exception {
-        String symbolicName = "sampleId";
-        String parentName = "parentId";
-        String v1 = "0.1.0";
-        String v2 = "0.2.0";
-        String expectedType = BasicApplication.class.getName();
-
-        addCatalogEntity(symbolicName, v1, expectedType);
-        addCatalogEntity(symbolicName, v2);
-        addCatalogEntity(parentName, v1, symbolicName + ":" + v1);
-
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + parentName + ":" + v1);
-
-        assertEquals(app.getEntityType().getName(), expectedType);
-    }
-
-    @Test
-    public void testUnversionedReference() throws Exception {
-        String symbolicName = "sampleId";
-        String parentName = "parentId";
-        String v1 = "0.1.0";
-        String v2 = "0.2.0";
-        String expectedType = BasicApplication.class.getName();
-
-        addCatalogEntity(symbolicName, v1);
-        addCatalogEntity(symbolicName, v2, expectedType);
-        addCatalogEntity(parentName, v1, symbolicName);
-
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + parentName + ":" + v1);
-
-        assertEquals(app.getEntityType().getName(), expectedType);
-    }
-
-    private void doTestVersionedReferenceJustAdded(boolean isVersionImplicitSyntax) throws Exception {
-        addCatalogItems(            "brooklyn.catalog:",
-            "  version: 0.9",
-            "  items:",
-            "  - id: referrent",
-            "    item:",
-            "      type: "+BasicEntity.class.getName(),
-            "  - id: referrent",
-            "    version: 1.1",
-            "    item:",
-            "      type: "+BasicEntity.class.getName(),
-            "      brooklyn.config: { foo: bar }",
-            "  - id: referrer",
-            "    version: 1.0",
-            "    item:",
-            (isVersionImplicitSyntax ? 
-                "      type: referrent:1.1" :
-                "      type: referrent\n" +
-                "      version: 1.1"));
-        
-        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo("referrer")));
-        Assert.assertEquals(Iterables.size(items), 1, "Wrong number of: "+items);
-        CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
-        Assert.assertEquals(item.getVersion(), "1.0");
-        
-        Entity app = createAndStartApplication(
-            "services:",
-            (isVersionImplicitSyntax ? 
-                "- type: referrer:1.0" :
-                "- type: referrer\n" +
-                "  version: 1.0") );
-        Entity child = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertTrue(child instanceof BasicEntity, "Wrong child: "+child);
-        Assert.assertEquals(child.getConfig(ConfigKeys.newStringConfigKey("foo")), "bar");
-    }
-
-    @Test
-    public void testVersionedReferenceJustAddedExplicitVersion() throws Exception {
-        doTestVersionedReferenceJustAdded(false);
-    }
-    
-    @Test
-    public void testVersionedReferenceJustAddedImplicitVersionSyntax() throws Exception {
-        doTestVersionedReferenceJustAdded(true);
-    }
-    
-    private void assertSingleCatalogItem(String symbolicName, String version) {
-        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
-        CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
-        assertEquals(item.getSymbolicName(), symbolicName);
-        assertEquals(item.getVersion(), version);
-    }
-    
-    private void addCatalogEntity(String symbolicName, String version) {
-        addCatalogEntity(symbolicName, version, BasicEntity.class.getName());
-    }
-
-    private void addCatalogEntity(String symbolicName, String version, String type) {
-        addCatalogEntity(symbolicName, version, type, "classpath://path/to/myicon.jpg");
-    }
-    
-    private void addCatalogEntity(String symbolicName, String version, String type, String iconUrl) {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: "+iconUrl,
-            (version != null ? "  version: " + version : ""),
-            "",
-            "services:",
-            "- type: " + type);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicApp.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
deleted file mode 100644
index 46347c5..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
+++ /dev/null
@@ -1,27 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import brooklyn.entity.basic.BasicApplication;
-import brooklyn.entity.proxying.ImplementedBy;
-
-@ImplementedBy(TestBasicAppImpl.class)
-public interface TestBasicApp extends BasicApplication {
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
deleted file mode 100644
index 952ccd9..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
+++ /dev/null
@@ -1,24 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import brooklyn.entity.basic.BasicApplicationImpl;
-
-public class TestBasicAppImpl extends BasicApplicationImpl implements TestBasicApp {
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
deleted file mode 100644
index e701318..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
+++ /dev/null
@@ -1,79 +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 io.brooklyn.camp.brooklyn.spi.dsl;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.FunctionWithArgs;
-import io.brooklyn.camp.brooklyn.spi.dsl.parse.QuotedString;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.testng.annotations.Test;
-
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-@Test
-public class DslParseTest {
-
-    public void testParseString() {
-        assertEquals(new DslParser("\"hello world\"").parse(), new QuotedString(JavaStringEscapes.wrapJavaString("hello world")));
-    }
-
-    public void testParseNoArgFunction() {
-        Object fx = new DslParser("f()").parse();
-        fx = Iterables.getOnlyElement( (List<?>)fx );
-        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
-        assertEquals( ((FunctionWithArgs)fx).getArgs(), ImmutableList.of());
-    }
-    
-    public void testParseOneArgFunction() {
-        Object fx = new DslParser("f(\"x\")").parse();
-        fx = Iterables.getOnlyElement( (List<?>)fx );
-        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
-        assertEquals( ((FunctionWithArgs)fx).getArgs(), Arrays.asList(new QuotedString("\"x\"")) );
-    }
-    
-    public void testParseMultiArgMultiTypeFunction() {
-        // TODO Parsing "f(\"x\", 1)" fails, because it interprets 1 as a function rather than a number. Is that expected?
-        Object fx = new DslParser("f(\"x\", \"y\")").parse();
-        fx = Iterables.getOnlyElement( (List<?>)fx );
-        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
-        assertEquals( ((FunctionWithArgs)fx).getArgs(), ImmutableList.of(new QuotedString("\"x\""), new QuotedString("\"y\"")));
-    }
-
-    
-    public void testParseFunctionChain() {
-        Object fx = new DslParser("f(\"x\").g()").parse();
-        assertTrue(((List<?>)fx).size() == 2, ""+fx);
-        Object fx1 = ((List<?>)fx).get(0);
-        Object fx2 = ((List<?>)fx).get(1);
-        assertEquals( ((FunctionWithArgs)fx1).getFunction(), "f" );
-        assertEquals( ((FunctionWithArgs)fx1).getArgs(), ImmutableList.of(new QuotedString("\"x\"")) );
-        assertEquals( ((FunctionWithArgs)fx2).getFunction(), "g" );
-        assertTrue( ((FunctionWithArgs)fx2).getArgs().isEmpty() );
-    }
-    
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
new file mode 100644
index 0000000..9b3c855
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Set;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.rebind.RebindOptions;
+import brooklyn.entity.rebind.RebindTestFixture;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplication> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractYamlTest.class);
+    protected static final String TEST_VERSION = "0.1.2";
+
+    protected BrooklynCampPlatform platform;
+    protected BrooklynCampPlatformLauncherNoServer launcher;
+    private boolean forceUpdate;
+    
+    @BeforeMethod(alwaysRun = true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        launcher = new BrooklynCampPlatformLauncherNoServer() {
+            @Override
+            protected LocalManagementContext newMgmtContext() {
+                return (LocalManagementContext) mgmt();
+            }
+        };
+        launcher.launch();
+        platform = launcher.getCampPlatform();
+    }
+
+    @AfterMethod(alwaysRun = true)
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            super.tearDown();
+        } finally {
+            if (launcher != null) launcher.stopServers();
+        }
+    }
+
+    protected StartableApplication rebind(RebindOptions options) throws Exception {
+        StartableApplication result = super.rebind(options);
+        if (launcher != null) {
+            launcher.stopServers();
+            launcher = new BrooklynCampPlatformLauncherNoServer() {
+                @Override
+                protected LocalManagementContext newMgmtContext() {
+                    return (LocalManagementContext) mgmt();
+                }
+            };
+            launcher.launch();
+            platform = launcher.getCampPlatform();
+        }
+        return result;
+    }
+    
+    @Override
+    protected StartableApplication createApp() {
+        return null;
+    }
+
+    protected ManagementContext mgmt() {
+        return (newManagementContext != null) ? newManagementContext : origManagementContext;
+    }
+    
+    ///////////////////////////////////////////////////
+    // TODO code below is duplicate of AbstractYamlTest
+    ///////////////////////////////////////////////////
+    
+    protected void waitForApplicationTasks(Entity app) {
+        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(origManagementContext.getExecutionManager(), app);
+        getLogger().info("Waiting on " + tasks.size() + " task(s)");
+        for (Task<?> t : tasks) {
+            t.blockUntilEnded();
+        }
+    }
+
+    protected Reader loadYaml(String yamlFileName, String ...extraLines) throws Exception {
+        String input = new ResourceUtils(this).getResourceAsString(yamlFileName).trim();
+        StringBuilder builder = new StringBuilder(input);
+        for (String l: extraLines)
+            builder.append("\n").append(l);
+        return new StringReader(builder.toString());
+    }
+    
+    protected Entity createAndStartApplication(String... multiLineYaml) throws Exception {
+        return createAndStartApplication(joinLines(multiLineYaml));
+    }
+    
+    protected Entity createAndStartApplication(String input) throws Exception {
+        return createAndStartApplication(new StringReader(input));
+    }
+
+    protected Entity createAndStartApplication(Reader input) throws Exception {
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+        Assembly assembly;
+        try {
+            assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+        } catch (Exception e) {
+            getLogger().warn("Unable to instantiate " + at + " (rethrowing): " + e);
+            throw e;
+        }
+        getLogger().info("Test - created " + assembly);
+        final Entity app = origManagementContext.getEntityManager().getEntity(assembly.getId());
+        getLogger().info("App - " + app);
+        
+        // wait for app to have started
+        Set<Task<?>> tasks = origManagementContext.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+                BrooklynTaskTags.EFFECTOR_TAG, 
+                BrooklynTaskTags.tagForContextEntity(app), 
+                BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
+        Iterables.getOnlyElement(tasks).get();
+        
+        return app;
+    }
+
+    protected Entity createStartWaitAndLogApplication(Reader input) throws Exception {
+        Entity app = createAndStartApplication(input);
+        waitForApplicationTasks(app);
+
+        getLogger().info("App started:");
+        Entities.dumpInfo(app);
+        
+        return app;
+    }
+
+    protected void addCatalogItems(Iterable<String> catalogYaml) {
+        addCatalogItems(joinLines(catalogYaml));
+    }
+
+    protected void addCatalogItems(String... catalogYaml) {
+        addCatalogItems(joinLines(catalogYaml));
+    }
+
+    protected void addCatalogItems(String catalogYaml) {
+        mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
+    }
+
+    protected void deleteCatalogEntity(String catalogItem) {
+        mgmt().getCatalog().deleteCatalogItem(catalogItem, TEST_VERSION);
+    }
+
+    protected Logger getLogger() {
+        return LOG;
+    }
+
+    private String joinLines(Iterable<String> catalogYaml) {
+        return Joiner.on("\n").join(catalogYaml);
+    }
+
+    private String joinLines(String[] catalogYaml) {
+        return Joiner.on("\n").join(catalogYaml);
+    }
+
+    protected String ver(String id) {
+        return CatalogUtils.getVersionedId(id, TEST_VERSION);
+    }
+
+    public void forceCatalogUpdate() {
+        forceUpdate = true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
new file mode 100644
index 0000000..e222b9f
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Set;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public abstract class AbstractYamlTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractYamlTest.class);
+    protected static final String TEST_VERSION = "0.1.2";
+
+    private ManagementContext brooklynMgmt;
+    protected BrooklynCampPlatform platform;
+    protected BrooklynCampPlatformLauncherNoServer launcher;
+    private boolean forceUpdate;
+    
+    public AbstractYamlTest() {
+        super();
+    }
+
+    protected ManagementContext mgmt() { return brooklynMgmt; }
+    
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() {
+        forceUpdate = false;
+        launcher = new BrooklynCampPlatformLauncherNoServer() {
+            @Override
+            protected LocalManagementContext newMgmtContext() {
+                return newTestManagementContext();
+            }
+        };
+        launcher.launch();
+        brooklynMgmt = launcher.getBrooklynMgmt();
+        platform = launcher.getCampPlatform();
+    }
+
+    protected LocalManagementContext newTestManagementContext() {
+        // TODO they don't all need osgi, just a few do, so could speed it up by specifying when they do
+        return LocalManagementContextForTests.newInstanceWithOsgi();
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() {
+        if (brooklynMgmt != null) Entities.destroyAll(brooklynMgmt);
+        if (launcher != null) launcher.stopServers();
+    }
+
+    protected void waitForApplicationTasks(Entity app) {
+        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
+        getLogger().info("Waiting on " + tasks.size() + " task(s)");
+        for (Task<?> t : tasks) {
+            t.blockUntilEnded();
+        }
+    }
+
+    protected Reader loadYaml(String yamlFileName, String ...extraLines) throws Exception {
+        String input = new ResourceUtils(this).getResourceAsString(yamlFileName).trim();
+        StringBuilder builder = new StringBuilder(input);
+        for (String l: extraLines)
+            builder.append("\n").append(l);
+        return new StringReader(builder.toString());
+    }
+    
+    protected Entity createAndStartApplication(String... multiLineYaml) throws Exception {
+        return createAndStartApplication(joinLines(multiLineYaml));
+    }
+    
+    protected Entity createAndStartApplication(String input) throws Exception {
+        return createAndStartApplication(new StringReader(input));
+    }
+
+    protected Entity createAndStartApplication(Reader input) throws Exception {
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+        Assembly assembly;
+        try {
+            assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+        } catch (Exception e) {
+            getLogger().warn("Unable to instantiate " + at + " (rethrowing): " + e);
+            throw e;
+        }
+        getLogger().info("Test - created " + assembly);
+        final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+        getLogger().info("App - " + app);
+        
+        // wait for app to have started
+        Set<Task<?>> tasks = brooklynMgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+                BrooklynTaskTags.EFFECTOR_TAG, 
+                BrooklynTaskTags.tagForContextEntity(app), 
+                BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
+        Iterables.getOnlyElement(tasks).get();
+        
+        return app;
+    }
+
+    protected Entity createStartWaitAndLogApplication(Reader input) throws Exception {
+        Entity app = createAndStartApplication(input);
+        waitForApplicationTasks(app);
+
+        getLogger().info("App started:");
+        Entities.dumpInfo(app);
+        
+        return app;
+    }
+
+    protected void addCatalogItems(Iterable<String> catalogYaml) {
+        addCatalogItems(joinLines(catalogYaml));
+    }
+
+    protected void addCatalogItems(String... catalogYaml) {
+        addCatalogItems(joinLines(catalogYaml));
+    }
+
+    protected void addCatalogItems(String catalogYaml) {
+        mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
+    }
+
+    protected void deleteCatalogEntity(String catalogItem) {
+        mgmt().getCatalog().deleteCatalogItem(catalogItem, TEST_VERSION);
+    }
+
+    protected Logger getLogger() {
+        return LOG;
+    }
+
+    private String joinLines(Iterable<String> catalogYaml) {
+        return Joiner.on("\n").join(catalogYaml);
+    }
+
+    private String joinLines(String[] catalogYaml) {
+        return Joiner.on("\n").join(catalogYaml);
+    }
+
+    protected String ver(String id) {
+        return CatalogUtils.getVersionedId(id, TEST_VERSION);
+    }
+
+    public void forceCatalogUpdate() {
+        forceUpdate = true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AppYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AppYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AppYamlTest.java
new file mode 100644
index 0000000..44d9780
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AppYamlTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.api.client.repackaged.com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.test.entity.TestEntity;
+
+@Test
+public class AppYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(AppYamlTest.class);
+
+    @Test
+    public void testAutoWrapsEntityInApp() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestEntity");
+        
+        BasicApplication app = (BasicApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        @SuppressWarnings("unused")
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+    }
+    
+    @Test
+    public void testDoesNotAutoWrapApp() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestApplication");
+        
+        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        assertTrue(app.getChildren().isEmpty());
+    }
+    
+    @Test
+    public void testWrapsAppIfNameAtTopLevelAndOnApp() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "name: myTopLevelName",
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestApplication",
+                "  name: myEntityName");
+        
+        BasicApplication app = (BasicApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestApplication entity = (TestApplication) Iterables.getOnlyElement(app.getChildren());
+        assertEquals(app.getDisplayName(), "myTopLevelName");
+        assertEquals(entity.getDisplayName(), "myEntityName");
+    }
+    
+    @Test
+    public void testDoesNotWrapAppIfNoConflictingNameOnApp() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "name: myTopLevelName",
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestApplication");
+        
+        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        assertTrue(app.getChildren().isEmpty());
+        assertEquals(app.getDisplayName(), "myTopLevelName");
+    }
+    
+    @Test
+    public void testDoesNotWrapAppWithDefaultDisplayName() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "name: myTopLevelName",
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestApplication",
+                "  brooklyn.config:",
+                "    defaultDisplayName: myDefaultEntityName");
+        
+        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        assertTrue(app.getChildren().isEmpty());
+        assertEquals(app.getDisplayName(), "myTopLevelName");
+    }
+    
+    @Test
+    public void testUsesDefaultDisplayNameIfNoOther() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "services:",
+                "- serviceType: brooklyn.test.entity.TestApplication",
+                "  brooklyn.config:",
+                "    defaultDisplayName: myDefaultEntityName");
+        
+        TestApplication app = (TestApplication) createStartWaitAndLogApplication(new StringReader(yaml));
+        assertTrue(app.getChildren().isEmpty());
+        assertEquals(app.getDisplayName(), "myDefaultEntityName");
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
new file mode 100644
index 0000000..b65f042
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.Factory;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
+import brooklyn.policy.Policy;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.time.Duration;
+
+public class BrooklynYamlTypeInstantiatorTest extends AbstractYamlTest {
+
+    protected BrooklynClassLoadingContext loader() {
+        return JavaBrooklynClassLoadingContext.create(mgmt());
+    }
+    
+    @Test
+    public void testLoadPolicySpecProgrammatically() {
+        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
+        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName())).prefix("some");
+        
+        Assert.assertTrue(decoL.getConfigMap().isEmpty());
+        Assert.assertEquals(decoL.getTypeName().get(), ServiceRestarter.class.getName());
+        Assert.assertEquals(decoL.getType(), ServiceRestarter.class);
+        
+        Object sl1 = decoL.newInstance();
+        Assert.assertTrue(sl1 instanceof ServiceRestarter);
+        
+        Policy sl2 = decoL.newInstance(Policy.class);
+        Assert.assertTrue(sl2 instanceof ServiceRestarter);
+    }
+    
+    @Test
+    public void testLoadPolicySpecWithBrooklynConfig() {
+        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
+        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName(),
+            "brooklyn.config", MutableMap.of("failOnRecurringFailuresInThisDuration", Duration.seconds(42)))).prefix("some");
+        Policy sl2 = decoL.newInstance(Policy.class);
+        Assert.assertEquals(sl2.getConfig(ServiceRestarter.FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION).toSeconds(), 42);
+    }
+
+    @Test(groups = "WIP")
+    public void testLoadPolicySpecWithFlag() {
+        Factory loader = new BrooklynYamlTypeInstantiator.Factory(loader(), "test:"+JavaClassNames.niceClassAndMethod());
+        InstantiatorFromKey decoL = loader.from(MutableMap.of("some_type", ServiceRestarter.class.getName(),
+            "failOnRecurringFailuresInThisDuration", Duration.seconds(42))).prefix("some");
+        Policy sl2 = decoL.newInstance(Policy.class);
+        Assert.assertEquals(sl2.getConfig(ServiceRestarter.FAIL_ON_RECURRING_FAILURES_IN_THIS_DURATION).toSeconds(), 42);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
new file mode 100644
index 0000000..4fe40c8
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.api.client.repackaged.com.google.common.base.Joiner;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.net.HostAndPort;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.DoNothingSoftwareProcess;
+import brooklyn.entity.basic.Entities;
+import brooklyn.location.MachineLocation;
+import brooklyn.location.access.PortForwardManager;
+import brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import brooklyn.location.basic.LocationPredicates;
+import brooklyn.location.basic.Machines;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.location.basic.WinRmMachineLocation;
+import brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.test.Asserts;
+import brooklyn.util.net.UserAndHostAndPort;
+
+public class ByonLocationsYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(ByonLocationsYamlTest.class);
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testByonSpec() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location: byon(user=myuser,mykey=myval,hosts=\"1.1.1.1\")",
+                "services:",
+                "- serviceType: brooklyn.entity.basic.BasicApplication");
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(app.getLocations(), 0);
+        
+        Set<SshMachineLocation> machines = loc.getAvailable();
+        SshMachineLocation machine = Iterables.getOnlyElement(machines);
+        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  22), ImmutableMap.of("mykey", "myval"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testByonMachine() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location:",
+                "  byon:",
+                "    hosts:",
+                "    - ssh: 1.1.1.1:8022",
+                "      privateAddresses: [10.0.0.1]",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval",
+                "services:",
+                "- serviceType: brooklyn.entity.basic.BasicApplication");
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(app.getLocations(), 0);
+        
+        Set<SshMachineLocation> machines = loc.getAvailable();
+        SshMachineLocation machine = Iterables.getOnlyElement(machines);
+        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8022), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval"));
+        assertEquals(machine.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testByonWindowsMachine() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location:",
+                "  byon:",
+                "    hosts:",
+                "    - winrm: 1.1.1.1:8985",
+                "      privateAddresses: [10.0.0.1]",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval",
+                "      osfamily: windows",
+                "services:",
+                "- serviceType: brooklyn.entity.basic.BasicApplication");
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        FixedListMachineProvisioningLocation<WinRmMachineLocation> loc = (FixedListMachineProvisioningLocation<WinRmMachineLocation>) Iterables.get(app.getLocations(), 0);
+        
+        Set<WinRmMachineLocation> machines = loc.getAvailable();
+        WinRmMachineLocation machine = Iterables.getOnlyElement(machines);
+        assertMachine(machine, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8985), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval"));
+        assertEquals(machine.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testByonMultiMachine() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location:",
+                "  byon:",
+                "    hosts:",
+                "    - ssh: 1.1.1.1:8022",
+                "      privateAddresses: [10.0.0.1]",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval1",
+                "    - ssh: 1.1.1.2:8022",
+                "      privateAddresses: [10.0.0.2]",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval2",
+                "    - winrm: 1.1.1.3:8985",
+                "      privateAddresses: [10.0.0.3]",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval3",
+                "      osfamily: windows",
+                "services:",
+                "- serviceType: brooklyn.entity.basic.BasicApplication");
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
+        
+        Set<MachineLocation> machines = loc.getAvailable();
+        assertEquals(machines.size(), 3, "machines="+machines);
+        SshMachineLocation machine1 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval1"));
+        SshMachineLocation machine2 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval2"));
+        WinRmMachineLocation machine3 = (WinRmMachineLocation) Iterables.find(machines, Predicates.instanceOf(WinRmMachineLocation.class));
+
+        assertMachine(machine1, UserAndHostAndPort.fromParts("myuser", "1.1.1.1",  8022), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval1"));
+        assertEquals(machine1.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
+
+        assertMachine(machine2, UserAndHostAndPort.fromParts("myuser", "1.1.1.2",  8022), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval2"));
+        assertEquals(machine2.getPrivateAddresses(), ImmutableSet.of("10.0.0.2"));
+
+        assertMachine(machine3, UserAndHostAndPort.fromParts("myuser", "1.1.1.3",  8985), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval3"));
+        assertEquals(machine3.getPrivateAddresses(), ImmutableSet.of("10.0.0.3"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testByonPortMapping() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location:",
+                "  byon:",
+                "    hosts:",
+                "    - ssh: 1.1.1.1:22",
+                "      privateAddresses: [10.0.0.1]",
+                "      tcpPortMappings: {22: \"83.222.229.1:12001\", 8080: \"83.222.229.1:12002\"}",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval1",
+                "    - winrm: 1.1.1.2:8985",
+                "      privateAddresses: [10.0.0.2]",
+                "      tcpPortMappings: {8985: \"83.222.229.2:12003\", 8080: \"83.222.229.2:12004\"}",
+                "      password: mypassword",
+                "      user: myuser",
+                "      mykey: myval2",
+                "      osfamily: windows",
+                "services:",
+                "- serviceType: brooklyn.entity.basic.BasicApplication");
+
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
+        PortForwardManager pfm = (PortForwardManager) mgmt().getLocationRegistry().resolve("portForwardManager(scope=global)");
+        
+        Set<MachineLocation> machines = loc.getAvailable();
+        assertEquals(machines.size(), 2, "machines="+machines);
+        SshMachineLocation machine1 = (SshMachineLocation) Iterables.find(machines, LocationPredicates.configEqualTo(ConfigKeys.newStringConfigKey("mykey"), "myval1"));
+        WinRmMachineLocation machine2 = (WinRmMachineLocation) Iterables.find(machines, Predicates.instanceOf(WinRmMachineLocation.class));
+
+        assertMachine(machine1, UserAndHostAndPort.fromParts("myuser", "83.222.229.1", 12001), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval1"));
+        assertEquals(machine1.getPrivateAddresses(), ImmutableSet.of("10.0.0.1"));
+        assertEquals(pfm.lookup(machine1, 22), HostAndPort.fromParts("83.222.229.1", 12001));
+        assertEquals(pfm.lookup(machine1, 8080), HostAndPort.fromParts("83.222.229.1", 12002));
+        assertNull(pfm.lookup(machine1, 12345));
+        
+        assertMachine(machine2, UserAndHostAndPort.fromParts("myuser", "83.222.229.2",  12003), ImmutableMap.of(
+                SshMachineLocation.PASSWORD.getName(), "mypassword",
+                "mykey", "myval2"));
+        assertEquals(machine2.getPrivateAddresses(), ImmutableSet.of("10.0.0.2"));
+        assertEquals(pfm.lookup(machine2, 8985), HostAndPort.fromParts("83.222.229.2", 12003));
+        assertEquals(pfm.lookup(machine2, 8080), HostAndPort.fromParts("83.222.229.2", 12004));
+        assertNull(pfm.lookup(machine2, 12345));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testPassesInboundPortsToMachineAndRemovesOnceMachineReleased() throws Exception {
+        String yaml = Joiner.on("\n").join(
+                "location:",
+                "  byon:",
+                "    hosts:",
+                "    - ssh: 1.1.1.1:22",
+                "      password: mypassword",
+                "      user: myuser",
+                "services:",
+                "- type: brooklyn.entity.basic.DoNothingSoftwareProcess",
+                "  brooklyn.config:",
+                "    requiredOpenLoginPorts: [22, 1024]");
+
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        DoNothingSoftwareProcess entity = (DoNothingSoftwareProcess) Iterables.find(Entities.descendants(app), Predicates.instanceOf(DoNothingSoftwareProcess.class));
+        FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
+        
+        // Machine should have been given the inbound-ports
+        SshMachineLocation machine = Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
+        Asserts.assertEqualsIgnoringOrder((Iterable<?>)machine.config().get(CloudLocationConfig.INBOUND_PORTS), ImmutableList.of(22, 1024));
+        
+        // Stop the entity; should release the machine
+        entity.stop();
+        MachineLocation availableMachine = Iterables.getOnlyElement(loc.getAvailable());
+        assertEquals(availableMachine, machine);
+        assertNull(machine.config().get(CloudLocationConfig.INBOUND_PORTS));
+    }
+
+    private void assertMachine(SshMachineLocation machine, UserAndHostAndPort conn, Map<String, ?> config) {
+        assertEquals(machine.getAddress().getHostAddress(), conn.getHostAndPort().getHostText());
+        assertEquals(machine.getPort(), conn.getHostAndPort().getPort());
+        assertEquals(machine.getUser(), conn.getUser());
+        for (Map.Entry<String, ?> entry : config.entrySet()) {
+            Object actualVal = machine.getConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()));
+            assertEquals(actualVal, entry.getValue());
+        }
+    }
+    
+    private void assertMachine(WinRmMachineLocation machine, UserAndHostAndPort conn, Map<String, ?> config) {
+        assertEquals(machine.getAddress().getHostAddress(), conn.getHostAndPort().getHostText());
+        assertEquals(machine.getConfig(WinRmMachineLocation.WINRM_PORT), (Integer) conn.getHostAndPort().getPort());
+        assertEquals(machine.getUser(), conn.getUser());
+        for (Map.Entry<String, ?> entry : config.entrySet()) {
+            Object actualVal = machine.getConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()));
+            assertEquals(actualVal, entry.getValue());
+        }
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
new file mode 100644
index 0000000..fb0aa36
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.event.Sensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.task.Tasks;
+
+import com.google.common.collect.Iterables;
+import com.google.common.io.Files;
+
+@Test
+public class DslAndRebindYamlTest extends AbstractYamlTest {
+    
+    private static final Logger log = LoggerFactory.getLogger(DslAndRebindYamlTest.class);
+    
+    protected ClassLoader classLoader = getClass().getClassLoader();
+    protected File mementoDir;
+    protected Set<ManagementContext> mgmtContexts = MutableSet.of();
+
+    @Override
+    protected LocalManagementContext newTestManagementContext() {
+        if (mementoDir!=null) throw new IllegalStateException("already created mgmt context");
+        mementoDir = Files.createTempDir();
+        LocalManagementContext mgmt = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
+        mgmtContexts.add(mgmt);
+        return mgmt;
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    @Override
+    public void tearDown() {
+        for (ManagementContext mgmt: mgmtContexts) Entities.destroyAll(mgmt);
+        super.tearDown();
+        mementoDir = null;
+        mgmtContexts.clear();
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+    public Application rebind(Application app) throws Exception {
+        RebindTestUtils.waitForPersisted(app);
+        // not strictly needed, but for good measure:
+        RebindTestUtils.checkCurrentMementoSerializable(app);
+        Application result = RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+        mgmtContexts.add(result.getManagementContext());
+        return result;
+    }
+
+
+    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+        
+        return (TestEntity)entity;
+    }
+
+    public static <T> T getConfigInTask(final Entity entity, final ConfigKey<T> key) {
+        return Entities.submit(entity, Tasks.<T>builder().body(new Callable<T>() {
+            @Override
+            public T call() throws Exception {
+                return entity.getConfig(key);
+            }
+        }).build()).getUnchecked();
+    }
+    
+    @Test
+    public void testDslAttributeWhenReady() throws Exception {
+        Entity testEntity = entityWithAttributeWhenReady();
+        ((EntityInternal)testEntity).setAttribute(Sensors.newStringSensor("foo"), "bar");
+        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "bar");
+    }
+
+    @Test
+    public void testDslAttributeWhenReadyRebind() throws Exception {
+        Entity testEntity = entityWithAttributeWhenReady();
+        ((EntityInternal)testEntity).setAttribute(Sensors.newStringSensor("foo"), "bar");
+        Application app2 = rebind(testEntity.getApplication());
+        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
+        
+        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "bar");
+    }
+
+    private Entity entityWithAttributeWhenReady() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.confName: $brooklyn:component(\"x\").attributeWhenReady(\"foo\")");
+    }
+
+    private void doTestOnEntityWithSensor(Entity testEntity, Sensor<?> expectedSensor) throws Exception {
+        doTestOnEntityWithSensor(testEntity, expectedSensor, true);
+    }
+    private void doTestOnEntityWithSensor(Entity testEntity, Sensor<?> expectedSensor, boolean inTask) throws Exception {
+        @SuppressWarnings("rawtypes")
+        ConfigKey<Sensor> configKey = ConfigKeys.newConfigKey(Sensor.class, "test.sensor");
+        Sensor<?> s;
+        s = inTask ? getConfigInTask(testEntity, configKey) : testEntity.getConfig(configKey);
+        Assert.assertEquals(s, expectedSensor);
+        Application app2 = rebind(testEntity.getApplication());
+        Entity te2 = Iterables.getOnlyElement( app2.getChildren() );
+        s = inTask ? getConfigInTask(te2, configKey) : te2.getConfig(configKey);
+        Assert.assertEquals(s, expectedSensor);
+    }
+    
+    @Test
+    public void testDslSensorFromClass() throws Exception {
+        doTestOnEntityWithSensor(entityWithSensorFromClass(), Attributes.SERVICE_UP);
+        // without context it can still find it
+        doTestOnEntityWithSensor(entityWithSensorFromClass(), Attributes.SERVICE_UP, false);
+    }
+    @Test
+    public void testDslSensorLocal() throws Exception {
+        doTestOnEntityWithSensor(entityWithSensorLocal(), TestEntity.SEQUENCE);
+        // here without context it makes one up, so type info (and description etc) not present; 
+        // but context is needed to submit the DslDeferredSupplier object, so this would fail
+//        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, TestEntity.SEQUENCE.getName()), false);
+    }
+    @Test
+    public void testDslSensorAdHoc() throws Exception {
+        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, "sensor.foo"));
+        // here context has no impact, but it is needed to submit the DslDeferredSupplier object so this would fail
+//        doTestOnEntityWithSensor(entityWithSensorAdHoc(), Sensors.newSensor(Object.class, "sensor.foo"), false);
+    }
+    
+    private Entity entityWithSensorFromClass() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.sensor: $brooklyn:sensor(\""+Attributes.class.getName()+"\", \""+Attributes.SERVICE_UP.getName()+"\")");
+    }
+
+    private Entity entityWithSensorLocal() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.sensor: $brooklyn:sensor(\""+TestEntity.SEQUENCE.getName()+"\")");
+    }
+
+    private Entity entityWithSensorAdHoc() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.sensor: $brooklyn:sensor(\"sensor.foo\")");
+    }
+
+
+    @Test
+    public void testDslConfigFromRoot() throws Exception {
+        Entity testEntity = entityWithConfigFromRoot();
+        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "bar");
+    }
+
+    @Test
+    public void testDslConfigFromRootRebind() throws Exception {
+        Entity testEntity = entityWithConfigFromRoot();
+        Application app2 = rebind(testEntity.getApplication());
+        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
+        
+        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "bar");
+    }
+
+    private Entity entityWithConfigFromRoot() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.confName: $brooklyn:component(\"x\").config(\"foo\")",
+            "brooklyn.config:",
+            "  foo: bar");
+    }
+
+
+    @Test
+    public void testDslFormatString() throws Exception {
+        Entity testEntity = entityWithFormatString();
+        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "hello world");
+    }
+
+    @Test
+    public void testDslFormatStringRebind() throws Exception {
+        Entity testEntity = entityWithFormatString();
+        Application app2 = rebind(testEntity.getApplication());
+        Entity e2 = Iterables.getOnlyElement( app2.getChildren() );
+        
+        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "hello world");
+    }
+
+    private Entity entityWithFormatString() throws Exception {
+        return setupAndCheckTestEntityInBasicYamlWith( 
+            "  id: x",
+            "  brooklyn.config:",
+            "    test.confName: $brooklyn:formatString(\"hello %s\", \"world\")");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
new file mode 100644
index 0000000..f45fddb
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EmptySoftwareProcess;
+import brooklyn.entity.basic.Entities;
+import brooklyn.location.Location;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.Jsonya;
+
+@Test
+public class EmptySoftwareProcessYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(EnrichersYamlTest.class);
+
+    @Test(groups="Integration")
+    public void testProvisioningProperties() throws Exception {
+        Entity app = createAndStartApplication(
+            "location: localhost",
+            "services:",
+            "- type: "+EmptySoftwareProcess.class.getName(),
+            "  provisioning.properties:",
+            "    minRam: 16384");
+        waitForApplicationTasks(app);
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        EmptySoftwareProcess entity = (EmptySoftwareProcess) app.getChildren().iterator().next();
+        Map<String, Object> pp = entity.getConfig(EmptySoftwareProcess.PROVISIONING_PROPERTIES);
+        Assert.assertEquals(pp.get("minRam"), 16384);
+    }
+
+    @Test(groups="Integration")
+    public void testProvisioningPropertiesViaJsonya() throws Exception {
+        Entity app = createAndStartApplication(
+            Jsonya.newInstance()
+                .put("location", "localhost")
+                .at("services").list()
+                .put("type", EmptySoftwareProcess.class.getName())
+                .at("provisioning.properties").put("minRam", 16384)
+                .root().toString());
+        waitForApplicationTasks(app);
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        EmptySoftwareProcess entity = (EmptySoftwareProcess) app.getChildren().iterator().next();
+        Map<String, Object> pp = entity.getConfig(EmptySoftwareProcess.PROVISIONING_PROPERTIES);
+        Assert.assertEquals(pp.get("minRam"), 16384);
+    }
+
+    // for https://github.com/brooklyncentral/brooklyn/issues/1377
+    @Test(groups="Integration")
+    public void testWithAppAndEntityLocations() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: "+EmptySoftwareProcess.class.getName(),
+                "  location: localhost:(name=localhost on entity)",
+                "location: byon:(hosts=\"127.0.0.1\", name=loopback on app)");
+        waitForApplicationTasks(app);
+        Entities.dumpInfo(app);
+        
+        Assert.assertEquals(app.getLocations().size(), 1);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        
+        Location appLocation = app.getLocations().iterator().next();
+        Assert.assertEquals(appLocation.getDisplayName(), "loopback on app");
+        
+        Assert.assertEquals(entity.getLocations().size(), 2);
+        Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
+        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost on entity");
+        Location actualMachine = entityLocationIterator.next();
+        Assert.assertTrue(actualMachine instanceof SshMachineLocation, "wrong location: "+actualMachine);
+        // TODO this, below, probably should be 'localhost on entity', see #1377
+        Assert.assertEquals(actualMachine.getParent().getDisplayName(), "loopback on app");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
new file mode 100644
index 0000000..b416be5
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
+import brooklyn.event.basic.Sensors;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.util.collections.CollectionFunctionals;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.math.MathPredicates;
+import brooklyn.util.text.StringPredicates;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+/** Tests some improvements to enricher classes to make them a bit more yaml friendly.
+ * Called "SlightlySimpler" as it would be nice to make enrichers a lot more yaml friendly! */
+@Test
+public class EnrichersSlightlySimplerYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(EnrichersSlightlySimplerYamlTest.class);
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Test
+    public void testWithAppEnricher() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-app-with-enrichers-slightly-simpler.yaml"));
+        waitForApplicationTasks(app);
+        log.info("Started "+app+":");
+        Entities.dumpInfo(app);
+        
+        Entity cluster = Iterables.getOnlyElement( app.getChildren() );
+        Collection<Entity> leafs = ((DynamicCluster)cluster).getMembers();
+        Iterator<Entity> li = leafs.iterator();
+        
+        Entity e1 = li.next();
+        ((EntityInternal)e1).setAttribute(Sensors.newStringSensor("ip"), "127.0.0.1");
+        EntityTestUtils.assertAttributeEqualsEventually(e1, Sensors.newStringSensor("url"), "http://127.0.0.1/");
+        EntityTestUtils.assertAttributeEqualsEventually(e1, Attributes.MAIN_URI, URI.create("http://127.0.0.1/"));
+
+        int i=2;
+        while (li.hasNext()) {
+            Entity ei = li.next();
+            ((EntityInternal)ei).setAttribute(Sensors.newStringSensor("ip"), "127.0.0."+i);
+            i++;
+        }
+        
+        EntityTestUtils.assertAttributeEventually(cluster, Sensors.newSensor(Iterable.class, "urls.list"),
+            (Predicate)CollectionFunctionals.sizeEquals(3));
+        
+        EntityTestUtils.assertAttributeEventually(cluster, Sensors.newSensor(String.class, "urls.list.comma_separated.max_2"),
+            StringPredicates.matchesRegex("\"http:\\/\\/127[^\"]*\\/\",\"http:\\/\\/127[^\"]*\\/\""));
+
+        EntityTestUtils.assertAttributeEventually(cluster, Attributes.MAIN_URI, Predicates.notNull());
+        URI main = cluster.getAttribute(Attributes.MAIN_URI);
+        Assert.assertTrue(main.toString().matches("http:\\/\\/127.0.0..\\/"), "Wrong URI: "+main);
+        
+        EntityTestUtils.assertAttributeEventually(app, Attributes.MAIN_URI, Predicates.notNull());
+        main = app.getAttribute(Attributes.MAIN_URI);
+        Assert.assertTrue(main.toString().matches("http:\\/\\/127.0.0..\\/"), "Wrong URI: "+main);
+        
+        // TODO would we want to allow "all-but-usual" as the default if nothing specified
+    }
+    
+    @Test(groups="Integration")
+    public void testWebappWithAveragingEnricher() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-webapp-with-averaging-enricher.yaml"));
+        waitForApplicationTasks(app);
+        log.info("Started "+app+":");
+        Entities.dumpInfo(app);
+
+        List<JavaWebAppSoftwareProcess> appservers = MutableList.copyOf(Entities.descendants(app, JavaWebAppSoftwareProcess.class));
+        Assert.assertEquals(appservers.size(), 3);
+        
+        EntityInternal srv0 = (EntityInternal) appservers.get(0);
+        EntityInternal dwac = (EntityInternal) srv0.getParent();
+        EntityInternal cdwac = (EntityInternal) dwac.getParent();
+        
+        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), 20.0);
+        
+        EntityTestUtils.assertAttributeEventually(dwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            MathPredicates.equalsApproximately(20));
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            MathPredicates.equalsApproximately(20));
+
+        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), null);
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            Predicates.isNull());
+
+        ((EntityInternal) appservers.get(1)).setAttribute(Sensors.newDoubleSensor("my.load"), 10.0);
+        ((EntityInternal) appservers.get(2)).setAttribute(Sensors.newDoubleSensor("my.load"), 20.0);
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            MathPredicates.equalsApproximately(15));
+        srv0.setAttribute(Sensors.newDoubleSensor("my.load"), 0.0);
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            MathPredicates.equalsApproximately(10));
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+    
+}


[19/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
Package rename to org.apache.brooklyn: usage/camp/


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

Branch: refs/heads/master
Commit: e406d1ad4ede0410142c5426bc720920b91dc9f7
Parents: 74ee6aa
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 5 14:56:27 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 5 16:51:01 2015 +0100

----------------------------------------------------------------------
 .../camp/brooklyn/BrooklynCampConstants.java    |  50 -
 .../camp/brooklyn/BrooklynCampPlatform.java     |  76 --
 .../BrooklynCampPlatformLauncherAbstract.java   |  73 --
 .../BrooklynCampPlatformLauncherNoServer.java   |  36 -
 .../camp/brooklyn/BrooklynCampReservedKeys.java |  29 -
 .../camp/brooklyn/YamlLauncherAbstract.java     | 133 ---
 .../camp/brooklyn/YamlLauncherNoServer.java     |  39 -
 .../BrooklynAssemblyTemplateInstantiator.java   | 282 ------
 .../BrooklynComponentTemplateResolver.java      | 491 ----------
 .../BrooklynEntityDecorationResolver.java       | 181 ----
 .../spi/creation/BrooklynEntityMatcher.java     | 193 ----
 .../creation/BrooklynYamlLocationResolver.java  | 142 ---
 .../creation/BrooklynYamlTypeInstantiator.java  | 208 -----
 .../spi/creation/EntitySpecConfiguration.java   |  58 --
 .../service/BrooklynServiceTypeResolver.java    |  72 --
 .../service/CatalogServiceTypeResolver.java     |  78 --
 .../service/ChefServiceTypeResolver.java        |  62 --
 .../service/JavaServiceTypeResolver.java        |  39 -
 .../creation/service/ServiceTypeResolver.java   |  73 --
 .../spi/dsl/BrooklynDslDeferredSupplier.java    |  99 --
 .../spi/dsl/BrooklynDslInterpreter.java         | 188 ----
 .../camp/brooklyn/spi/dsl/DslUtils.java         |  44 -
 .../spi/dsl/methods/BrooklynDslCommon.java      | 302 ------
 .../brooklyn/spi/dsl/methods/DslComponent.java  | 320 -------
 .../camp/brooklyn/spi/dsl/parse/DslParser.java  | 144 ---
 .../spi/dsl/parse/FunctionWithArgs.java         |  57 --
 .../brooklyn/spi/dsl/parse/QuotedString.java    |  49 -
 .../lookup/AbstractBrooklynResourceLookup.java  |  36 -
 .../lookup/AbstractTemplateBrooklynLookup.java  |  62 --
 .../spi/lookup/AssemblyBrooklynLookup.java      |  69 --
 .../lookup/AssemblyTemplateBrooklynLookup.java  |  70 --
 .../brooklyn/spi/lookup/BrooklynUrlLookup.java  |  38 -
 .../lookup/PlatformComponentBrooklynLookup.java |  61 --
 ...PlatformComponentTemplateBrooklynLookup.java |  59 --
 .../platform/BrooklynImmutableCampPlatform.java | 107 ---
 .../camp/brooklyn/BrooklynCampConstants.java    |  50 +
 .../camp/brooklyn/BrooklynCampPlatform.java     |  78 ++
 .../BrooklynCampPlatformLauncherAbstract.java   |  73 ++
 .../BrooklynCampPlatformLauncherNoServer.java   |  36 +
 .../camp/brooklyn/BrooklynCampReservedKeys.java |  29 +
 .../camp/brooklyn/YamlLauncherAbstract.java     | 133 +++
 .../camp/brooklyn/YamlLauncherNoServer.java     |  39 +
 .../BrooklynAssemblyTemplateInstantiator.java   | 283 ++++++
 .../BrooklynComponentTemplateResolver.java      | 490 ++++++++++
 .../BrooklynEntityDecorationResolver.java       | 180 ++++
 .../spi/creation/BrooklynEntityMatcher.java     | 193 ++++
 .../creation/BrooklynYamlLocationResolver.java  | 142 +++
 .../creation/BrooklynYamlTypeInstantiator.java  | 208 +++++
 .../spi/creation/EntitySpecConfiguration.java   |  58 ++
 .../service/BrooklynServiceTypeResolver.java    |  71 ++
 .../service/CatalogServiceTypeResolver.java     |  78 ++
 .../service/ChefServiceTypeResolver.java        |  61 ++
 .../service/JavaServiceTypeResolver.java        |  39 +
 .../creation/service/ServiceTypeResolver.java   |  73 ++
 .../spi/dsl/BrooklynDslDeferredSupplier.java    |  99 ++
 .../spi/dsl/BrooklynDslInterpreter.java         | 188 ++++
 .../camp/brooklyn/spi/dsl/DslUtils.java         |  44 +
 .../spi/dsl/methods/BrooklynDslCommon.java      | 301 ++++++
 .../brooklyn/spi/dsl/methods/DslComponent.java  | 320 +++++++
 .../camp/brooklyn/spi/dsl/parse/DslParser.java  | 144 +++
 .../spi/dsl/parse/FunctionWithArgs.java         |  57 ++
 .../brooklyn/spi/dsl/parse/QuotedString.java    |  49 +
 .../lookup/AbstractBrooklynResourceLookup.java  |  36 +
 .../lookup/AbstractTemplateBrooklynLookup.java  |  62 ++
 .../spi/lookup/AssemblyBrooklynLookup.java      |  69 ++
 .../lookup/AssemblyTemplateBrooklynLookup.java  |  70 ++
 .../brooklyn/spi/lookup/BrooklynUrlLookup.java  |  38 +
 .../lookup/PlatformComponentBrooklynLookup.java |  61 ++
 ...PlatformComponentTemplateBrooklynLookup.java |  59 ++
 .../platform/BrooklynImmutableCampPlatform.java | 109 +++
 ...lyn.spi.creation.service.ServiceTypeResolver |  22 -
 ...lyn.spi.creation.service.ServiceTypeResolver |  22 +
 .../camp/brooklyn/AbstractYamlRebindTest.java   | 206 -----
 .../camp/brooklyn/AbstractYamlTest.java         | 182 ----
 .../io/brooklyn/camp/brooklyn/AppYamlTest.java  | 119 ---
 .../BrooklynYamlTypeInstantiatorTest.java       |  76 --
 .../camp/brooklyn/ByonLocationsYamlTest.java    | 281 ------
 .../camp/brooklyn/DslAndRebindYamlTest.java     | 245 -----
 .../brooklyn/EmptySoftwareProcessYamlTest.java  | 103 ---
 .../EnrichersSlightlySimplerYamlTest.java       | 134 ---
 .../camp/brooklyn/EnrichersYamlTest.java        | 257 ------
 .../brooklyn/EntitiesYamlIntegrationTest.java   |  71 --
 .../camp/brooklyn/EntitiesYamlTest.java         | 919 -------------------
 ...aWebAppWithDslYamlRebindIntegrationTest.java | 125 ---
 .../brooklyn/JavaWebAppsIntegrationTest.java    | 272 ------
 .../camp/brooklyn/JavaWebAppsMatchingTest.java  | 144 ---
 .../camp/brooklyn/LocationsYamlTest.java        | 285 ------
 .../camp/brooklyn/MapReferenceYamlTest.java     | 130 ---
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 280 ------
 .../camp/brooklyn/PoliciesYamlTest.java         | 215 -----
 .../camp/brooklyn/ReferencedYamlTest.java       | 180 ----
 .../brooklyn/ReferencingYamlTestEntity.java     |  66 --
 .../brooklyn/ReferencingYamlTestEntityImpl.java |  25 -
 .../brooklyn/ReloadBrooklynPropertiesTest.java  |  87 --
 .../camp/brooklyn/TestEntityWithInitConfig.java |  35 -
 .../brooklyn/TestEntityWithInitConfigImpl.java  |  59 --
 .../camp/brooklyn/TestReferencingEnricher.java  |  34 -
 .../camp/brooklyn/TestReferencingPolicy.java    |  34 -
 .../TestSensorAndEffectorInitializer.java       |  86 --
 .../brooklyn/VanillaBashNetcatYamlTest.java     | 113 ---
 .../io/brooklyn/camp/brooklyn/WrapAppTest.java  |  93 --
 .../catalog/AbstractCatalogXmlTest.java         | 109 ---
 .../CatalogOsgiVersionMoreEntityTest.java       | 261 ------
 .../brooklyn/catalog/CatalogXmlOsgiTest.java    |  37 -
 .../brooklyn/catalog/CatalogXmlVersionTest.java |  58 --
 .../brooklyn/catalog/CatalogYamlCombiTest.java  | 145 ---
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 781 ----------------
 .../catalog/CatalogYamlLocationTest.java        | 248 -----
 .../brooklyn/catalog/CatalogYamlPolicyTest.java | 196 ----
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 132 ---
 .../catalog/CatalogYamlTemplateTest.java        |  96 --
 .../catalog/CatalogYamlVersioningTest.java      | 258 ------
 .../camp/brooklyn/catalog/TestBasicApp.java     |  27 -
 .../camp/brooklyn/catalog/TestBasicAppImpl.java |  24 -
 .../camp/brooklyn/spi/dsl/DslParseTest.java     |  79 --
 .../camp/brooklyn/AbstractYamlRebindTest.java   | 208 +++++
 .../camp/brooklyn/AbstractYamlTest.java         | 184 ++++
 .../brooklyn/camp/brooklyn/AppYamlTest.java     | 119 +++
 .../BrooklynYamlTypeInstantiatorTest.java       |  75 ++
 .../camp/brooklyn/ByonLocationsYamlTest.java    | 281 ++++++
 .../camp/brooklyn/DslAndRebindYamlTest.java     | 245 +++++
 .../brooklyn/EmptySoftwareProcessYamlTest.java  | 103 +++
 .../EnrichersSlightlySimplerYamlTest.java       | 134 +++
 .../camp/brooklyn/EnrichersYamlTest.java        | 257 ++++++
 .../brooklyn/EntitiesYamlIntegrationTest.java   |  71 ++
 .../camp/brooklyn/EntitiesYamlTest.java         | 919 +++++++++++++++++++
 ...aWebAppWithDslYamlRebindIntegrationTest.java | 125 +++
 .../brooklyn/JavaWebAppsIntegrationTest.java    | 275 ++++++
 .../camp/brooklyn/JavaWebAppsMatchingTest.java  | 146 +++
 .../camp/brooklyn/LocationsYamlTest.java        | 285 ++++++
 .../camp/brooklyn/MapReferenceYamlTest.java     | 130 +++
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 280 ++++++
 .../camp/brooklyn/PoliciesYamlTest.java         | 215 +++++
 .../camp/brooklyn/ReferencedYamlTest.java       | 180 ++++
 .../brooklyn/ReferencingYamlTestEntity.java     |  66 ++
 .../brooklyn/ReferencingYamlTestEntityImpl.java |  25 +
 .../brooklyn/ReloadBrooklynPropertiesTest.java  |  89 ++
 .../camp/brooklyn/TestEntityWithInitConfig.java |  35 +
 .../brooklyn/TestEntityWithInitConfigImpl.java  |  59 ++
 .../camp/brooklyn/TestReferencingEnricher.java  |  34 +
 .../camp/brooklyn/TestReferencingPolicy.java    |  34 +
 .../TestSensorAndEffectorInitializer.java       |  86 ++
 .../brooklyn/VanillaBashNetcatYamlTest.java     | 114 +++
 .../brooklyn/camp/brooklyn/WrapAppTest.java     |  93 ++
 .../catalog/AbstractCatalogXmlTest.java         | 109 +++
 .../CatalogOsgiVersionMoreEntityTest.java       | 262 ++++++
 .../brooklyn/catalog/CatalogXmlOsgiTest.java    |  37 +
 .../brooklyn/catalog/CatalogXmlVersionTest.java |  58 ++
 .../brooklyn/catalog/CatalogYamlCombiTest.java  | 143 +++
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 780 ++++++++++++++++
 .../catalog/CatalogYamlLocationTest.java        | 247 +++++
 .../brooklyn/catalog/CatalogYamlPolicyTest.java | 195 ++++
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 132 +++
 .../catalog/CatalogYamlTemplateTest.java        |  95 ++
 .../catalog/CatalogYamlVersioningTest.java      | 257 ++++++
 .../camp/brooklyn/catalog/TestBasicApp.java     |  27 +
 .../camp/brooklyn/catalog/TestBasicAppImpl.java |  24 +
 .../camp/brooklyn/spi/dsl/DslParseTest.java     |  79 ++
 .../more-entities-osgi-catalog-scan.yaml        |  32 -
 .../more-entity-v1-called-v1-osgi-catalog.yaml  |  27 -
 .../catalog/more-entity-v1-osgi-catalog.yaml    |  27 -
 ...more-entity-v1-with-policy-osgi-catalog.yaml |  29 -
 .../catalog/more-entity-v2-osgi-catalog.yaml    |  28 -
 .../more-policies-osgi-catalog-scan.yaml        |  32 -
 .../catalog/simple-policy-osgi-catalog.yaml     |  27 -
 .../more-entities-osgi-catalog-scan.yaml        |  32 +
 .../more-entity-v1-called-v1-osgi-catalog.yaml  |  27 +
 .../catalog/more-entity-v1-osgi-catalog.yaml    |  27 +
 ...more-entity-v1-with-policy-osgi-catalog.yaml |  29 +
 .../catalog/more-entity-v2-osgi-catalog.yaml    |  28 +
 .../more-policies-osgi-catalog-scan.yaml        |  32 +
 .../catalog/simple-policy-osgi-catalog.yaml     |  27 +
 .../camp/src/test/resources/simple-catalog.xml  |   2 +-
 .../resources/test-entity-with-init-config.yaml |   2 +-
 .../resources/test-referencing-enrichers.yaml   |  26 +-
 .../resources/test-referencing-entities.yaml    |  12 +-
 .../resources/test-referencing-policies.yaml    |  26 +-
 .../brooklyn/launcher/BrooklynLauncher.java     |   4 +-
 .../camp/BrooklynCampPlatformLauncher.java      |   5 +-
 .../launcher/camp/SimpleYamlLauncher.java       |   4 +-
 .../blueprints/AbstractBlueprintTest.java       |   2 +-
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |   4 +-
 .../brooklyn/rest/HaMasterCheckFilterTest.java  |   2 +-
 .../rest/testing/BrooklynRestApiTest.java       |   2 +-
 184 files changed, 11602 insertions(+), 11596 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampConstants.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampConstants.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampConstants.java
deleted file mode 100644
index c8d3d1d..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampConstants.java
+++ /dev/null
@@ -1,50 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.CampPlatform;
-
-import java.util.Set;
-
-import brooklyn.config.BrooklynServerConfig;
-import brooklyn.config.ConfigInheritance;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-
-import com.google.common.collect.ImmutableSet;
-
-public class BrooklynCampConstants {
-
-    public static final String PLAN_ID_FLAG = "planId";
-
-    public static final ConfigKey<String> PLAN_ID = ConfigKeys.builder(String.class, "camp.plan.id")
-            .description("Identifier supplied in the deployment plan for component to which this entity corresponds "
-                        + "(human-readable, for correlating across plan, template, and instance)")
-            .inheritance(ConfigInheritance.NONE)
-            .build();
-
-    public static final ConfigKey<String> TEMPLATE_ID = ConfigKeys.builder(String.class, "camp.template.id")
-            .description("UID of the component in the CAMP template from which this entity was created")
-            .inheritance(ConfigInheritance.NONE)
-            .build();
-
-    public static final ConfigKey<CampPlatform> CAMP_PLATFORM = BrooklynServerConfig.CAMP_PLATFORM;
-
-    public static final Set<String> YAML_URL_PROTOCOL_WHITELIST = ImmutableSet.of("classpath", "http");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatform.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
deleted file mode 100644
index db4ce37..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
+++ /dev/null
@@ -1,76 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.AggregatingCampPlatform;
-import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
-import io.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslInterpreter;
-import io.brooklyn.camp.brooklyn.spi.platform.BrooklynImmutableCampPlatform;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
-import brooklyn.config.BrooklynProperties;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.ManagementContext.PropertiesReloadListener;
-
-/** {@link CampPlatform} implementation which includes Brooklyn entities 
- * (via {@link BrooklynImmutableCampPlatform})
- * and allows customisation / additions */
-public class BrooklynCampPlatform extends AggregatingCampPlatform implements HasBrooklynManagementContext {
-
-    private final ManagementContext bmc;
-
-    public BrooklynCampPlatform(PlatformRootSummary root, ManagementContext managementContext) {
-        super(root);
-        addPlatform(new BrooklynImmutableCampPlatform(root, managementContext));
-        
-        this.bmc = managementContext;
-        
-        addMatchers();
-        addInterpreters();
-        
-        managementContext.addPropertiesReloadListener(new PropertiesReloadListener() {
-            private static final long serialVersionUID = -3739276553334749184L;
-            @Override public void reloaded() {
-                setConfigKeyAtManagmentContext();
-            }
-        });
-    }
-
-    // --- brooklyn setup
-    
-    public ManagementContext getBrooklynManagementContext() {
-        return bmc;
-    }
-    
-    protected void addMatchers() {
-        // TODO artifacts
-        pdp().addMatcher(new BrooklynEntityMatcher(bmc));
-    }
-    
-    protected void addInterpreters() {
-        pdp().addInterpreter(new BrooklynDslInterpreter());
-    }
-
-    public BrooklynCampPlatform setConfigKeyAtManagmentContext() {
-        ((BrooklynProperties)bmc.getConfig()).put(BrooklynCampConstants.CAMP_PLATFORM, this);
-        return this;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
deleted file mode 100644
index 81f633a..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
+++ /dev/null
@@ -1,73 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.annotations.Beta;
-
-/** launcher for {@link BrooklynCampPlatform}, which may or may not start a (web) server depending on children */
-@Beta
-public abstract class BrooklynCampPlatformLauncherAbstract {
-
-    protected BrooklynCampPlatform platform;
-    protected ManagementContext mgmt;
-    
-    public BrooklynCampPlatformLauncherAbstract useManagementContext(ManagementContext mgmt) {
-        if (this.mgmt!=null && mgmt!=this.mgmt)
-            throw new IllegalStateException("Attempt to change mgmt context; not supported.");
-        
-        this.mgmt = mgmt;
-        
-        return this;
-    }
-    
-    public BrooklynCampPlatformLauncherAbstract launch() {
-        if (platform!=null)
-            throw new IllegalStateException("platform already created");
-
-        if (getBrooklynMgmt()==null)
-            useManagementContext(newMgmtContext());
-        
-        platform = new BrooklynCampPlatform(
-                PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
-                getBrooklynMgmt())
-            .setConfigKeyAtManagmentContext();
-        
-        return this;
-    }
-
-    protected LocalManagementContext newMgmtContext() {
-        return new LocalManagementContext();
-    }
-
-    public ManagementContext getBrooklynMgmt() {
-        return mgmt;
-    }
-    
-    public BrooklynCampPlatform getCampPlatform() {
-        return platform;
-    }
-
-    /** stops any servers (camp and brooklyn) launched by this launcher */
-    public abstract void stopServers() throws Exception;
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java
deleted file mode 100644
index 440c5ed..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.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 io.brooklyn.camp.brooklyn;
-
-import com.google.common.annotations.Beta;
-
-
-/** launcher for {@link BrooklynCampPlatform}, which does not start a server (and can live in this project) */
-@Beta
-public class BrooklynCampPlatformLauncherNoServer extends BrooklynCampPlatformLauncherAbstract {
-
-    public void stopServers() {
-        // nothing to do
-    }
-    
-    public static void main(String[] args) {
-        new BrooklynCampPlatformLauncherNoServer().launch();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
deleted file mode 100644
index b81e223..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
+++ /dev/null
@@ -1,29 +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 io.brooklyn.camp.brooklyn;
-
-public interface BrooklynCampReservedKeys {
-    public static final String BROOKLYN_CONFIG = "brooklyn.config";
-    public static final String BROOKLYN_FLAGS = "brooklyn.flags";
-    public static final String BROOKLYN_POLICIES = "brooklyn.policies";
-    public static final String BROOKLYN_ENRICHERS = "brooklyn.enrichers";
-    public static final String BROOKLYN_CHILDREN = "brooklyn.children";
-    public static final String BROOKLYN_INITIALIZERS = "brooklyn.initializers";
-    public static final String BROOKLYN_CATALOG = "brooklyn.catalog";
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherAbstract.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
deleted file mode 100644
index c4e7894..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
+++ /dev/null
@@ -1,133 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-
-import java.io.Reader;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BrooklynShutdownHooks;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.Entities;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.annotations.Beta;
-
-/** convenience for launching YAML files directly */
-@Beta
-public abstract class YamlLauncherAbstract {
-
-    private static final Logger log = LoggerFactory.getLogger(YamlLauncherAbstract.class);
-       
-    protected final BrooklynCampPlatformLauncherAbstract platformLauncher;
-
-    protected final BrooklynCampPlatform platform;
-    protected final ManagementContext brooklynMgmt;
-    protected boolean shutdownAppsOnExit = false;
-
-    public YamlLauncherAbstract() {
-        this.platformLauncher = newPlatformLauncher();
-        platformLauncher.launch();
-        this.platform = platformLauncher.getCampPlatform();
-        this.brooklynMgmt = platformLauncher.getBrooklynMgmt();
-    }
-
-    public ManagementContext getManagementContext() {
-        return brooklynMgmt;
-    }
-
-    public boolean getShutdownAppsOnExit() {
-        return shutdownAppsOnExit;
-    }
-    
-    public void setShutdownAppsOnExit(boolean shutdownAppsOnExit) {
-        this.shutdownAppsOnExit = shutdownAppsOnExit;
-    }
-    
-    protected abstract BrooklynCampPlatformLauncherAbstract newPlatformLauncher();
-
-    public Application launchAppYaml(String url) {
-        return launchAppYaml(url, true);
-    }
-
-    public Application launchAppYaml(String url, boolean waitForTasksToComplete) {
-        try {
-            Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl(url));
-            Application app = launchAppYaml(input, waitForTasksToComplete);
-            log.info("Application started from YAML file "+url+": "+app);
-            return app;
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    public Application launchAppYaml(Reader input) {
-        return launchAppYaml(input, true);
-    }
-
-    public Application launchAppYaml(Reader input, boolean waitForTasksToComplete) {
-        try {
-            AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-            Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-            log.info("Launching "+app);
-
-            if (getShutdownAppsOnExit()) BrooklynShutdownHooks.invokeStopOnShutdown(app);
-
-            if (waitForTasksToComplete) {
-                Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
-                log.info("Waiting on "+tasks.size()+" task(s)");
-                for (Task<?> t: tasks) {
-                    t.blockUntilEnded();
-                }
-            }
-
-            log.info("Application started from YAML: "+app);
-            Entities.dumpInfo(app);
-            return (Application)app;
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    /** kills all apps, web servers, and mgmt context
-     * <p>
-     * this launcher does not support being used again subsequently */
-    public void destroyAll() {
-        Entities.destroyAll(getManagementContext());
-        try {
-            platformLauncher.stopServers();
-        } catch (Exception e) {
-            log.warn("Unable to stop servers (ignoring): "+e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherNoServer.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
deleted file mode 100644
index c5ef371..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
+++ /dev/null
@@ -1,39 +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 io.brooklyn.camp.brooklyn;
-
-import com.google.common.annotations.Beta;
-
-/** convenience for launching YAML files directly */
-@Beta
-public class YamlLauncherNoServer extends YamlLauncherAbstract {
-
-    @Override
-    protected BrooklynCampPlatformLauncherAbstract newPlatformLauncher() {
-        return new BrooklynCampPlatformLauncherNoServer();
-    }
-
-    public static void main(String[] args) {
-        YamlLauncherNoServer l = new YamlLauncherNoServer();
-        l.setShutdownAppsOnExit(true);
-        
-        l.launchAppYaml("java-web-app-and-db-with-function.yaml");
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
deleted file mode 100644
index 7fb0da7..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ /dev/null
@@ -1,282 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.brooklyn.BrooklynCampConstants;
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.AssemblyTemplate.Builder;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
-import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.config.BrooklynServerConfig;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicApplicationImpl;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.internal.EntityManagementUtils;
-import brooklyn.management.internal.EntityManagementUtils.CreationResult;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.net.Urls;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynAssemblyTemplateInstantiator.class);
-
-    public static final String NEVER_UNWRAP_APPS_PROPERTY = "wrappedApp";
-
-    @Override
-    public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) {
-        Application app = create(template, platform);
-        CreationResult<Application, Void> start = EntityManagementUtils.start(app);
-        log.debug("CAMP created "+app+"; starting in "+start.task());
-        return platform.assemblies().get(app.getApplicationId());
-    }
-
-    public Application create(AssemblyTemplate template, CampPlatform platform) {
-        Application instance = EntityManagementUtils.createUnstarted(getBrooklynManagementContext(platform), template);
-        log.debug("CAMP created {}", instance);
-        return instance;
-    }
-
-    private ManagementContext getBrooklynManagementContext(CampPlatform platform) {
-        return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
-    }
-
-    @SuppressWarnings("unchecked")
-    public EntitySpec<? extends Application> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfPossible) {
-        log.debug("CAMP creating application instance for {} ({})", template.getId(), template);
-
-        // AssemblyTemplates created via PDP, _specifying_ then entities to put in
-
-        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
-            loader, buildWrapperAppTemplate(template));
-        EntitySpec<? extends Application> app = resolver.resolveSpec(null);
-
-        // first build the children into an empty shell app
-        List<EntitySpec<?>> childSpecs = buildTemplateServicesAsSpecs(loader, template, platform);
-        for (EntitySpec<?> childSpec : childSpecs) {
-            app.child(childSpec);
-        }
-
-        if (autoUnwrapIfPossible && shouldUnwrap(template, app)) {
-            EntitySpec<? extends Application> oldApp = app;
-            app = (EntitySpec<? extends Application>) Iterables.getOnlyElement( app.getChildren() );
-
-            // 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;
-    }
-
-    private AssemblyTemplate buildWrapperAppTemplate(AssemblyTemplate template) {
-        Builder<? extends AssemblyTemplate> builder = AssemblyTemplate.builder();
-        builder.type("brooklyn:" + BasicApplicationImpl.class.getName());
-        builder.id(template.getId());
-        builder.name(template.getName());
-        builder.sourceCode(template.getSourceCode());
-        for (Entry<String, Object> entry : template.getCustomAttributes().entrySet()) {
-            builder.customAttribute(entry.getKey(), entry.getValue());
-        }
-        builder.instantiator(template.getInstantiator());
-        AssemblyTemplate wrapTemplate = builder.build();
-        return wrapTemplate;
-    }
-
-    protected boolean shouldUnwrap(AssemblyTemplate template, EntitySpec<? extends Application> app) {
-        Object leaveWrapped = template.getCustomAttributes().get(NEVER_UNWRAP_APPS_PROPERTY);
-        if (leaveWrapped!=null) {
-            if (TypeCoercions.coerce(leaveWrapped, Boolean.class))
-                return false;
-        }
-
-        if (app.getChildren().size()!=1)
-            return false;
-
-        EntitySpec<?> childSpec = Iterables.getOnlyElement(app.getChildren());
-        if (childSpec.getType()==null || !Application.class.isAssignableFrom(childSpec.getType()))
-            return false;
-
-        return EntityManagementUtils.hasNoNameOrCustomKeysOrRoot(template, app);
-    }
-
-    private List<EntitySpec<?>> buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform) {
-        return buildTemplateServicesAsSpecsImpl(loader, template, platform, Sets.<String>newLinkedHashSet());
-    }
-
-    private List<EntitySpec<?>> buildTemplateServicesAsSpecsImpl(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform, Set<String> encounteredCatalogTypes) {
-        List<EntitySpec<?>> result = Lists.newArrayList();
-
-        for (ResolvableLink<PlatformComponentTemplate> ctl: template.getPlatformComponentTemplates().links()) {
-            PlatformComponentTemplate appChildComponentTemplate = ctl.resolve();
-            BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, appChildComponentTemplate);
-            EntitySpec<?> spec = resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
-
-            result.add(spec);
-        }
-        return result;
-    }
-
-    static EntitySpec<?> resolveSpec(ResourceUtils ru,
-            BrooklynComponentTemplateResolver entityResolver,
-            Set<String> encounteredCatalogTypes) {
-        String brooklynType = entityResolver.getServiceTypeResolver().getBrooklynType(entityResolver.getDeclaredType());
-        CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getServiceTypeResolver().getCatalogItem(entityResolver, entityResolver.getDeclaredType());
-
-        if (log.isTraceEnabled()) log.trace("Building CAMP template services: type="+brooklynType+"; item="+item+"; loader="+entityResolver.getLoader()+"; encounteredCatalogTypes="+encounteredCatalogTypes);
-
-        EntitySpec<?> spec = null;
-        String protocol = Urls.getProtocol(brooklynType);
-        if (protocol != null) {
-            if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
-                spec = tryResolveYamlUrlReferenceSpec(ru, brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
-                if (spec != null) {
-                    entityResolver.populateSpec(spec);
-                }
-            } else {
-                // TODO support https above
-                // TODO this will probably be logged if we refer to  chef:cookbook  or other service types which BCTR accepts;
-                // better would be to have BCTR supporting the calls above
-                log.debug("The reference " + brooklynType + " looks like a URL (running the CAMP Brooklyn assembly-template instantiator) but the protocol " +
-                        protocol + " isn't white listed (" + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + "). " +
-                        "Will try to load it as catalog item or java type.");
-            }
-        }
-
-        if (spec == null) {
-            // load from java or yaml
-            spec = entityResolver.resolveSpec(encounteredCatalogTypes);
-        }
-
-        return spec;
-    }
-
-    private static EntitySpec<?> tryResolveYamlUrlReferenceSpec(
-            ResourceUtils ru,
-            String brooklynType, BrooklynClassLoadingContext itemLoader,
-            Set<String> encounteredCatalogTypes) {
-        ManagementContext mgmt = itemLoader.getManagementContext();
-        Reader yaml;
-        try {
-            yaml = new InputStreamReader(ru.getResourceFromUrl(brooklynType), "UTF-8");
-        } catch (Exception e) {
-            log.warn("AssemblyTemplate type " + brooklynType + " which looks like a URL can't be fetched.", e);
-            return null;
-        }
-        try {
-            return createNestedSpec(mgmt, encounteredCatalogTypes, yaml, itemLoader);
-        } finally {
-            try {
-                yaml.close();
-            } catch (IOException e) {
-                throw Exceptions.propagate(e);
-            }
-        }
-    }
-
-    static EntitySpec<?> resolveCatalogYamlReferenceSpec(
-            ManagementContext mgmt,
-            CatalogItem<Entity, EntitySpec<?>> item,
-            Set<String> encounteredCatalogTypes) {
-
-        String yaml = item.getPlanYaml();
-        Reader input = new StringReader(yaml);
-        BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, item);
-
-        return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
-    }
-
-    private static EntitySpec<?> createNestedSpec(ManagementContext mgmt,
-            Set<String> encounteredCatalogTypes, Reader input,
-            BrooklynClassLoadingContext itemLoader) {
-        CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get();
-
-        AssemblyTemplate at;
-        BrooklynLoaderTracker.setLoader(itemLoader);
-        try {
-            at = platform.pdp().registerDeploymentPlan(input);
-        } finally {
-            BrooklynLoaderTracker.unsetLoader(itemLoader);
-        }
-        return createNestedSpecStatic(at, platform, itemLoader, encounteredCatalogTypes);
-    }
-
-    @Override
-    public EntitySpec<?> createNestedSpec(
-            AssemblyTemplate template,
-            CampPlatform platform,
-            BrooklynClassLoadingContext itemLoader,
-            Set<String> encounteredCatalogTypes) {
-        return createNestedSpecStatic(template, platform, itemLoader, encounteredCatalogTypes);
-    }
-    
-    private static EntitySpec<?> createNestedSpecStatic(
-        AssemblyTemplate template,
-        CampPlatform platform,
-        BrooklynClassLoadingContext itemLoader,
-        Set<String> encounteredCatalogTypes) {
-        // In case we want to allow multiple top-level entities in a catalog we need to think
-        // about what it would mean to subsequently call buildChildrenEntitySpecs on the list of top-level entities!
-        try {
-            AssemblyTemplateInstantiator ati = template.getInstantiator().newInstance();
-            if (ati instanceof BrooklynAssemblyTemplateInstantiator) {
-                List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecsImpl(itemLoader, template, platform, encounteredCatalogTypes);
-                if (specs.size() > 1) {
-                    throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+specs);
-                }
-                return specs.get(0);
-            } else {
-                throw new IllegalStateException("Cannot create application with instantiator: " + ati);
-            }
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
deleted file mode 100644
index ef5b506..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ /dev/null
@@ -1,491 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import io.brooklyn.camp.brooklyn.BrooklynCampConstants;
-import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-import io.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver;
-import io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver;
-import io.brooklyn.camp.spi.AbstractResource;
-import io.brooklyn.camp.spi.ApplicationComponentTemplate;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.annotation.Nullable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.BrooklynTags;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.proxying.InternalEntityFactory;
-import brooklyn.location.Location;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.ManagementContextInjectable;
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
-import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
-import brooklyn.management.internal.ManagementContextInternal;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.flags.FlagUtils.FlagConfigKeyAndValueRecord;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.javalang.Reflections;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-
-/**
- * This generates instances of a template resolver that use a {@link ServiceTypeResolver}
- * to parse the {@code serviceType} line in the template.
- */
-public class BrooklynComponentTemplateResolver {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynComponentTemplateResolver.class);
-
-    private final BrooklynClassLoadingContext loader;
-    private final ManagementContext mgmt;
-    private final ConfigBag attrs;
-    private final Maybe<AbstractResource> template;
-    private final BrooklynYamlTypeInstantiator.Factory yamlLoader;
-    private final String type;
-    private final ServiceTypeResolver typeResolver;
-    private final AtomicBoolean alreadyBuilt = new AtomicBoolean(false);
-
-    public BrooklynComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate, String type, ServiceTypeResolver typeResolver) {
-        this.loader = loader;
-        this.mgmt = loader.getManagementContext();
-        this.attrs = ConfigBag.newInstanceCopying(attrs);
-        this.template = Maybe.fromNullable(optionalTemplate);
-        this.yamlLoader = new BrooklynYamlTypeInstantiator.Factory(loader, this);
-        this.type = type;
-        this.typeResolver = typeResolver;
-    }
-
-    public BrooklynClassLoadingContext getLoader() { return loader; }
-    public ManagementContext getManagementContext() { return mgmt; }
-    public ConfigBag getAttrs() { return attrs; }
-    public Maybe<AbstractResource> getTemplate() { return template; }
-    public BrooklynYamlTypeInstantiator.Factory getYamlLoader() { return yamlLoader; }
-    public ServiceTypeResolver getServiceTypeResolver() { return typeResolver; }
-    public String getDeclaredType() { return type; }
-    public Boolean isAlreadyBuilt() { return alreadyBuilt.get(); }
-
-    public static class Factory {
-
-        /** returns resolver type based on the service type, inspecting the arguments in order to determine the service type */
-        private static ServiceTypeResolver computeResolverType(BrooklynClassLoadingContext context, String knownServiceType, AbstractResource optionalTemplate, ConfigBag attrs) {
-            String type = getDeclaredType(knownServiceType, optionalTemplate, attrs);
-            return findService(context, type);
-        }
-
-        // TODO This could be extended to support multiple prefixes per resolver and a 'best-match' algorithm
-        protected static ServiceTypeResolver findService(BrooklynClassLoadingContext context, String type) {
-            if (type.indexOf(':') != -1) {
-                String prefix = Splitter.on(":").splitToList(type).get(0);
-                ServiceLoader<ServiceTypeResolver> loader = ServiceLoader.load(ServiceTypeResolver.class,
-                        context.getManagementContext().getCatalogClassLoader());
-                for (ServiceTypeResolver resolver : loader) {
-                   if (prefix.equals(resolver.getTypePrefix())) {
-                       return resolver;
-                   }
-                }
-            }
-            return null;
-        }
-
-        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, Map<String, ?> childAttrs) {
-            return newInstance(context, ConfigBag.newInstance(childAttrs), null);
-        }
-
-        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, AbstractResource template) {
-            return newInstance(context, ConfigBag.newInstance(template.getCustomAttributes()), template);
-        }
-
-        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, String serviceType) {
-            return newInstance(context, ConfigBag.newInstance().configureStringKey("serviceType", serviceType), null);
-        }
-
-        private static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, ConfigBag attrs, AbstractResource optionalTemplate) {
-            ServiceTypeResolver typeResolver = computeResolverType(context, null, optionalTemplate, attrs);
-            String type = getDeclaredType(null, optionalTemplate, attrs);
-            if (typeResolver == null) // use default
-                typeResolver = new BrooklynServiceTypeResolver();
-            return new BrooklynComponentTemplateResolver(context, attrs, optionalTemplate, type, typeResolver);
-        }
-
-        public static String getDeclaredType(String knownServiceType, AbstractResource optionalTemplate, @Nullable ConfigBag attrs) {
-            String type = knownServiceType;
-            if (type==null && optionalTemplate!=null) {
-                type = optionalTemplate.getType();
-                if (type.equals(AssemblyTemplate.CAMP_TYPE) || type.equals(PlatformComponentTemplate.CAMP_TYPE) || type.equals(ApplicationComponentTemplate.CAMP_TYPE))
-                    // ignore these values for the type; only subclasses are interesting
-                    type = null;
-            }
-            if (type==null) type = extractServiceTypeAttribute(attrs);
-            return type;
-        }
-
-        private static String extractServiceTypeAttribute(@Nullable ConfigBag attrs) {
-            return BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("service", attrs).orNull();
-        }
-
-        public static boolean supportsType(BrooklynClassLoadingContext context, String serviceType) {
-            ServiceTypeResolver typeResolver = computeResolverType(context, serviceType, null, null);
-            if (typeResolver != null) return true;
-            return newInstance(context, serviceType).canResolve();
-        }
-    }
-
-    protected boolean canResolve() {
-        if (typeResolver.getCatalogItem(this, type)!=null)
-            return true;
-        if (loader.tryLoadClass(getJavaType(), Entity.class).isPresent())
-            return true;
-        return false;
-    }
-
-    /** returns the entity class, if needed in contexts which scan its statics for example */
-    protected Class<? extends Entity> loadEntityClass() {
-        Maybe<Class<? extends Entity>> result = tryLoadEntityClass();
-        if (result.isAbsent())
-            throw new IllegalStateException("Could not find "+typeResolver.getBrooklynType(type), ((Maybe.Absent<?>)result).getException());
-        return result.get();
-    }
-
-    /** tries to load the Java entity class */
-    protected Maybe<Class<? extends Entity>> tryLoadEntityClass() {
-        return loader.tryLoadClass(getJavaType(), Entity.class);
-    }
-
-    // TODO Generalise to have other prefixes (e.g. explicit "catalog:" etc)?
-    protected boolean isJavaTypePrefix() {
-        return type != null && (type.toLowerCase().startsWith("java:") || type.toLowerCase().startsWith("brooklyn:java:"));
-    }
-
-    protected String getJavaType() {
-        CatalogItem<Entity, EntitySpec<?>> item = typeResolver.getCatalogItem(this, type);
-        if (!isJavaTypePrefix() && item != null && item.getJavaType() != null) {
-            return item.getJavaType();
-        } else {
-            return typeResolver.getBrooklynType(type);
-        }
-    }
-
-    /** resolves the spec, updating the loader if a catalog item is loaded */
-    protected <T extends Entity> EntitySpec<T> resolveSpec(Set<String> encounteredCatalogTypes) {
-        if (alreadyBuilt.getAndSet(true))
-            throw new IllegalStateException("Spec can only be used once: "+this);
-
-        EntitySpec<T> spec = createSpec(encounteredCatalogTypes);
-        populateSpec(spec);
-
-        return spec;
-    }
-
-    @SuppressWarnings({ "unchecked" })
-    protected <T extends Entity> EntitySpec<T> createSpec(Set<String> encounteredCatalogTypes) {
-        CatalogItem<Entity, EntitySpec<?>> item = getServiceTypeResolver().getCatalogItem(this, getDeclaredType());
-        if (encounteredCatalogTypes==null) encounteredCatalogTypes = MutableSet.of();
-        
-        //Take the symoblicName part of the catalog item only for recursion detection to prevent
-        //cross referencing of different versions. Not interested in non-catalog item types.
-        //Prevent catalog items self-referencing even if explicitly different version.
-        boolean firstOccurrence = (item == null || encounteredCatalogTypes.add(item.getSymbolicName()));
-        boolean recursiveButTryJava = !firstOccurrence;
-
-        // Load a java class from current loader if explicit java prefix, or if no item, or if item is legacy / 
-        // old-style catalog item (item != null && item.getJavaType() != null).
-        // Old-style catalog items (can be defined in catalog.xml only) don't have structure, only a single type, so
-        // they are loaded as a simple java type, only taking the class name from the catalog item instead of the
-        // type value in the YAML. Classpath entries in the item are also used (through the catalog root classloader).
-        if (isJavaTypePrefix() || item == null || item.getJavaType() != null) {
-            return createSpecFromJavaType();
-
-        // Same as above case, but this time force java type loading (either as plain class or through an old-style
-        // catalog item, since we have already loaded a class item with the same name as the type value.
-        } else if (recursiveButTryJava) {
-            if (tryLoadEntityClass().isAbsent()) {
-                throw new IllegalStateException("Recursive reference to " + item + " (and cannot be resolved as a Java type)");
-            }
-            return createSpecFromJavaType();
-
-        // Only case that's left is a catalog item with YAML content - try to parse it recursively
-        // including it's OSGi bundles in the loader classpath.
-        } else {
-            // TODO perhaps migrate to catalog.createSpec ?
-            EntitySpec<?> spec = BrooklynAssemblyTemplateInstantiator.resolveCatalogYamlReferenceSpec(mgmt, item, encounteredCatalogTypes);
-            spec.catalogItemId(item.getId());
-            
-            return (EntitySpec<T>)spec;
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
-    protected <T extends Entity> EntitySpec<T> createSpecFromJavaType() {
-        Class<T> type = (Class<T>) loadEntityClass();
-        
-        EntitySpec<T> spec;
-        if (type.isInterface()) {
-            spec = EntitySpec.create(type);
-        } else {
-            // If this is a concrete class, particularly for an Application class, we want the proxy
-            // to expose all interfaces it implements.
-            @SuppressWarnings("rawtypes")
-            Class interfaceclazz = (Application.class.isAssignableFrom(type)) ? Application.class : Entity.class;
-            List<Class<?>> additionalInterfaceClazzes = Reflections.getAllInterfaces(type);
-            spec = EntitySpec.create(interfaceclazz).impl(type).additionalInterfaces(additionalInterfaceClazzes);
-        }
-        spec.catalogItemId(CatalogUtils.getCatalogItemIdFromLoader(loader));
-        if (template.isPresent() && template.get().getSourceCode()!=null)
-            spec.tag(BrooklynTags.newYamlSpecTag(template.get().getSourceCode()));
-
-        return spec;
-    }
-
-    //called from BrooklynAssemblyTemplateInstantiator as well
-    @SuppressWarnings("unchecked")
-    protected <T extends Entity> void populateSpec(EntitySpec<T> spec) {
-        String name, templateId=null, planId=null;
-        if (template.isPresent()) {
-            name = template.get().getName();
-            templateId = template.get().getId();
-        } else {
-            name = (String)attrs.getStringKey("name");
-        }
-        planId = (String)attrs.getStringKey("id");
-        if (planId==null)
-            planId = (String) attrs.getStringKey(BrooklynCampConstants.PLAN_ID_FLAG);
-
-        Object childrenObj = attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
-        if (childrenObj != null) {
-            // Creating a new set of encounteredCatalogTypes means that this won't check things recursively;
-            // but we are looking at children so we probably *should* be resetting the recursive list we've looked at;
-            // (but see also, a previous comment here which suggested otherwise? - Apr 2015)
-            Set<String> encounteredCatalogTypes = MutableSet.of();
-
-            Iterable<Map<String,?>> children = (Iterable<Map<String,?>>)childrenObj;
-            for (Map<String,?> childAttrs : children) {
-                BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, childAttrs);
-                EntitySpec<? extends Entity> childSpec = BrooklynAssemblyTemplateInstantiator.resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
-                spec.child(childSpec);
-            }
-        }
-        if (!Strings.isBlank(name))
-            spec.displayName(name);
-        if (templateId != null)
-            spec.configure(BrooklynCampConstants.TEMPLATE_ID, templateId);
-        if (planId != null)
-            spec.configure(BrooklynCampConstants.PLAN_ID, planId);
-
-        List<Location> childLocations = new BrooklynYamlLocationResolver(mgmt).resolveLocations(attrs.getAllConfig(), true);
-        if (childLocations != null)
-            spec.locations(childLocations);
-
-        typeResolver.decorateSpec(this, spec);
-        configureEntityConfig(spec);
-    }
-
-    /** returns new *uninitialised* entity, with just a few of the pieces from the spec;
-     * initialisation occurs soon after, in {@link #initEntity(ManagementContext, Entity, EntitySpec)},
-     * inside an execution context and after entity ID's are recognised
-     */
-    protected <T extends Entity> T newEntity(EntitySpec<T> spec) {
-        Class<? extends T> entityImpl = (spec.getImplementation() != null) ? spec.getImplementation() : mgmt.getEntityManager().getEntityTypeRegistry().getImplementedBy(spec.getType());
-        InternalEntityFactory entityFactory = ((ManagementContextInternal)mgmt).getEntityFactory();
-        T entity = entityFactory.constructEntity(entityImpl, spec);
-
-        String planId = (String)spec.getConfig().get(BrooklynCampConstants.PLAN_ID);
-        if (planId != null) {
-            entity.config().set(BrooklynCampConstants.PLAN_ID, planId);
-        }
-
-        if (spec.getLocations().size() > 0) {
-            ((AbstractEntity)entity).addLocations(spec.getLocations());
-        }
-
-        if (spec.getParent() != null) entity.setParent(spec.getParent());
-
-        return entity;
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    protected void configureEntityConfig(EntitySpec<?> spec) {
-        // first take *recognised* flags and config keys from the top-level, and put them in the bag (of brooklyn.config)
-        // attrs will contain only brooklyn.xxx properties when coming from BrooklynEntityMatcher.
-        // Any top-level flags will go into "brooklyn.flags". When resolving a spec from $brooklyn:entitySpec
-        // top level flags remain in place. Have to support both cases.
-
-        ConfigBag bag = ConfigBag.newInstance((Map<Object, Object>) attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CONFIG));
-        ConfigBag bagFlags = ConfigBag.newInstanceCopying(attrs);
-        if (attrs.containsKey(BrooklynCampReservedKeys.BROOKLYN_FLAGS)) {
-            bagFlags.putAll((Map<String, Object>) attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_FLAGS));
-        }
-
-        Collection<FlagConfigKeyAndValueRecord> topLevelApparentConfig = findAllFlagsAndConfigKeys(spec, bagFlags);
-        for (FlagConfigKeyAndValueRecord r: topLevelApparentConfig) {
-            if (r.getConfigKeyMaybeValue().isPresent())
-                bag.putIfAbsent((ConfigKey)r.getConfigKey(), r.getConfigKeyMaybeValue().get());
-            if (r.getFlagMaybeValue().isPresent())
-                bag.putAsStringKeyIfAbsent(r.getFlagName(), r.getFlagMaybeValue().get());
-        }
-
-        // now set configuration for all the items in the bag
-        Collection<FlagConfigKeyAndValueRecord> records = findAllFlagsAndConfigKeys(spec, bag);
-        Set<String> keyNamesUsed = new LinkedHashSet<String>();
-        for (FlagConfigKeyAndValueRecord r: records) {
-            if (r.getFlagMaybeValue().isPresent()) {
-                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(r.getFlagMaybeValue().get());
-                spec.configure(r.getFlagName(), transformed);
-                keyNamesUsed.add(r.getFlagName());
-            }
-            if (r.getConfigKeyMaybeValue().isPresent()) {
-                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(r.getConfigKeyMaybeValue().get());
-                spec.configure((ConfigKey<Object>)r.getConfigKey(), transformed);
-                keyNamesUsed.add(r.getConfigKey().getName());
-            }
-        }
-
-        // set unused keys as anonymous config keys -
-        // they aren't flags or known config keys, so must be passed as config keys in order for
-        // EntitySpec to know what to do with them (as they are passed to the spec as flags)
-        for (String key: MutableSet.copyOf(bag.getUnusedConfig().keySet())) {
-            // we don't let a flag with the same name as a config key override the config key
-            // (that's why we check whether it is used)
-            if (!keyNamesUsed.contains(key)) {
-                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(bag.getStringKey(key));
-                spec.configure(ConfigKeys.newConfigKey(Object.class, key.toString()), transformed);
-            }
-        }
-    }
-
-    /**
-     * Searches for config keys in the type, additional interfaces and the implementation (if specified)
-     */
-    private Collection<FlagConfigKeyAndValueRecord> findAllFlagsAndConfigKeys(EntitySpec<?> spec, ConfigBag bagFlags) {
-        Set<FlagConfigKeyAndValueRecord> allKeys = MutableSet.of();
-        allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, spec.getType(), bagFlags));
-        if (spec.getImplementation() != null) {
-            allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, spec.getImplementation(), bagFlags));
-        }
-        for (Class<?> iface : spec.getAdditionalInterfaces()) {
-            allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, iface, bagFlags));
-        }
-        return allKeys;
-    }
-
-    protected static class SpecialFlagsTransformer implements Function<Object, Object> {
-        protected final ManagementContext mgmt;
-        /* TODO find a way to make do without loader here?
-         * it is not very nice having to serialize it; but serialization of BLCL is now relatively clean.
-         *
-         * it is only used to instantiate classes, and now most things should be registered with catalog;
-         * the notable exception is when one entity in a bundle is creating another in the same bundle,
-         * it wants to use his bundle CLC to do that.  but we can set up some unique reference to the entity
-         * which can be used to find it from mgmt, rather than pass the loader.
-         */
-        private BrooklynClassLoadingContext loader = null;
-
-        public SpecialFlagsTransformer(BrooklynClassLoadingContext loader) {
-            this.loader = loader;
-            mgmt = loader.getManagementContext();
-        }
-        public Object apply(Object input) {
-            if (input instanceof Map)
-                return transformSpecialFlags((Map<?, ?>)input);
-            else if (input instanceof Set<?>)
-                return MutableSet.of(transformSpecialFlags((Iterable<?>)input));
-            else if (input instanceof List<?>)
-                return MutableList.copyOf(transformSpecialFlags((Iterable<?>)input));
-            else if (input instanceof Iterable<?>)
-                return transformSpecialFlags((Iterable<?>)input);
-            else
-                return transformSpecialFlags((Object)input);
-        }
-
-        protected Map<?, ?> transformSpecialFlags(Map<?, ?> flag) {
-            return Maps.transformValues(flag, this);
-        }
-
-        protected Iterable<?> transformSpecialFlags(Iterable<?> flag) {
-            return Iterables.transform(flag, this);
-        }
-
-        protected BrooklynClassLoadingContext getLoader() {
-            if (loader!=null) return loader;
-            // TODO currently loader will non-null unless someone has messed with the rebind files,
-            // but we'd like to get rid of it; ideally we'd have a reference to the entity.
-            // for now, this is a slightly naff way to do it, if we have to set loader=null as a workaround
-            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (entity!=null) return CatalogUtils.getClassLoadingContext(entity);
-            return JavaBrooklynClassLoadingContext.create(mgmt);
-        }
-
-        /**
-         * Makes additional transformations to the given flag with the extra knowledge of the flag's management context.
-         * @return The modified flag, or the flag unchanged.
-         */
-        protected Object transformSpecialFlags(Object flag) {
-            if (flag instanceof EntitySpecConfiguration) {
-                EntitySpecConfiguration specConfig = (EntitySpecConfiguration) flag;
-                // TODO: This should called from BrooklynAssemblyTemplateInstantiator.configureEntityConfig
-                // And have transformSpecialFlags(Object flag, ManagementContext mgmt) drill into the Object flag if it's a map or iterable?
-                @SuppressWarnings("unchecked")
-                Map<String, Object> resolvedConfig = (Map<String, Object>)transformSpecialFlags(specConfig.getSpecConfiguration());
-                specConfig.setSpecConfiguration(resolvedConfig);
-                return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(null);
-            }
-            if (flag instanceof ManagementContextInjectable) {
-                log.debug("Injecting Brooklyn management context info object: {}", flag);
-                ((ManagementContextInjectable) flag).injectManagementContext(loader.getManagementContext());
-            }
-
-            return flag;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    protected List<Map<String, Object>> getChildren(Map<String, Object> attrs) {
-        if (attrs==null) return null;
-        return (List<Map<String, Object>>) attrs.get(BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
deleted file mode 100644
index 7c1decc..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ /dev/null
@@ -1,181 +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 io.brooklyn.camp.brooklyn.spi.creation;
-
-import io.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.proxying.EntityInitializer;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.management.ManagementContext;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.Policy;
-import brooklyn.policy.PolicySpec;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Pattern for resolving "decorations" on service specs / entity specs, such as policies, enrichers, etc.
- * @since 0.7.0
- */
-@Beta
-public abstract class BrooklynEntityDecorationResolver<DT> {
-
-    public final BrooklynYamlTypeInstantiator.Factory instantiator;
-    
-    protected BrooklynEntityDecorationResolver(BrooklynYamlTypeInstantiator.Factory instantiator) {
-        this.instantiator = instantiator;
-    }
-    
-    public abstract void decorate(EntitySpec<?> entitySpec, ConfigBag attrs);
-
-    protected Iterable<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) {
-        Object value = getDecorationAttributeJsonValue(attrs); 
-        List<DT> decorations = MutableList.of();
-        if (value==null) return decorations;
-        if (value instanceof Iterable) {
-            for (Object decorationJson: (Iterable<?>)value)
-                addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
-        } else {
-            // in future may support types other than iterables here, 
-            // e.g. a map short form where the key is the type
-            throw new IllegalArgumentException(getDecorationKind()+" body should be iterable, not " + value.getClass());
-        }
-        return decorations;
-    }
-    
-    protected Map<?,?> checkIsMap(Object decorationJson) {
-        if (!(decorationJson instanceof Map))
-            throw new IllegalArgumentException(getDecorationKind()+" value must be a Map, not " + 
-                (decorationJson==null ? null : decorationJson.getClass()) );
-        return (Map<?,?>) decorationJson;
-    }
-
-    protected abstract String getDecorationKind();
-    protected abstract Object getDecorationAttributeJsonValue(ConfigBag attrs);
-    
-    /** creates and adds decorations from the given json to the given collection; 
-     * default impl requires a map and calls {@link #addDecorationFromJsonMap(Map, List)} */
-    protected void addDecorationFromJson(Object decorationJson, List<DT> decorations) {
-        addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
-    }
-    protected abstract void addDecorationFromJsonMap(Map<?,?> decorationJson, List<DT> decorations);
-    
-
-    public static class PolicySpecResolver extends BrooklynEntityDecorationResolver<PolicySpec<?>> {
-        
-        public PolicySpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
-        @Override protected String getDecorationKind() { return "Policy"; }
-
-        @Override
-        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
-            entitySpec.policySpecs(buildListOfTheseDecorationsFromEntityAttributes(attrs));
-        }
-        
-        @Override
-        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
-            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_POLICIES);
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<PolicySpec<?>> decorations) {
-            InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("policy");
-
-            String policyType = decoLoader.getTypeName().get();
-            ManagementContext mgmt = instantiator.loader.getManagementContext();
-            BrooklynCatalog catalog = mgmt.getCatalog();
-            CatalogItem<?, ?> item = getPolicyCatalogItem(catalog, policyType);
-            PolicySpec<? extends Policy> spec;
-            if (item != null) {
-                spec = (PolicySpec<? extends Policy>) catalog.createSpec(item);
-                spec.configure(decoLoader.getConfigMap());
-            } else {
-                // this pattern of creating a spec could be simplified with a "Configurable" superinterface on *Spec  
-                spec = PolicySpec.create(decoLoader.getType(Policy.class))
-                    .configure( decoLoader.getConfigMap() );
-            }
-            decorations.add(spec);
-        }
-        private CatalogItem<?, ?> getPolicyCatalogItem(BrooklynCatalog catalog, String policyType) {
-            if (CatalogUtils.looksLikeVersionedId(policyType)) {
-                String id = CatalogUtils.getIdFromVersionedId(policyType);
-                String version = CatalogUtils.getVersionFromVersionedId(policyType);
-                return catalog.getCatalogItem(id, version);
-            } else {
-                return catalog.getCatalogItem(policyType, BrooklynCatalog.DEFAULT_VERSION);
-            }
-        }
-    }
-
-    public static class EnricherSpecResolver extends BrooklynEntityDecorationResolver<EnricherSpec<?>> {
-        
-        public EnricherSpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
-        @Override protected String getDecorationKind() { return "Enricher"; }
-
-        @Override
-        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
-            entitySpec.enricherSpecs(buildListOfTheseDecorationsFromEntityAttributes(attrs));
-        }
-        
-        @Override
-        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
-            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_ENRICHERS);
-        }
-
-        @Override
-        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<EnricherSpec<?>> decorations) {
-            InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("enricher");
-            decorations.add(EnricherSpec.create(decoLoader.getType(Enricher.class))
-                .configure( decoLoader.getConfigMap() ));
-        }
-    }
-    
-    public static class InitializerResolver extends BrooklynEntityDecorationResolver<EntityInitializer> {
-        
-        public InitializerResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
-        @Override protected String getDecorationKind() { return "Entity initializer"; }
-
-        @Override
-        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
-            entitySpec.addInitializers(buildListOfTheseDecorationsFromEntityAttributes(attrs));
-        }
-        
-        @Override
-        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
-            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS);
-        }
-
-        @Override
-        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<EntityInitializer> decorations) {
-            decorations.add(instantiator.from(decorationJson).prefix("initializer").newInstance(EntityInitializer.class));
-        }
-    }
-    
-
-}


[03/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage-cli

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
new file mode 100644
index 0000000..044042a
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
@@ -0,0 +1,381 @@
+/*
+ * 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.cli;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+import io.airlift.command.ParseException;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+
+import brooklyn.location.Location;
+import brooklyn.location.LocationDefinition;
+import brooklyn.location.basic.LocationConfigKeys;
+import brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.location.jclouds.JcloudsLocation;
+import brooklyn.location.jclouds.JcloudsUtil;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.collect.Lists;
+
+/**
+ * Convenience for listing Cloud Compute and BlobStore details.
+ * <p>
+ * For fuller functionality, consider instead the jclouds CLI or Ruby Fog CLI.
+ * <p>
+ * The advantage of this utility is that it piggie-backs off the {@code brooklyn.property} credentials,
+ * so requires less additional credential configuration. It also gives brooklyn-specific information,
+ * such as which image will be used by default in a given cloud.
+ */
+public class CloudExplorer {
+
+    public static abstract class JcloudsCommand extends AbstractMain.BrooklynCommandCollectingArgs {
+        @Option(name = { "--all-locations" }, title = "all locations",
+                description = "All locations (i.e. all locations in brooklyn.properties for which there are credentials)")
+        public boolean allLocations;
+        
+        @Option(name = { "-l", "--location" }, title = "location spec",
+                description = "A location spec (e.g. referring to a named location in brooklyn.properties file)")
+        public String location;
+
+        @Option(name = { "-y", "--yes" }, title = "auto-confirm",
+                description = "Automatically answer yes to any questions")
+        public boolean autoconfirm = false;
+
+        protected abstract void doCall(JcloudsLocation loc, String indent) throws Exception;
+        
+        @Override
+        public Void call() throws Exception {
+            LocalManagementContext mgmt = new LocalManagementContext();
+            List<JcloudsLocation> locs = Lists.newArrayList();
+            try {
+                if (location != null && allLocations) {
+                    throw new FatalConfigurationRuntimeException("Must not specify --location and --all-locations");
+                } else if (location != null) {
+                    JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(location);
+                    locs.add(loc);
+                } else if (allLocations) {
+                    // Find all named locations that point at different target clouds
+                    Map<String, LocationDefinition> definedLocations = mgmt.getLocationRegistry().getDefinedLocations();
+                    for (LocationDefinition locationDef : definedLocations.values()) {
+                        Location loc = mgmt.getLocationRegistry().resolve(locationDef);
+                        if (loc instanceof JcloudsLocation) {
+                            boolean found = false;
+                            for (JcloudsLocation existing : locs) {
+                                if (equalTargets(existing, (JcloudsLocation) loc)) {
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (!found) {
+                                locs.add((JcloudsLocation) loc);
+                            }
+                        }
+                    }
+                } else {
+                    throw new FatalConfigurationRuntimeException("Must specify one of --location or --all-locations");
+                }
+                
+                for (JcloudsLocation loc : locs) {
+                    stdout.println("Location {");
+                    stdout.println("\tprovider: "+loc.getProvider());
+                    stdout.println("\tdisplayName: "+loc.getDisplayName());
+                    stdout.println("\tidentity: "+loc.getIdentity());
+                    if (loc.getEndpoint() != null) stdout.println("\tendpoint: "+loc.getEndpoint());
+                    if (loc.getRegion() != null) stdout.println("\tregion: "+loc.getRegion());
+
+                    try {
+                        doCall(loc, "\t");
+                    } finally {
+                        stdout.println("}");
+                    }
+                }
+            } finally {
+                mgmt.terminate();
+            }
+            return null;
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("location", location);
+        }
+        
+        protected boolean equalTargets(JcloudsLocation loc1, JcloudsLocation loc2) {
+            return Objects.equal(loc1.getProvider(), loc2.getProvider())
+                    && Objects.equal(loc1.getIdentity(), loc2.getIdentity())
+                    && Objects.equal(loc1.getEndpoint(), loc2.getEndpoint())
+                    && Objects.equal(loc1.getRegion(), loc2.getRegion());
+        }
+        
+        
+        protected boolean confirm(String msg, String indent) throws Exception {
+            if (autoconfirm) {
+                stdout.println(indent+"Auto-confirmed: "+msg);
+                return true;
+            } else {
+                stdout.println(indent+"Enter y/n. Are you sure you want to "+msg);
+                int in = stdin.read();
+                boolean confirmed = (Character.toLowerCase(in) == 'y');
+                if (confirmed) {
+                    stdout.println(indent+"Confirmed; will "+msg);
+                } else {
+                    stdout.println(indent+"Declined; will not "+msg);
+                }
+                return confirmed;
+            }
+        }
+    }
+    
+    public static abstract class ComputeCommand extends JcloudsCommand {
+        protected abstract void doCall(ComputeService computeService, String indent) throws Exception;
+            
+        @Override
+        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
+            ComputeService computeService = loc.getComputeService();
+            doCall(computeService, indent);
+        }
+    }
+
+    @Command(name = "list-instances", description = "")
+    public static class ComputeListInstancesCommand extends ComputeCommand {
+        @Override
+        protected void doCall(ComputeService computeService, String indent) throws Exception {
+            failIfArguments();
+            Set<? extends ComputeMetadata> instances = computeService.listNodes();
+            stdout.println(indent+"Instances {");
+            for (ComputeMetadata instance : instances) {
+                stdout.println(indent+"\t"+instance);
+            }
+            stdout.println(indent+"}");
+        }
+    }
+
+    @Command(name = "list-images", description = "")
+    public static class ComputeListImagesCommand extends ComputeCommand {
+        @Override
+        protected void doCall(ComputeService computeService, String indent) throws Exception {
+            failIfArguments();
+            Set<? extends Image> images = computeService.listImages();
+            stdout.println(indent+"Images {");
+            for (Image image : images) {
+                stdout.println(indent+"\t"+image);
+            }
+            stdout.println(indent+"}");
+        }
+    }
+    
+    @Command(name = "list-hardware-profiles", description = "")
+    public static class ComputeListHardwareProfilesCommand extends ComputeCommand {
+        @Override
+        protected void doCall(ComputeService computeService, String indent) throws Exception {
+            failIfArguments();
+            Set<? extends Hardware> hardware = computeService.listHardwareProfiles();
+            stdout.println(indent+"Hardware Profiles {");
+            for (Hardware image : hardware) {
+                stdout.println(indent+"\t"+image);
+            }
+            stdout.println(indent+"}");
+        }
+    }
+    
+    @Command(name = "get-image", description = "")
+    public static class ComputeGetImageCommand extends ComputeCommand {
+        @Override
+        protected void doCall(ComputeService computeService, String indent) throws Exception {
+            if (arguments.isEmpty()) {
+                throw new ParseException("Requires at least one image-id arguments");
+            }
+            
+            for (String imageId : arguments) {
+                Image image = computeService.getImage(imageId);
+                stdout.println(indent+"Image "+imageId+" {");
+                stdout.println(indent+"\t"+image);
+                stdout.println(indent+"}");
+            }
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("imageIds", arguments);
+        }
+    }
+
+    @Command(name = "default-template", description = "")
+    public static class ComputeDefaultTemplateCommand extends JcloudsCommand {
+        @Override
+        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
+            failIfArguments();
+            ComputeService computeService = loc.getComputeService();
+            
+            Template template = loc.buildTemplate(computeService, loc.config().getBag());
+            Image image = template.getImage();
+            Hardware hardware = template.getHardware();
+            org.jclouds.domain.Location location = template.getLocation();
+            TemplateOptions options = template.getOptions();
+            stdout.println(indent+"Default template {");
+            stdout.println(indent+"\tImage: "+image);
+            stdout.println(indent+"\tHardware: "+hardware);
+            stdout.println(indent+"\tLocation: "+location);
+            stdout.println(indent+"\tOptions: "+options);
+            stdout.println(indent+"}");
+        }
+    }
+    
+    @Command(name = "terminate-instances", description = "")
+    public static class ComputeTerminateInstancesCommand extends ComputeCommand {
+        @Override
+        protected void doCall(ComputeService computeService, String indent) throws Exception {
+            if (arguments.isEmpty()) {
+                throw new ParseException("Requires at least one instance-id arguments");
+            }
+            
+            for (String instanceId : arguments) {
+                NodeMetadata instance = computeService.getNodeMetadata(instanceId);
+                if (instance == null) {
+                    stderr.println(indent+"Cannot terminate instance; could not find "+instanceId);
+                } else {
+                    boolean confirmed = confirm(indent, "terminate "+instanceId+" ("+instance+")");
+                    if (confirmed) {
+                        computeService.destroyNode(instanceId);
+                    }
+                }
+            }
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("instanceIds", arguments);
+        }
+    }
+
+    public static abstract class BlobstoreCommand extends JcloudsCommand {
+        protected abstract void doCall(BlobStore blobstore, String indent) throws Exception;
+
+        @Override
+        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
+            String identity = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_IDENTITY), "identity must not be null");
+            String credential = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_CREDENTIAL), "credential must not be null");
+            String provider = checkNotNull(loc.getConfig(LocationConfigKeys.CLOUD_PROVIDER), "provider must not be null");
+            String endpoint = loc.getConfig(CloudLocationConfig.CLOUD_ENDPOINT);
+            
+            BlobStoreContext context = JcloudsUtil.newBlobstoreContext(provider, endpoint, identity, credential);
+            try {
+                BlobStore blobStore = context.getBlobStore();
+                doCall(blobStore, indent);
+            } finally {
+                context.close();
+            }
+        }
+    }
+    
+    @Command(name = "list-containers", description = "")
+    public static class BlobstoreListContainersCommand extends BlobstoreCommand {
+        @Override
+        protected void doCall(BlobStore blobstore, String indent) throws Exception {
+            failIfArguments();
+            Set<? extends StorageMetadata> containers = blobstore.list();
+            stdout.println(indent+"Containers {");
+            for (StorageMetadata container : containers) {
+                stdout.println(indent+"\t"+container);
+            }
+            stdout.println(indent+"}");
+        }
+    }
+
+    @Command(name = "list-container", description = "")
+    public static class BlobstoreListContainerCommand extends BlobstoreCommand {
+        @Override
+        protected void doCall(BlobStore blobStore, String indent) throws Exception {
+            if (arguments.isEmpty()) {
+                throw new ParseException("Requires at least one container-name arguments");
+            }
+            
+            for (String containerName : arguments) {
+                Set<? extends StorageMetadata> contents = blobStore.list(containerName);
+                stdout.println(indent+"Container "+containerName+" {");
+                for (StorageMetadata content : contents) {
+                    stdout.println(indent+"\t"+content);
+                }
+                stdout.println(indent+"}");
+            }
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("containers", arguments);
+        }
+    }
+    
+    @Command(name = "blob", description = "")
+    public static class BlobstoreGetBlobCommand extends BlobstoreCommand {
+        @Option(name = { "--container" }, title = "list contents of a given container",
+                description = "")
+        public String container;
+
+        @Option(name = { "--blob" }, title = "retrieves the blog in the given container",
+                description = "")
+        public String blob;
+
+        @Override
+        protected void doCall(BlobStore blobStore, String indent) throws Exception {
+            failIfArguments();
+            Blob content = blobStore.getBlob(container, blob);
+            stdout.println(indent+"Blob "+container+" : " +blob +" {");
+            stdout.println(indent+"\tHeaders {");
+            for (Map.Entry<String, String> entry : content.getAllHeaders().entries()) {
+                stdout.println(indent+"\t\t"+entry.getKey() + " = " + entry.getValue());
+            }
+            stdout.println(indent+"\t}");
+            stdout.println(indent+"\tmetadata : "+content.getMetadata());
+            stdout.println(indent+"\tpayload : "+Streams.readFullyString(content.getPayload().openStream()));
+            stdout.println(indent+"}");
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("container", container)
+                    .add("blob", blob);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
new file mode 100644
index 0000000..dc25447
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
@@ -0,0 +1,273 @@
+/*
+ * 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.cli;
+
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.basic.BrooklynObject;
+import org.apache.brooklyn.catalog.Catalog;
+import org.apache.brooklyn.cli.lister.ClassFinder;
+import org.apache.brooklyn.cli.lister.ItemDescriptors;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.location.Location;
+import brooklyn.location.LocationResolver;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.Policy;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.net.Urls;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.Strings;
+import brooklyn.util.text.TemplateProcessor;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.google.common.base.Charsets;
+import com.google.common.base.Splitter;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+
+public class ItemLister {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ItemLister.class);
+    private static final String BASE = "brooklyn/item-lister";
+    private static final String BASE_TEMPLATES = BASE+"/"+"templates";
+    private static final String BASE_STATICS = BASE+"/"+"statics";
+
+    @Command(name = "list-objects", description = "List Brooklyn objects (Entities, Policies, Enrichers and Locations)")
+    public static class ListAllCommand extends AbstractMain.BrooklynCommandCollectingArgs {
+
+        @Option(name = { "--jars" }, title = "Jars", description = "Jars to scan. If a file (not a url) pointing at a directory, will include all files in that directory")
+        public List<String> jars = Lists.newLinkedList();
+
+        @Option(name = { "--type-regex" }, title = "Regex for types to list")
+        public String typeRegex;
+
+        @Option(name = { "--catalog-only" }, title = "Whether to only list items annotated with @Catalog")
+        public boolean catalogOnly = true;
+
+        @Option(name = { "--ignore-impls" }, title = "Ignore Entity implementations, where there is an Entity interface with @ImplementedBy")
+        public boolean ignoreImpls = false;
+
+        @Option(name = { "--headings-only" }, title = "Whether to only show name/type, and not config keys etc")
+        public boolean headingsOnly = false;
+        
+        @Option(name = { "--output-folder" }, title = "Folder to save output")
+        public String outputFolder;
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Void call() throws Exception {
+            List<URL> urls = getUrls();
+            LOG.info("Retrieving objects from "+urls);
+
+            // TODO Remove duplication from separate ListPolicyCommand etc
+            List<Class<? extends Entity>> entityTypes = getTypes(urls, Entity.class);
+            List<Class<? extends Policy>> policyTypes = getTypes(urls, Policy.class);
+            List<Class<? extends Enricher>> enricherTypes = getTypes(urls, Enricher.class);
+            List<Class<? extends Location>> locationTypes = getTypes(urls, Location.class, Boolean.FALSE);
+
+            Map<String, Object> result = ImmutableMap.<String, Object>builder()
+                    .put("entities", ItemDescriptors.toItemDescriptors(entityTypes, headingsOnly, "name"))
+                    .put("policies", ItemDescriptors.toItemDescriptors(policyTypes, headingsOnly, "name"))
+                    .put("enrichers", ItemDescriptors.toItemDescriptors(enricherTypes, headingsOnly, "name"))
+                    .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly, "type"))
+                    .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)), true))
+                    .build();
+
+            String json = toJson(result);
+
+            if (outputFolder == null) {
+                System.out.println(json);
+            } else {
+                LOG.info("Outputting item list (size "+itemCount+") to " + outputFolder);
+                String outputPath = Os.mergePaths(outputFolder, "index.html");
+                String parentDir = (new File(outputPath).getParentFile()).getAbsolutePath();
+                mkdir(parentDir, "entities");
+                mkdir(parentDir, "policies");
+                mkdir(parentDir, "enrichers");
+                mkdir(parentDir, "locations");
+                mkdir(parentDir, "locationResolvers"); //TODO nothing written here yet...
+                
+                mkdir(parentDir, "style");
+                mkdir(Os.mergePaths(parentDir, "style"), "js");
+                mkdir(Os.mergePaths(parentDir, "style", "js"), "catalog");
+                
+                Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8);
+                ResourceUtils resourceUtils = ResourceUtils.create(this);
+                
+                // root - just loads the above JSON
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "brooklyn-object-list.html", "index.html");
+                
+                // statics - structure mirrors docs (not for any real reason however... the json is usually enough for our docs)
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "common.js");
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "items.css");
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.js");
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.map");
+                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/catalog/bloodhound.js");
+
+                // now make pages for each item
+                
+                List<Map<String, Object>> entities = (List<Map<String, Object>>) result.get("entities");
+                String entityTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "entity.html"));
+                for (Map<String, Object> entity : entities) {
+                    String type = (String) entity.get("type");
+                    String name = (String) entity.get("name");
+                    String entityHtml = TemplateProcessor.processTemplateContents(entityTemplateHtml, ImmutableMap.of("type", type, "name", name));
+                    Files.write(entityHtml, new File(Os.mergePaths(outputFolder, "entities", type + ".html")), Charsets.UTF_8);
+                }
+                
+                List<Map<String, Object>> policies = (List<Map<String, Object>>) result.get("policies");
+                String policyTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "policy.html"));
+                for (Map<String, Object> policy : policies) {
+                    String type = (String) policy.get("type");
+                    String name = (String) policy.get("name");
+                    String policyHtml = TemplateProcessor.processTemplateContents(policyTemplateHtml, ImmutableMap.of("type", type, "name", name));
+                    Files.write(policyHtml, new File(Os.mergePaths(outputFolder, "policies", type + ".html")), Charsets.UTF_8);
+                }
+                
+                List<Map<String, Object>> enrichers = (List<Map<String, Object>>) result.get("enrichers");
+                String enricherTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "enricher.html"));
+                for (Map<String, Object> enricher : enrichers) {
+                    String type = (String) enricher.get("type");
+                    String name = (String) enricher.get("name");
+                    String enricherHtml = TemplateProcessor.processTemplateContents(enricherTemplateHtml, ImmutableMap.of("type", type, "name", name));
+                    Files.write(enricherHtml, new File(Os.mergePaths(outputFolder, "enrichers", type + ".html")), Charsets.UTF_8);
+                }
+                
+                List<Map<String, Object>> locations = (List<Map<String, Object>>) result.get("locations");
+                String locationTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "location.html"));
+                for (Map<String, Object> location : locations) {
+                    String type = (String) location.get("type");
+                    String locationHtml = TemplateProcessor.processTemplateContents(locationTemplateHtml, ImmutableMap.of("type", type));
+                    Files.write(locationHtml, new File(Os.mergePaths(outputFolder, "locations", type + ".html")), Charsets.UTF_8);
+                }
+                LOG.info("Finished outputting item list to " + outputFolder);
+            }
+            return null;
+        }
+
+        private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item) throws IOException {
+            copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, item, item);
+        }
+        private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item, String dest) throws IOException {
+            String js = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_STATICS, item));
+            Files.write(js, new File(Os.mergePaths(outputFolder, dest)), Charsets.UTF_8);
+        }
+
+        private void mkdir(String rootDir, String dirName) {
+            (new File(Os.mergePaths(rootDir, dirName))).mkdirs();
+        }
+
+        protected List<URL> getUrls() throws MalformedURLException {
+            List<URL> urls = Lists.newArrayList();
+            if (jars.isEmpty()) {
+                String classpath = System.getenv("INITIAL_CLASSPATH");
+                if (Strings.isNonBlank(classpath)) {
+                    List<String> entries = Splitter.on(":").omitEmptyStrings().trimResults().splitToList(classpath);
+                    for (String entry : entries) {
+                        if (entry.endsWith(".jar") || entry.endsWith("/*")) {
+                            urls.addAll(ClassFinder.toJarUrls(entry.replace("/*", "")));
+                        }
+                    }
+                } else {
+                    throw new IllegalArgumentException("No Jars to process");
+                }
+            } else {
+                for (String jar : jars) {
+                    List<URL> expanded = ClassFinder.toJarUrls(jar);
+                    if (expanded.isEmpty())
+                        LOG.warn("No jars found at: "+jar);
+                    urls.addAll(expanded);
+                }
+            }
+            return urls;
+        }
+
+        private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type) {
+            return getTypes(urls, type, null);
+        }
+
+        int itemCount = 0;
+        
+        private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type, Boolean catalogOnlyOverride) {
+            FluentIterable<Class<? extends T>> fluent = FluentIterable.from(ClassFinder.findClasses(urls, type));
+            if (typeRegex != null) {
+                fluent = fluent.filter(ClassFinder.withClassNameMatching(typeRegex));
+            }
+            if (catalogOnlyOverride == null ? catalogOnly : catalogOnlyOverride) {
+                fluent = fluent.filter(ClassFinder.withAnnotation(Catalog.class));
+            }
+            List<Class<? extends T>> filtered = fluent.toList();
+            Collection<Class<? extends T>> result;
+            if (ignoreImpls) {
+                result = MutableSet.copyOf(filtered);
+                for (Class<? extends T> clazz : filtered) {
+                    ImplementedBy implementedBy = clazz.getAnnotation(ImplementedBy.class);
+                    if (implementedBy != null) {
+                        result.remove(implementedBy.value());
+                    }
+                }
+            } else {
+                result = filtered;
+            }
+            itemCount += result.size();
+            return ImmutableList.copyOf(result);
+        }
+        
+        private String toJson(Object obj) throws JsonProcessingException {
+            ObjectMapper objectMapper = new ObjectMapper()
+                    .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .enable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)
+                    .enable(SerializationFeature.INDENT_OUTPUT)
+                    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
+                    .setSerializationInclusion(JsonInclude.Include.ALWAYS)
+            
+                    // Only serialise annotated fields
+                    .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
+                    .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+            
+            return objectMapper.writeValueAsString(obj);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
new file mode 100644
index 0000000..cd827e0
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
@@ -0,0 +1,987 @@
+/*
+ * 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.cli;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+import brooklyn.BrooklynVersion;
+import brooklyn.basic.BrooklynTypes;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.catalog.CatalogItem;
+import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
+import org.apache.brooklyn.cli.CloudExplorer.BlobstoreGetBlobCommand;
+import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainerCommand;
+import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainersCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeDefaultTemplateCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeGetImageCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeListHardwareProfilesCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeListImagesCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
+import org.apache.brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
+import org.apache.brooklyn.cli.ItemLister.ListAllCommand;
+
+import brooklyn.catalog.internal.CatalogInitialization;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
+import brooklyn.entity.rebind.persister.PersistMode;
+import brooklyn.entity.rebind.transformer.CompoundTransformer;
+import brooklyn.entity.trait.Startable;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.launcher.BrooklynServerDetails;
+import brooklyn.launcher.config.StopWhichAppsOnShutdown;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.OsgiManager;
+import brooklyn.rest.security.PasswordHasher;
+import brooklyn.rest.util.ShutdownHandler;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
+import brooklyn.util.exceptions.FatalRuntimeException;
+import brooklyn.util.exceptions.UserFacingException;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.javalang.Enums;
+import brooklyn.util.net.Networking;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import brooklyn.util.text.Strings;
+import brooklyn.util.time.Duration;
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyShell;
+import io.airlift.command.Cli;
+import io.airlift.command.Cli.CliBuilder;
+import io.airlift.command.Command;
+import io.airlift.command.Option;
+
+/**
+ * This class is the primary CLI for brooklyn.
+ * Run with the `help` argument for help.
+ * <p>
+ * This class is designed for subclassing, with subclasses typically:
+ * <li> providing their own static {@link #main(String...)} (of course) which need simply invoke 
+ *      {@link #execCli(String[])} with the arguments 
+ * <li> returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()}
+ * <li> providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired
+ * <li> providing any other CLI customisations by overriding {@link #cliBuilder()}
+ *      (typically calling the parent and then customizing the builder)
+ * <li> populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)}
+ */
+public class Main extends AbstractMain {
+
+    private static final Logger log = LoggerFactory.getLogger(Main.class);
+
+    public static void main(String... args) {
+        log.debug("Launching Brooklyn via CLI, with "+Arrays.toString(args));
+        BrooklynVersion.INSTANCE.logSummary();
+        new Main().execCli(args);
+    }
+
+    @Command(name = "generate-password", description = "Generates a hashed web-console password")
+    public static class GeneratePasswordCommand extends BrooklynCommandCollectingArgs {
+
+        @Option(name = { "--user" }, title = "username", required = true)
+        public String user;
+
+        @Option(name = { "--stdin" }, title = "read password from stdin, instead of console", 
+                description = "Before using stdin, read http://stackoverflow.com/a/715681/1393883 for discussion of security!")
+        public boolean useStdin;
+
+        @Override
+        public Void call() throws Exception {
+            checkCanReadPassword();
+            
+            System.out.print("Enter password: ");
+            System.out.flush();
+            String password = readPassword();
+            if (Strings.isBlank(password)) {
+                throw new UserFacingException("Password must not be blank; aborting");
+            }
+            
+            System.out.print("Re-enter password: ");
+            System.out.flush();
+            String password2 = readPassword();
+            if (!password.equals(password2)) {
+                throw new UserFacingException("Passwords did not match; aborting");
+            }
+
+            String salt = Identifiers.makeRandomId(4);
+            String sha256password = PasswordHasher.sha256(salt, new String(password));
+            
+            System.out.println();
+            System.out.println("Please add the following to your brooklyn.properties:");
+            System.out.println();
+            System.out.println("brooklyn.webconsole.security.users="+user);
+            System.out.println("brooklyn.webconsole.security.user."+user+".salt="+salt);
+            System.out.println("brooklyn.webconsole.security.user."+user+".sha256="+sha256password);
+
+            return null;
+        }
+        
+        private void checkCanReadPassword() {
+            if (useStdin) {
+                // yes; always
+            } else {
+                Console console = System.console();
+                if (console == null) {
+                    throw new FatalConfigurationRuntimeException("No console; cannot get password securely; aborting");
+                }
+            }
+        }
+        
+        private String readPassword() throws IOException {
+            if (useStdin) {
+                return readLine(System.in);
+            } else {
+                return new String(System.console().readPassword());
+            }
+        }
+        
+        private String readLine(InputStream in) throws IOException {
+            StringBuilder result = new StringBuilder();
+            char c;
+            while ((c = (char)in.read()) != '\n') {
+                result.append(c);
+            }
+            return result.toString();
+        }
+    }
+    
+    @Command(name = "launch", description = "Starts a server, optionally with applications")
+    public static class LaunchCommand extends BrooklynCommandCollectingArgs {
+
+        @Option(name = { "--localBrooklynProperties" }, title = "local brooklyn.properties file",
+                description = "Load the given properties file, specific to this launch (appending to and overriding global properties)")
+        public String localBrooklynProperties;
+
+        @Option(name = { "--noGlobalBrooklynProperties" }, title = "do not use any global brooklyn.properties file found",
+            description = "Do not use the default global brooklyn.properties file found")
+        public boolean noGlobalBrooklynProperties = false;
+
+        @Option(name = { "-a", "--app" }, title = "application class or file",
+                description = "The Application to start. " +
+                        "For example, my.AppName, file://my/app.yaml, or classpath://my/AppName.groovy -- "
+                        + "note that a BROOKLYN_CLASSPATH environment variable may be required to "
+                        + "load classes from other locations")
+        public String app;
+
+        @Beta
+        @Option(name = { "-s", "--script" }, title = "script URI",
+                description = "EXPERIMENTAL. URI for a Groovy script to parse and load." +
+                        " This script will run before starting the app.")
+        public String script = null;
+
+        @Option(name = { "-l", "--location", "--locations" }, title = "location list",
+                description = "Specifies the locations where the application will be launched. " +
+                        "You can specify more than one location as a comma-separated list of values " +
+                        "(or as a JSON array, if the values are complex)")
+        public String locations;
+
+        @Option(name = { "--catalogInitial" }, title = "catalog initial bom URI",
+            description = "Specifies a catalog.bom URI to be used to populate the initial catalog, "
+                + "loaded on first run, or when persistence is off/empty or the catalog is reset")
+        public String catalogInitial;
+
+        @Option(name = { "--catalogReset" }, 
+            description = "Specifies that any catalog items which have been persisted should be cleared")
+        public boolean catalogReset;
+
+        @Option(name = { "--catalogAdd" }, title = "catalog bom URI to add",
+            description = "Specifies a catalog.bom to be added to the catalog")
+        public String catalogAdd;
+
+        @Option(name = { "--catalogForce" }, 
+            description = "Specifies that catalog items added via the CLI should be forcibly added, "
+                + "replacing any identical versions already registered (use with care!)")
+        public boolean catalogForce;
+
+        @Option(name = { "-p", "--port" }, title = "port number",
+                description = "Use this port for the brooklyn management web console and REST API; "
+                    + "default is 8081+ for http, 8443+ for https.")
+        public String port;
+
+        @Option(name = { "--https" },
+            description = "Launch the web console on https")
+        public boolean useHttps = false;
+        
+        @Option(name = { "-nc", "--noConsole" },
+                description = "Do not start the web console or REST API")
+        public boolean noConsole = false;
+
+        @Option(name = { "-b", "--bindAddress" },
+                description = "Specifies the IP address of the NIC to bind the Brooklyn Management Console to")
+        public String bindAddress = null;
+
+        @Option(name = { "-pa", "--publicAddress" },
+                description = "Specifies the IP address or hostname that the Brooklyn Management Console will be available on")
+        public String publicAddress = null;
+
+        @Option(name = { "--noConsoleSecurity" },
+                description = "Whether to disable authentication and security filters for the web console (for use when debugging on a secure network or bound to localhost)")
+        public Boolean noConsoleSecurity = false;
+
+        @Option(name = { "--startupContinueOnWebErrors" },
+            description = "Continue on web subsystem failures during startup "
+                + "(default is to abort if the web API fails to start, as management access is not normally possible)")
+        public boolean startupContinueOnWebErrors = false;
+
+        @Option(name = { "--startupFailOnPersistenceErrors" },
+            description = "Fail on persistence/HA subsystem failures during startup "
+                + "(default is to continue, so errors can be viewed via the API)")
+        public boolean startupFailOnPersistenceErrors = false;
+
+        @Option(name = { "--startupFailOnCatalogErrors" },
+            description = "Fail on catalog subsystem failures during startup "
+                + "(default is to continue, so errors can be viewed via the API)")
+        public boolean startupFailOnCatalogErrors = false;
+
+        @Option(name = { "--startupFailOnManagedAppsErrors" },
+            description = "Fail startup on errors deploying of managed apps specified via the command line "
+                + "(default is to continue, so errors can be viewed via the API)")
+        public boolean startupFailOnManagedAppsErrors = false;
+
+        @Beta
+        @Option(name = { "--startBrooklynNode" },
+                description = "Start a BrooklynNode entity representing this Brooklyn instance")
+        public boolean startBrooklynNode = false;
+
+        // Note in some cases, you can get java.util.concurrent.RejectedExecutionException
+        // if shutdown is not co-ordinated, looks like: {@linktourl https://gist.github.com/47066f72d6f6f79b953e}
+        @Beta
+        @Option(name = { "-sk", "--stopOnKeyPress" },
+                description = "Shutdown immediately on user text entry after startup (useful for debugging and demos)")
+        public boolean stopOnKeyPress = false;
+
+        final static String STOP_WHICH_APPS_ON_SHUTDOWN = "--stopOnShutdown";
+        protected final static String STOP_ALL = "all";
+        protected final static String STOP_ALL_IF_NOT_PERSISTED = "allIfNotPersisted";
+        protected final static String STOP_NONE = "none";
+        protected final static String STOP_THESE = "these";        
+        protected final static String STOP_THESE_IF_NOT_PERSISTED = "theseIfNotPersisted";
+        static { Enums.checkAllEnumeratedIgnoreCase(StopWhichAppsOnShutdown.class, STOP_ALL, STOP_ALL_IF_NOT_PERSISTED, STOP_NONE, STOP_THESE, STOP_THESE_IF_NOT_PERSISTED); }
+        
+        @Option(name = { STOP_WHICH_APPS_ON_SHUTDOWN },
+            allowedValues = { STOP_ALL, STOP_ALL_IF_NOT_PERSISTED, STOP_NONE, STOP_THESE, STOP_THESE_IF_NOT_PERSISTED },
+            description = "Which managed applications to stop on shutdown. Possible values are:\n"+
+                "all: stop all apps\n"+
+                "none: leave all apps running\n"+
+                "these: stop the apps explicitly started on this command line, but leave others started subsequently running\n"+
+                "theseIfNotPersisted: stop the apps started on this command line IF persistence is not enabled, otherwise leave all running\n"+
+                "allIfNotPersisted: stop all apps IF persistence is not enabled, otherwise leave all running")
+        public String stopWhichAppsOnShutdown = STOP_THESE_IF_NOT_PERSISTED;
+
+        @Option(name = { "--exitAndLeaveAppsRunningAfterStarting" },
+                description = "Once the application to start (from --app) is running exit the process, leaving any entities running. "
+                    + "Can be used in combination with --persist auto --persistenceDir <custom folder location> to attach to the running app at a later time.")
+        public boolean exitAndLeaveAppsRunningAfterStarting = false;
+
+        final static String PERSIST_OPTION = "--persist";
+        protected final static String PERSIST_OPTION_DISABLED = "disabled";
+        protected final static String PERSIST_OPTION_AUTO = "auto";
+        protected final static String PERSIST_OPTION_REBIND = "rebind";
+        protected final static String PERSIST_OPTION_CLEAN = "clean";
+        static { Enums.checkAllEnumeratedIgnoreCase(PersistMode.class, PERSIST_OPTION_DISABLED, PERSIST_OPTION_AUTO, PERSIST_OPTION_REBIND, PERSIST_OPTION_CLEAN); }
+        
+        // TODO currently defaults to disabled; want it to default to on, when we're ready
+        // TODO how to force a line-split per option?!
+        //      Looks like java.io.airlift.airline.UsagePrinter is splitting the description by word, and
+        //      wrapping it automatically.
+        //      See https://github.com/airlift/airline/issues/30
+        @Option(name = { PERSIST_OPTION }, 
+                allowedValues = { PERSIST_OPTION_DISABLED, PERSIST_OPTION_AUTO, PERSIST_OPTION_REBIND, PERSIST_OPTION_CLEAN },
+                title = "persistence mode",
+                description =
+                        "The persistence mode. Possible values are: \n"+
+                        "disabled: will not read or persist any state; \n"+
+                        "auto: will rebind to any existing state, or start up fresh if no state; \n"+
+                        "rebind: will rebind to the existing state, or fail if no state available; \n"+
+                        "clean: will start up fresh (removing any existing state)")
+        public String persist = PERSIST_OPTION_DISABLED;
+
+        @Option(name = { "--persistenceDir" }, title = "persistence dir",
+                description = "The directory to read/write persisted state (or container name if using an object store)")
+        public String persistenceDir;
+
+        @Option(name = { "--persistenceLocation" }, title = "persistence location",
+            description = "The location spec for an object store to read/write persisted state")
+        public String persistenceLocation;
+
+        final static String HA_OPTION = "--highAvailability";
+        protected final static String HA_OPTION_DISABLED = "disabled";
+        protected final static String HA_OPTION_AUTO = "auto";
+        protected final static String HA_OPTION_MASTER = "master";
+        protected final static String HA_OPTION_STANDBY = "standby";
+        protected final static String HA_OPTION_HOT_STANDBY = "hot_standby";
+        protected final static String HA_OPTION_HOT_BACKUP = "hot_backup";
+        static { Enums.checkAllEnumeratedIgnoreCase(HighAvailabilityMode.class, HA_OPTION_AUTO, HA_OPTION_DISABLED, HA_OPTION_MASTER, HA_OPTION_STANDBY, HA_OPTION_HOT_STANDBY, HA_OPTION_HOT_BACKUP); }
+        
+        @Option(name = { HA_OPTION }, allowedValues = { HA_OPTION_DISABLED, HA_OPTION_AUTO, HA_OPTION_MASTER, HA_OPTION_STANDBY, HA_OPTION_HOT_STANDBY, HA_OPTION_HOT_BACKUP },
+                title = "high availability mode",
+                description =
+                        "The high availability mode. Possible values are: \n"+
+                        "disabled: management node works in isolation - will not cooperate with any other standby/master nodes in management plane; \n"+
+                        "auto: will look for other management nodes, and will allocate itself as standby or master based on other nodes' states; \n"+
+                        "master: will startup as master - if there is already a master then fails immediately; \n"+
+                        "standby: will start up as lukewarm standby with no state - if there is not already a master then fails immediately, "
+                        + "and if there is a master which subsequently fails, this node can promote itself; \n"+
+                        "hot_standby: will start up as hot standby in read-only mode - if there is not already a master then fails immediately, "
+                        + "and if there is a master which subseuqently fails, this node can promote itself; \n"+
+                        "hot_backup: will start up as hot backup in read-only mode - no master is required, and this node will not become a master"
+                        )
+        public String highAvailability = HA_OPTION_AUTO;
+
+        @VisibleForTesting
+        protected ManagementContext explicitManagementContext;
+        
+        @Override
+        public Void call() throws Exception {
+            // Configure launcher
+            BrooklynLauncher launcher;
+            AppShutdownHandler shutdownHandler = new AppShutdownHandler();
+            failIfArguments();
+            try {
+                if (log.isDebugEnabled()) log.debug("Invoked launch command {}", this);
+                
+                if (!quiet) stdout.println(banner);
+    
+                if (verbose) {
+                    if (app != null) {
+                        stdout.println("Launching brooklyn app: " + app + " in " + locations);
+                    } else {
+                        stdout.println("Launching brooklyn server (no app)");
+                    }
+                }
+    
+                PersistMode persistMode = computePersistMode();
+                HighAvailabilityMode highAvailabilityMode = computeHighAvailabilityMode(persistMode);
+                
+                StopWhichAppsOnShutdown stopWhichAppsOnShutdownMode = computeStopWhichAppsOnShutdown();
+                
+                computeLocations();
+                
+                ResourceUtils utils = ResourceUtils.create(this);
+                GroovyClassLoader loader = new GroovyClassLoader(getClass().getClassLoader());
+    
+                // First, run a setup script if the user has provided one
+                if (script != null) {
+                    execGroovyScript(utils, loader, script);
+                }
+    
+                launcher = createLauncher();
+
+                CatalogInitialization catInit = new CatalogInitialization(catalogInitial, catalogReset, catalogAdd, catalogForce);
+                catInit.addPopulationCallback(new Function<CatalogInitialization,Void>() {
+                    @Override
+                    public Void apply(CatalogInitialization catInit) {
+                        try {
+                            populateCatalog(catInit.getManagementContext().getCatalog());
+                        } catch (Throwable e) {
+                            catInit.handleException(e, "overridden main class populate catalog");
+                        }
+                        
+                        // Force load of catalog (so web console is up to date)
+                        confirmCatalog(catInit);
+                        return null;
+                    }
+                });
+                catInit.setFailOnStartupErrors(startupFailOnCatalogErrors);
+                launcher.catalogInitialization(catInit);
+                
+                launcher.persistMode(persistMode);
+                launcher.persistenceDir(persistenceDir);
+                launcher.persistenceLocation(persistenceLocation);
+
+                launcher.highAvailabilityMode(highAvailabilityMode);
+
+                launcher.stopWhichAppsOnShutdown(stopWhichAppsOnShutdownMode);
+                launcher.shutdownHandler(shutdownHandler);
+                
+                computeAndSetApp(launcher, utils, loader);
+                
+                customize(launcher);
+                
+            } catch (FatalConfigurationRuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new FatalConfigurationRuntimeException("Fatal error configuring Brooklyn launch: "+e.getMessage(), e);
+            }
+            
+            // Launch server
+            try {
+                launcher.start();
+            } catch (FatalRuntimeException e) {
+                // rely on caller logging this propagated exception
+                throw e;
+            } catch (Exception e) {
+                // for other exceptions we log it, possibly redundantly but better too much than too little
+                Exceptions.propagateIfFatal(e);
+                log.error("Error launching brooklyn: "+Exceptions.collapseText(e), e);
+                try {
+                    launcher.terminate();
+                } catch (Exception e2) {
+                    log.warn("Subsequent error during termination: "+e2);
+                    log.debug("Details of subsequent error during termination: "+e2, e2);
+                }
+                Exceptions.propagate(e);
+            }
+            
+            BrooklynServerDetails server = launcher.getServerDetails();
+            ManagementContext ctx = server.getManagementContext();
+            
+            if (verbose) {
+                Entities.dumpInfo(launcher.getApplications());
+            }
+            
+            if (!exitAndLeaveAppsRunningAfterStarting) {
+                waitAfterLaunch(ctx, shutdownHandler);
+            }
+
+            // will call mgmt.terminate() in BrooklynShutdownHookJob
+            return null;
+        }
+
+        /** can be overridden by subclasses which need to customize the launcher and/or management */
+        protected void customize(BrooklynLauncher launcher) {
+        }
+        
+        protected void computeLocations() {
+            boolean hasLocations = !Strings.isBlank(locations);
+            if (app != null) {
+                if (hasLocations && isYamlApp()) {
+                    log.info("YAML app combined with command line locations; YAML locations will take precedence; this behaviour may change in subsequent versions");
+                } else if (!hasLocations && isYamlApp()) {
+                    log.info("No locations supplied; defaulting to locations defined in YAML (if any)");
+                } else if (!hasLocations) {
+                    log.info("No locations supplied; starting with no locations");
+                }
+            } else if (hasLocations) {
+                log.error("Locations specified without any applications; ignoring locations");
+            }
+        }
+
+        protected boolean isYamlApp() {
+            return app != null && app.endsWith(".yaml");
+        }
+
+        protected PersistMode computePersistMode() {
+            Maybe<PersistMode> persistMode = Enums.valueOfIgnoreCase(PersistMode.class, persist);
+            if (!persistMode.isPresent()) {
+                if (Strings.isBlank(persist)) {
+                    throw new FatalConfigurationRuntimeException("Persist mode must not be blank");
+                } else {
+                    throw new FatalConfigurationRuntimeException("Illegal persist setting: "+persist);
+                }
+            }
+   
+            if (persistMode.get() == PersistMode.DISABLED) {
+                if (Strings.isNonBlank(persistenceDir))
+                    throw new FatalConfigurationRuntimeException("Cannot specify persistenceDir when persist is disabled");
+                if (Strings.isNonBlank(persistenceLocation))
+                    throw new FatalConfigurationRuntimeException("Cannot specify persistenceLocation when persist is disabled");
+            }
+            return persistMode.get();
+        }
+
+        protected HighAvailabilityMode computeHighAvailabilityMode(PersistMode persistMode) {
+            Maybe<HighAvailabilityMode> highAvailabilityMode = Enums.valueOfIgnoreCase(HighAvailabilityMode.class, highAvailability);
+            if (!highAvailabilityMode.isPresent()) {
+                if (Strings.isBlank(highAvailability)) {
+                    throw new FatalConfigurationRuntimeException("High availability mode must not be blank");
+                } else {
+                    throw new FatalConfigurationRuntimeException("Illegal highAvailability setting: "+highAvailability);
+                }
+            }
+   
+            if (highAvailabilityMode.get() != HighAvailabilityMode.DISABLED) {
+                if (persistMode == PersistMode.DISABLED) {
+                    if (highAvailabilityMode.get() == HighAvailabilityMode.AUTO)
+                        return HighAvailabilityMode.DISABLED;
+                    throw new FatalConfigurationRuntimeException("Cannot specify highAvailability when persistence is disabled");
+                } else if (persistMode == PersistMode.CLEAN && 
+                        (highAvailabilityMode.get() == HighAvailabilityMode.STANDBY 
+                        || highAvailabilityMode.get() == HighAvailabilityMode.HOT_STANDBY
+                        || highAvailabilityMode.get() == HighAvailabilityMode.HOT_BACKUP)) {
+                    throw new FatalConfigurationRuntimeException("Cannot specify highAvailability "+highAvailabilityMode.get()+" when persistence is CLEAN");
+                }
+            }
+            return highAvailabilityMode.get();
+        }
+        
+        protected StopWhichAppsOnShutdown computeStopWhichAppsOnShutdown() {
+            boolean isDefault = STOP_THESE_IF_NOT_PERSISTED.equals(stopWhichAppsOnShutdown);
+            if (exitAndLeaveAppsRunningAfterStarting && isDefault) {
+                return StopWhichAppsOnShutdown.NONE;
+            } else {
+                return Enums.valueOfIgnoreCase(StopWhichAppsOnShutdown.class, stopWhichAppsOnShutdown).get();
+            }
+        }
+        
+        @VisibleForTesting
+        /** forces the launcher to use the given management context, when programmatically invoked;
+         * mainly used when testing to inject a safe (and fast) mgmt context */
+        public void useManagementContext(ManagementContext mgmt) {
+            explicitManagementContext = mgmt;
+        }
+
+        protected BrooklynLauncher createLauncher() {
+            BrooklynLauncher launcher;
+            launcher = BrooklynLauncher.newInstance();
+            launcher.localBrooklynPropertiesFile(localBrooklynProperties)
+                    .ignorePersistenceErrors(!startupFailOnPersistenceErrors)
+                    .ignoreCatalogErrors(!startupFailOnCatalogErrors)
+                    .ignoreWebErrors(startupContinueOnWebErrors)
+                    .ignoreAppErrors(!startupFailOnManagedAppsErrors)
+                    .locations(Strings.isBlank(locations) ? ImmutableList.<String>of() : JavaStringEscapes.unwrapJsonishListIfPossible(locations));
+            
+            launcher.webconsole(!noConsole);
+            if (useHttps) {
+                // true sets it; false (not set) leaves it blank and falls back to config key
+                // (no way currently to override config key, but that could be added)
+                launcher.webconsoleHttps(useHttps);
+            }
+            launcher.webconsolePort(port);
+            
+            if (noGlobalBrooklynProperties) {
+                log.debug("Configuring to disable global brooklyn.properties");
+                launcher.globalBrooklynPropertiesFile(null);
+            }
+            if (noConsoleSecurity) {
+                log.info("Configuring to disable console security");
+                launcher.installSecurityFilter(false);
+            }
+            if (startBrooklynNode) {
+                log.info("Configuring BrooklynNode entity startup");
+                launcher.startBrooklynNode(true);
+            }
+            if (Strings.isNonEmpty(bindAddress)) {
+                log.debug("Configuring bind address as "+bindAddress);
+                launcher.bindAddress(Networking.getInetAddressWithFixedName(bindAddress));
+            }
+            if (Strings.isNonEmpty(publicAddress)) {
+                log.debug("Configuring public address as "+publicAddress);
+                launcher.publicAddress(Networking.getInetAddressWithFixedName(publicAddress));
+            }
+            if (explicitManagementContext!=null) {
+                log.debug("Configuring explicit management context "+explicitManagementContext);
+                launcher.managementContext(explicitManagementContext);
+            }
+            return launcher;
+        }
+
+        /** method intended for subclassing, to add custom items to the catalog */
+        protected void populateCatalog(BrooklynCatalog catalog) {
+            // nothing else added here
+        }
+
+        protected void confirmCatalog(CatalogInitialization catInit) {
+            // Force load of catalog (so web console is up to date)
+            Stopwatch time = Stopwatch.createStarted();
+            BrooklynCatalog catalog = catInit.getManagementContext().getCatalog();
+            Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems();
+            for (CatalogItem<Object, Object> item: items) {
+                try {
+                    if (item.getCatalogItemType()==CatalogItemType.TEMPLATE) {
+                        // skip validation of templates, they might contain instructions,
+                        // and additionally they might contain multiple items in which case
+                        // the validation below won't work anyway (you need to go via a deployment plan)
+                    } else {
+                        Object spec = catalog.createSpec(item);
+                        if (spec instanceof EntitySpec) {
+                            BrooklynTypes.getDefinedEntityType(((EntitySpec<?>)spec).getType());
+                        }
+                        log.debug("Catalog loaded spec "+spec+" for item "+item);
+                    }
+                } catch (Throwable throwable) {
+                    catInit.handleException(throwable, item);
+                }
+            }
+            log.debug("Catalog (size "+Iterables.size(items)+") confirmed in "+Duration.of(time));                      
+            // nothing else added here
+        }
+        
+        /** convenience for subclasses to specify that an app should run,
+         * throwing the right (caught) error if another app has already been specified */
+        protected void setAppToLaunch(String className) {
+            if (app!=null) {
+                if (app.equals(className)) return;
+                throw new FatalConfigurationRuntimeException("Cannot specify app '"+className+"' when '"+app+"' is already specified; "
+                    + "remove one or more conflicting CLI arguments.");
+            }
+            app = className;
+        }
+        
+        protected void computeAndSetApp(BrooklynLauncher launcher, ResourceUtils utils, GroovyClassLoader loader)
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
+            if (app != null) {
+                // Create the instance of the brooklyn app
+                log.debug("Loading the user's application: {}", app);
+   
+                if (isYamlApp()) {
+                    log.debug("Loading application as YAML spec: {}", app);
+                    String content = utils.getResourceAsString(app);
+                    launcher.application(content);
+                } else {
+                    Object loadedApp = loadApplicationFromClasspathOrParse(utils, loader, app);
+                    if (loadedApp instanceof ApplicationBuilder) {
+                        launcher.application((ApplicationBuilder)loadedApp);
+                    } else if (loadedApp instanceof Application) {
+                        launcher.application((AbstractApplication)loadedApp);
+                    } else {
+                        throw new FatalConfigurationRuntimeException("Unexpected application type "+(loadedApp==null ? null : loadedApp.getClass())+", for app "+loadedApp);
+                    }
+                }
+            }
+        }
+        
+        protected void waitAfterLaunch(ManagementContext ctx, AppShutdownHandler shutdownHandler) throws IOException {
+            if (stopOnKeyPress) {
+                // Wait for the user to type a key
+                log.info("Server started. Press return to stop.");
+                // Read in another thread so we can use timeout on the wait.
+                Task<Void> readTask = ctx.getExecutionManager().submit(new Callable<Void>() {
+                    @Override
+                    public Void call() throws Exception {
+                        stdin.read();
+                        return null;
+                    }
+                });
+                while (!shutdownHandler.isRequested()) {
+                    try {
+                        readTask.get(Duration.ONE_SECOND);
+                        break;
+                    } catch (TimeoutException e) {
+                        //check if there's a shutdown request
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                        throw Exceptions.propagate(e);
+                    } catch (ExecutionException e) {
+                        throw Exceptions.propagate(e);
+                    }
+                }
+                log.info("Shutting down applications.");
+                stopAllApps(ctx.getApplications());
+            } else {
+                // Block forever so that Brooklyn doesn't exit (until someone does cntrl-c or kill)
+                log.info("Launched Brooklyn; will now block until shutdown command received via GUI/API (recommended) or process interrupt.");
+                shutdownHandler.waitOnShutdownRequest();
+            }
+        }
+
+        protected void execGroovyScript(ResourceUtils utils, GroovyClassLoader loader, String script) {
+            log.debug("Running the user provided script: {}", script);
+            String content = utils.getResourceAsString(script);
+            GroovyShell shell = new GroovyShell(loader);
+            shell.evaluate(content);
+        }
+
+        /**
+         * Helper method that gets an instance of a brooklyn {@link AbstractApplication} or an {@link ApplicationBuilder}.
+         * Guaranteed to be non-null result of one of those types (throwing exception if app not appropriate).
+         */
+        @SuppressWarnings("unchecked")
+        protected Object loadApplicationFromClasspathOrParse(ResourceUtils utils, GroovyClassLoader loader, String app)
+                throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
+            
+            Class<?> tempclazz;
+            log.debug("Loading application as class on classpath: {}", app);
+            try {
+                tempclazz = loader.loadClass(app, true, false);
+            } catch (ClassNotFoundException cnfe) { // Not a class on the classpath
+                log.debug("Loading \"{}\" as class on classpath failed, now trying as .groovy source file", app);
+                String content = utils.getResourceAsString(app);
+                tempclazz = loader.parseClass(content);
+            }
+            final Class<?> clazz = tempclazz;
+            
+            // Instantiate an app builder (wrapping app class in ApplicationBuilder, if necessary)
+            if (ApplicationBuilder.class.isAssignableFrom(clazz)) {
+                Constructor<?> constructor = clazz.getConstructor();
+                return (ApplicationBuilder) constructor.newInstance();
+            } else if (StartableApplication.class.isAssignableFrom(clazz)) {
+                EntitySpec<? extends StartableApplication> appSpec;
+                if (tempclazz.isInterface())
+                    appSpec = EntitySpec.create((Class<? extends StartableApplication>) clazz);
+                else
+                    appSpec = EntitySpec.create(StartableApplication.class, (Class<? extends StartableApplication>) clazz);
+                return new ApplicationBuilder(appSpec) {
+                    @Override protected void doBuild() {
+                    }};
+            } else if (AbstractApplication.class.isAssignableFrom(clazz)) {
+                // TODO If this application overrides init() then in trouble, as that won't get called!
+                // TODO grr; what to do about non-startable applications?
+                // without this we could return ApplicationBuilder rather than Object
+                Constructor<?> constructor = clazz.getConstructor();
+                return (AbstractApplication) constructor.newInstance();
+            } else if (AbstractEntity.class.isAssignableFrom(clazz)) {
+                // TODO Should we really accept any entity type, and just wrap it in an app? That's not documented!
+                return new ApplicationBuilder() {
+                    @Override protected void doBuild() {
+                        addChild(EntitySpec.create(Entity.class).impl((Class<? extends AbstractEntity>)clazz).additionalInterfaces(clazz.getInterfaces()));
+                    }};
+            } else if (Entity.class.isAssignableFrom(clazz)) {
+                return new ApplicationBuilder() {
+                    @Override protected void doBuild() {
+                        addChild(EntitySpec.create((Class<? extends Entity>)clazz));
+                    }};
+            } else {
+                throw new FatalConfigurationRuntimeException("Application class "+clazz+" must extend one of ApplicationBuilder or AbstractApplication");
+            }
+        }
+
+        @VisibleForTesting
+        protected void stopAllApps(Collection<? extends Application> applications) {
+            for (Application application : applications) {
+                try {
+                    if (application instanceof Startable) {
+                        ((Startable)application).stop();
+                    }
+                } catch (Exception e) {
+                    log.error("Error stopping "+application+": "+e, e);
+                }
+            }
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("app", app)
+                    .add("script", script)
+                    .add("location", locations)
+                    .add("port", port)
+                    .add("bindAddress", bindAddress)
+                    .add("noConsole", noConsole)
+                    .add("noConsoleSecurity", noConsoleSecurity)
+                    .add("startupFailOnPersistenceErrors", startupFailOnPersistenceErrors)
+                    .add("startupFailsOnCatalogErrors", startupFailOnCatalogErrors)
+                    .add("startupContinueOnWebErrors", startupContinueOnWebErrors)
+                    .add("startupFailOnManagedAppsErrors", startupFailOnManagedAppsErrors)
+                    .add("catalogInitial", catalogInitial)
+                    .add("catalogAdd", catalogAdd)
+                    .add("catalogReset", catalogReset)
+                    .add("catalogForce", catalogForce)
+                    .add("stopWhichAppsOnShutdown", stopWhichAppsOnShutdown)
+                    .add("stopOnKeyPress", stopOnKeyPress)
+                    .add("localBrooklynProperties", localBrooklynProperties)
+                    .add("persist", persist)
+                    .add("persistenceLocation", persistenceLocation)
+                    .add("persistenceDir", persistenceDir)
+                    .add("highAvailability", highAvailability)
+                    .add("exitAndLeaveAppsRunningAfterStarting", exitAndLeaveAppsRunningAfterStarting);
+        }
+    }
+
+    @Command(name = "copy-state", description = "Retrieves persisted state")
+    public static class CopyStateCommand extends BrooklynCommandCollectingArgs {
+
+        @Option(name = { "--localBrooklynProperties" }, title = "local brooklyn.properties file",
+                description = "local brooklyn.properties file, specific to this launch (appending to and overriding global properties)")
+        public String localBrooklynProperties;
+
+        @Option(name = { "--persistenceDir" }, title = "persistence dir",
+                description = "The directory to read persisted state (or container name if using an object store)")
+        public String persistenceDir;
+
+        @Option(name = { "--persistenceLocation" }, title = "persistence location",
+            description = "The location spec for an object store to read persisted state")
+        public String persistenceLocation;
+    
+        @Option(name = { "--destinationDir" }, required = true, title = "destination dir",
+                description = "The directory to copy persistence data to")
+            public String destinationDir;
+        
+        @Option(name = { "--destinationLocation" }, title = "persistence location",
+                description = "The location spec for an object store to copy data to")
+            public String destinationLocation;
+        
+        @Option(name = { "--transformations" }, title = "transformations",
+                description = "local transformations file, to be applied to the copy of the data before uploading it")
+        public String transformations;
+        
+        @Override
+        public Void call() throws Exception {
+            checkNotNull(destinationDir, "destinationDir"); // presumably because required=true this will never be null!
+            
+            // Configure launcher
+            BrooklynLauncher launcher;
+            failIfArguments();
+            try {
+                log.info("Retrieving and copying persisted state to "+destinationDir+(Strings.isBlank(destinationLocation) ? "" : " @ "+destinationLocation));
+                
+                if (!quiet) stdout.println(banner);
+    
+                PersistMode persistMode = PersistMode.AUTO;
+                HighAvailabilityMode highAvailabilityMode = HighAvailabilityMode.DISABLED;
+                
+                launcher = BrooklynLauncher.newInstance()
+                        .localBrooklynPropertiesFile(localBrooklynProperties)
+                        .brooklynProperties(OsgiManager.USE_OSGI, false)
+                        .persistMode(persistMode)
+                        .persistenceDir(persistenceDir)
+                        .persistenceLocation(persistenceLocation)
+                        .highAvailabilityMode(highAvailabilityMode);
+                
+            } catch (FatalConfigurationRuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new FatalConfigurationRuntimeException("Fatal error configuring Brooklyn launch: "+e.getMessage(), e);
+            }
+            
+            try {
+                launcher.copyPersistedState(destinationDir, destinationLocation, loadTransformer(transformations));
+            } catch (FatalRuntimeException e) {
+                // rely on caller logging this propagated exception
+                throw e;
+            } catch (Exception e) {
+                // for other exceptions we log it, possibly redundantly but better too much than too little
+                Exceptions.propagateIfFatal(e);
+                log.error("Error retrieving persisted state: "+Exceptions.collapseText(e), e);
+                Exceptions.propagate(e);
+            } finally {
+                try {
+                    launcher.terminate();
+                } catch (Exception e2) {
+                    log.warn("Subsequent error during termination: "+e2);
+                    log.debug("Details of subsequent error during termination: "+e2, e2);
+                }
+            }
+            
+            return null;
+        }
+
+        protected CompoundTransformer loadTransformer(String transformationsFileUrl) {
+            return BrooklynPersistenceUtils.loadTransformer(ResourceUtils.create(this), transformationsFileUrl);
+        }
+        
+        @Override
+        public ToStringHelper string() {
+            return super.string()
+                    .add("localBrooklynProperties", localBrooklynProperties)
+                    .add("persistenceLocation", persistenceLocation)
+                    .add("persistenceDir", persistenceDir)
+                    .add("destinationDir", destinationDir);
+        }
+    }
+
+    /** method intended for overriding when a different {@link Cli} is desired,
+     * or when the subclass wishes to change any of the arguments */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected CliBuilder<BrooklynCommand> cliBuilder() {
+        CliBuilder<BrooklynCommand> builder = Cli.<BrooklynCommand>builder(cliScriptName())
+                .withDescription("Brooklyn Management Service")
+                .withDefaultCommand(cliDefaultInfoCommand())
+                .withCommands(
+                        HelpCommand.class,
+                        cliInfoCommand(),
+                        GeneratePasswordCommand.class,
+                        CopyStateCommand.class,
+                        ListAllCommand.class,
+                        cliLaunchCommand()
+                );
+
+        builder.withGroup("cloud-compute")
+                .withDescription("Access compute details of a given cloud")
+                .withDefaultCommand(HelpCommand.class)
+                .withCommands(
+                        ComputeListImagesCommand.class,
+                        ComputeListHardwareProfilesCommand.class,
+                        ComputeListInstancesCommand.class,
+                        ComputeGetImageCommand.class,
+                        ComputeDefaultTemplateCommand.class,
+                        ComputeTerminateInstancesCommand.class);
+
+        builder.withGroup("cloud-blobstore")
+                .withDescription("Access blobstore details of a given cloud")
+                .withDefaultCommand(HelpCommand.class)
+                .withCommands(
+                        BlobstoreListContainersCommand.class, 
+                        BlobstoreListContainerCommand.class,
+                        BlobstoreGetBlobCommand.class);
+
+        return builder;
+    }
+    
+    /** method intended for overriding when a custom {@link LaunchCommand} is being specified  */
+    protected Class<? extends BrooklynCommand> cliLaunchCommand() {
+        return LaunchCommand.class;
+    }
+    
+    /** method intended for overriding when a custom {@link InfoCommand} is being specified  */
+    protected Class<? extends BrooklynCommand> cliInfoCommand() {
+        return InfoCommand.class;
+    }
+    
+    /** method intended for overriding when a custom {@link InfoCommand} is being specified  */
+    protected Class<? extends BrooklynCommand> cliDefaultInfoCommand() {
+        return DefaultInfoCommand.class;
+    }
+    
+    public static class AppShutdownHandler implements ShutdownHandler {
+        private CountDownLatch lock = new CountDownLatch(1);
+
+        @Override
+        public void onShutdownRequest() {
+            lock.countDown();
+        }
+        
+        public boolean isRequested() {
+            return lock.getCount() == 0;
+        }
+
+        public void waitOnShutdownRequest() {
+            try {
+                lock.await();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                return; // exit gracefully
+            }
+        }
+    }
+}


[07/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
new file mode 100644
index 0000000..99830c9
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
@@ -0,0 +1,262 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertTrue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.basic.BrooklynTypes;
+
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.catalog.CatalogItem;
+import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.LocationSpec;
+import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
+import brooklyn.policy.Policy;
+import brooklyn.policy.PolicySpec;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.text.Strings;
+
+import com.google.common.collect.Iterables;
+
+/** Many of the same tests as per {@link OsgiVersionMoreEntityTest} but using YAML for catalog and entities, so catalog item ID is set automatically */
+public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest {
+    
+    private static final Logger log = LoggerFactory.getLogger(CatalogOsgiVersionMoreEntityTest.class);
+    
+    private static String getLocalResource(String filename) {
+        return ResourceUtils.create(CatalogOsgiVersionMoreEntityTest.class).getResourceAsString(
+            "classpath:/"+CatalogOsgiVersionMoreEntityTest.class.getPackage().getName().replace('.', '/')+"/"+filename);
+    }
+    
+    @Test
+    public void testMoreEntityV1() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
+
+        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity");
+        Assert.assertNotNull(item);
+        Assert.assertEquals(item.getVersion(), "1.0");
+        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY);
+        Assert.assertEquals(item.getLibraries().size(), 1);
+        
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
+        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity);
+        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity);
+    }
+
+    /** TODO we get warnings from {@link BrooklynEntityMatcher#extractValidConfigFlagsOrKeys};
+     * if we passed the correct loader at that point we could avoid those warnings. */ 
+    @Test
+    public void testMoreEntityV1WithPolicy() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("simple-policy-osgi-catalog.yaml"));
+        addCatalogItems(getLocalResource("more-entity-v1-with-policy-osgi-catalog.yaml"));
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
+        
+        Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies());
+        Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies());
+        // it was loaded by yaml w ref to catalog, so should have the simple-policy catalog-id
+        Assert.assertEquals(policy.getCatalogItemId(), "simple-policy:1.0");
+    }
+
+    @Test
+    public void testMoreEntityV2() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
+        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
+        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
+        
+        Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies());
+        Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies());
+        // it was loaded from the java so should have the base more-entity catalog id
+        Assert.assertEquals(policy.getCatalogItemId(), "more-entity:1.0");
+    }
+
+    @Test
+    /** TODO this test works if we assume most recent version wins, but semantics TBC */
+    public void testMoreEntityV2ThenV1GivesV1() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
+        forceCatalogUpdate();
+        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity);
+        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity);
+    }
+
+    /** unlike {@link #testMoreEntityV2ThenV1GivesV1()} this test should always work,
+     * because default should probably be either most-recent version or highest version,
+     * in either case this works */
+    @Test
+    public void testMoreEntityV1ThenV2GivesV2() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
+        forceCatalogUpdate();
+        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
+        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
+    }
+
+    @Test
+    public void testMoreEntityBothV1AndV2() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("more-entity-v1-called-v1-osgi-catalog.yaml"));
+        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
+        Entity v1 = createAndStartApplication("services: [ { type: 'more-entity-v1:1.0' } ]");
+        Entity v2 = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
+        
+        Entity moreEntityV1 = Iterables.getOnlyElement(v1.getChildren());
+        Entity moreEntityV2 = Iterables.getOnlyElement(v2.getChildren());
+        
+        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntityV1);
+        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntityV1);
+        
+        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntityV2);
+        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntityV2);
+    }
+
+    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
+    public void testMoreEntityV2AutoscanWithClasspath() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+        
+        addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml"));
+        
+        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
+
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity");
+        Assert.assertNotNull(item);
+        Assert.assertEquals(item.getVersion(), "2.0.test");
+        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY);
+        
+        // this refers to the java item, where the libraries are defined
+        item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MoreEntity");
+        Assert.assertEquals(item.getVersion(), "2.0.test_java");
+        Assert.assertEquals(item.getLibraries().size(), 2);
+        
+        Entity app = createAndStartApplication("services: [ { type: 'more-entity:2.0.test' } ]");
+        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
+        
+        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:2.0.test");
+        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
+        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
+    }
+
+    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
+    public void testMorePolicyV2AutoscanWithClasspath() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+        
+        addCatalogItems(getLocalResource("more-policies-osgi-catalog-scan.yaml"));
+        
+        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
+
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-policy");
+        Assert.assertNotNull(item);
+        Assert.assertEquals(item.getVersion(), "2.0.test");
+        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.POLICY);
+        
+        // this refers to the java item, where the libraries are defined
+        item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MorePolicy");
+        Assert.assertEquals(item.getVersion(), "2.0.test_java");
+        Assert.assertEquals(item.getLibraries().size(), 2);
+        
+        Entity app = createAndStartApplication(
+                "services: ",
+                "- type: brooklyn.entity.basic.BasicEntity",
+                "  brooklyn.policies:",
+                "  - type: more-policy:2.0.test");
+        Entity basicEntity = Iterables.getOnlyElement(app.getChildren());
+        Policy morePolicy = Iterables.getOnlyElement(basicEntity.getPolicies());
+        
+        Assert.assertEquals(morePolicy.getCatalogItemId(), "more-policy:2.0.test");
+        OsgiVersionMoreEntityTest.assertV2MethodCall(morePolicy);
+    }
+
+    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
+    public void testAutoscanWithClasspathCanCreateSpecs() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
+
+        addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml"));
+
+        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
+
+        BrooklynCatalog catalog = mgmt().getCatalog();
+        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems();
+        for (CatalogItem<Object, Object> item: items) {
+            Object spec = catalog.createSpec(item);
+            switch (item.getCatalogItemType()) {
+                case TEMPLATE:
+                case ENTITY:
+                    assertTrue(spec instanceof EntitySpec, "Not an EntitySpec: " + spec);
+                    BrooklynTypes.getDefinedEntityType(((EntitySpec<?>)spec).getType());
+                    break;
+                case POLICY:
+                    assertTrue(spec instanceof PolicySpec, "Not a PolicySpec: " + spec);
+                    BrooklynTypes.getDefinedBrooklynType(((PolicySpec<?>)spec).getType());
+                    break;
+                case LOCATION:
+                    assertTrue(spec instanceof LocationSpec, "Not a LocationSpec: " + spec);
+                    BrooklynTypes.getDefinedBrooklynType(((LocationSpec<?>)spec).getType());
+                    break;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
new file mode 100644
index 0000000..fc2c7e5
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.catalog;
+
+import org.testng.annotations.Test;
+
+public class CatalogXmlOsgiTest extends AbstractCatalogXmlTest {
+
+    public CatalogXmlOsgiTest(String catalogUrl) {
+        super("classpath://osgi-catalog.xml");
+    }
+
+    //OSGi libraries not supported with old-style catalog items
+    //We treat those catalog items just as an alias to the java type they hold.
+    //No loader wrapping their libraries is ever created.
+    @Test(expectedExceptions=IllegalStateException.class)
+    public void testOsgiItem() throws Exception {
+        startApp("OsgiApp");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
new file mode 100644
index 0000000..4bed94d
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+
+public class CatalogXmlVersionTest extends AbstractCatalogXmlTest {
+
+    public CatalogXmlVersionTest(String catalogUrl) {
+        super("classpath://simple-catalog.xml");
+    }
+
+    @DataProvider(name = "types")
+    public Object[][] createTypes() {
+        return new Object[][] {
+                {"brooklyn.entity.basic.BasicApplication"},
+                {"brooklyn.entity.basic.BasicApplication:0.0.0.SNAPSHOT"},
+                {"brooklyn.entity.basic.BasicApplication:2.0"},
+                {"BasicApp"}, // test that items with symbolicName not matching the type work
+                {"BasicApp:0.0.0.SNAPSHOT"},
+                {"BasicApp:2.0"},
+                {"brooklyn.osgi.tests.SimpleApplication"}, //test that classpath is used
+        };
+    }
+
+    @Test(dataProvider = "types")
+    public void testXmlCatalogItem(String type) throws Exception {
+        startApp(type);
+    }
+
+    @Test
+    public void testJavaPrefixDoesNotLoadXMLCatalogItem() throws Exception {
+        Entity entity = startApp("java:org.apache.brooklyn.camp.brooklyn.catalog.TestBasicApp");
+        assertTrue(entity instanceof TestBasicApp, "Entity is not a " + TestBasicApp.class.getName() + ", instead the type is " + entity.getEntityType().getName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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
new file mode 100644
index 0000000..e66c185
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.catalog;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.BasicStartable;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.policy.Policy;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.collect.Iterables;
+
+
+public class CatalogYamlCombiTest extends AbstractYamlTest {
+
+    private static final Logger log = LoggerFactory.getLogger(CatalogYamlCombiTest.class);
+    
+    @Test
+    public void testBRefEntityA() throws Exception {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  version: "+TEST_VERSION,
+            "  items:",
+            "  - item:",
+            "      id: A",
+            "      type: "+BasicEntity.class.getName(),
+            "      brooklyn.config: { a: 1, b: 0 }",
+            "  - item:",
+            "      id: B",
+            "      type: A",
+            "      brooklyn.config: { b: 1 }");
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("B", TEST_VERSION);
+        Assert.assertNotNull(item);
+
+        Entity a = launchEntity("A");
+        Assert.assertTrue(BasicEntity.class.isInstance(a), "Wrong type: "+a);
+        Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1);
+        Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)0);
+
+        Entity b = launchEntity("B");
+        Assert.assertTrue(BasicEntity.class.isInstance(b), "Wrong type: "+b);
+        Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1);
+        Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)1);
+
+        deleteCatalogEntity("A");
+        
+        // now loading B makes an error
+        try {
+            launchEntity("B");
+            Assert.fail("B should not be launchable");
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            log.info("Got expected error: "+e);
+        }
+        
+        deleteCatalogEntity("B");
+    }
+
+    @Test
+    public void testBRefPolicyALocationZ() throws Exception {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  version: "+TEST_VERSION,
+            "  id: Z",
+            "  items:",
+            "  - item: ",
+            "      type: localhost",
+            "      brooklyn.config: { z: 9 }");
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  version: "+TEST_VERSION,
+            "  items:",
+            "  - item_type: policy", 
+            "    item:",
+            "      id: A",
+            "      type: "+ServiceRestarter.class.getName(),
+            "      brooklyn.config: { a: 99 }",
+            "  - item:",
+            "      id: B",
+            "      type: "+BasicStartable.class.getName(),
+            "      location: Z",
+            "      brooklyn.policies:",
+            "      - type: A");
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("A", TEST_VERSION);
+        Assert.assertNotNull(item);
+
+        Entity b = launchEntity("B", false);
+        Assert.assertTrue(BasicStartable.class.isInstance(b), "Wrong type: "+b);
+        Entities.dumpInfo(b);
+        
+        Assert.assertEquals(Iterables.getOnlyElement(b.getLocations()).getConfig(ConfigKeys.newIntegerConfigKey("z")), (Integer)9);
+        
+        Policy p = Iterables.getOnlyElement(b.getPolicies());
+        Assert.assertTrue(ServiceRestarter.class.isInstance(p), "Wrong type: "+p);
+        Assert.assertEquals(p.getConfig(ConfigKeys.newIntegerConfigKey("a")), (Integer)99);
+        
+        deleteCatalogEntity("A");
+        deleteCatalogEntity("B");
+        deleteCatalogEntity("Z");
+    }
+
+    private Entity launchEntity(String symbolicName) throws Exception {
+        return launchEntity(symbolicName, true);
+    }
+    
+    private Entity launchEntity(String symbolicName, boolean includeLocation) throws Exception {
+        String yaml = "name: simple-app-yaml\n" +
+                      (includeLocation ? "location: localhost\n" : "") +
+                      "services: \n" +
+                      "  - type: "+ver(symbolicName);
+        Entity app = createAndStartApplication(yaml);
+        return Iterables.getOnlyElement(app.getChildren());
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
new file mode 100644
index 0000000..5d3dc75
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
@@ -0,0 +1,780 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+import brooklyn.management.osgi.OsgiTestResources;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.test.entity.TestEntityImpl;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.collect.Iterables;
+
+
+public class CatalogYamlEntityTest extends AbstractYamlTest {
+    
+    private static final String SIMPLE_ENTITY_TYPE = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY;
+
+    @Test
+    public void testAddCatalogItemVerySimple() throws Exception {
+        String symbolicName = "my.catalog.app.id.load";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  version: " + TEST_VERSION,
+            "  item:",
+            "    type: "+ BasicEntity.class.getName());
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertTrue(item.getPlanYaml().indexOf("services:")>=0, "expected 'services:' block: "+item+"\n"+item.getPlanYaml());
+
+        deleteCatalogEntity(symbolicName);
+    }
+    @Test
+    public void testAddCatalogItem() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.load";
+        addCatalogOSGiEntity(symbolicName);
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemTypeAsString() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.load";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item: " + SIMPLE_ENTITY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemTypeExplicitTypeAsString() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.load";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  item_type: entity",
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item: " + SIMPLE_ENTITY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemTopLevelSyntax() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.load";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemWithoutVersion() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "unversioned.app";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  name: " + id,
+            "  libraries:",
+            "  - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item:",
+            "    type: "+ SIMPLE_ENTITY_TYPE);
+        CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, BrooklynCatalog.DEFAULT_VERSION);
+        assertEquals(catalogItem.getVersion(), "0.0.0.SNAPSHOT");
+        mgmt().getCatalog().deleteCatalogItem(id, "0.0.0.SNAPSHOT");
+    }
+
+    @Test
+    public void testAddCatalogItemWithInlinedVersion() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "inline_version.app";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  name: " + id+":"+TEST_VERSION,
+            "  libraries:",
+            "  - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE);
+        CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, TEST_VERSION);
+        assertEquals(catalogItem.getVersion(), TEST_VERSION);
+        mgmt().getCatalog().deleteCatalogItem(id, TEST_VERSION);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingCatalog() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.launch";
+        registerAndLaunchAndAssertSimpleEntity(symbolicName, SIMPLE_ENTITY_TYPE);
+    }
+
+    @Test
+    public void testLaunchApplicationUnversionedCatalogReference() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.fail";
+        addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE);
+        try {
+            String yaml = "name: simple-app-yaml\n" +
+                          "location: localhost\n" +
+                          "services: \n" +
+                          "  - serviceType: " + symbolicName;
+            createAndStartApplication(yaml);
+        } finally {
+            deleteCatalogEntity(symbolicName);
+        }
+    }
+
+    @Test
+    public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String referencedSymbolicName = "my.catalog.app.id.referenced";
+        String referrerSymbolicName = "my.catalog.app.id.referring";
+        addCatalogOSGiEntities(referencedSymbolicName, SIMPLE_ENTITY_TYPE, referrerSymbolicName, ver(referencedSymbolicName));
+
+        CatalogItem<?, ?> referrer = mgmt().getCatalog().getCatalogItem(referrerSymbolicName, TEST_VERSION);
+        Assert.assertTrue(referrer.getPlanYaml().indexOf("services")>=0, "expected services in: "+referrer.getPlanYaml());
+        
+        String yaml = "name: simple-app-yaml\n" +
+                      "location: localhost\n" +
+                      "services: \n" +
+                      "  - type: " + ver(referrerSymbolicName);
+        Entity app = createAndStartApplication(yaml);
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(referencedSymbolicName);
+        deleteCatalogEntity(referrerSymbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationWithCatalogReferencingOtherCatalogInTwoSteps() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String referencedSymbolicName = "my.catalog.app.id.referenced";
+        String referrerSymbolicName = "my.catalog.app.id.referring";
+        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
+        addCatalogOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName));
+
+        String yaml = "name: simple-app-yaml\n" +
+                      "location: localhost\n" +
+                      "services: \n" +
+                      "  - serviceType: " + ver(referrerSymbolicName);
+        Entity app = createAndStartApplication(yaml);
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(referencedSymbolicName);
+        deleteCatalogEntity(referrerSymbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationChildWithCatalogReferencingOtherCatalog() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String referencedSymbolicName = "my.catalog.app.id.child.referenced";
+        String referrerSymbolicName = "my.catalog.app.id.child.referring";
+        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
+        addCatalogChildOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName));
+
+        Entity app = createAndStartApplication(
+            "name: simple-app-yaml",
+            "location: localhost",
+            "services:",
+            "- type: "+BasicEntity.class.getName(),
+            "  brooklyn.children:",
+            "  - type: " + ver(referrerSymbolicName));
+
+        Collection<Entity> children = app.getChildren();
+        assertEquals(children.size(), 1);
+        Entity child = Iterables.getOnlyElement(children);
+        assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
+        Collection<Entity> grandChildren = child.getChildren();
+        assertEquals(grandChildren.size(), 1);
+        Entity grandChild = Iterables.getOnlyElement(grandChildren);
+        assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
+        Collection<Entity> grandGrandChildren = grandChild.getChildren();
+        assertEquals(grandGrandChildren.size(), 1);
+        Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren);
+        assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(referencedSymbolicName);
+        deleteCatalogEntity(referrerSymbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationChildWithCatalogReferencingOtherCatalogServicesBlock() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String referencedSymbolicName = "my.catalog.app.id.child.referenced";
+        String referrerSymbolicName = "my.catalog.app.id.child.referring";
+        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
+        addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referencedSymbolicName));
+
+        Entity app = createAndStartApplication(
+            "name: simple-app-yaml",
+            "location: localhost",
+            "services:",
+            "- serviceType: "+BasicEntity.class.getName(),
+            "  brooklyn.children:",
+            "  - type: " + ver(referrerSymbolicName));
+
+        Collection<Entity> children = app.getChildren();
+        assertEquals(children.size(), 1);
+        Entity child = Iterables.getOnlyElement(children);
+        assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
+        Collection<Entity> grandChildren = child.getChildren();
+        assertEquals(grandChildren.size(), 1);
+        Entity grandChild = Iterables.getOnlyElement(grandChildren);
+        assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
+        Collection<Entity> grandGrandChildren = grandChild.getChildren();
+        assertEquals(grandGrandChildren.size(), 1);
+        Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren);
+        assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(referencedSymbolicName);
+        deleteCatalogEntity(referrerSymbolicName);
+    }
+    
+    @Test
+    public void testLaunchApplicationWithTypeUsingJavaColonPrefix() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = SIMPLE_ENTITY_TYPE;
+        String serviceName = "java:"+SIMPLE_ENTITY_TYPE;
+        registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName);
+    }
+
+    @Test
+    public void testLaunchApplicationLoopWithJavaTypeName() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = SIMPLE_ENTITY_TYPE;
+        String serviceName = SIMPLE_ENTITY_TYPE;
+        registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName);
+    }
+
+    @Test
+    public void testLaunchApplicationChildLoopCatalogIdFails() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String referrerSymbolicName = "my.catalog.app.id.child.referring";
+        try {
+            // TODO only fails if using 'services', because that forces plan parsing; should fail in all cases
+            addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referrerSymbolicName));
+            fail("Expected to throw");
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            assertTrue(e.getMessage().contains(referrerSymbolicName), "message was: "+e);
+        }
+    }
+
+    @Test
+    public void testReferenceInstalledBundleByName() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String firstItemId = "my.catalog.app.id.register_bundle";
+        String secondItemId = "my.catalog.app.id.reference_bundle";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + firstItemId,
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE);
+        deleteCatalogEntity(firstItemId);
+
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + secondItemId,
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME,
+            "    version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
+            "",
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(secondItemId);
+    }
+
+    @Test
+    public void testReferenceNonInstalledBundledByNameFails() {
+        String nonExistentId = "none-existent-id";
+        String nonExistentVersion = "9.9.9";
+        try {
+            addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: my.catalog.app.id.non_existing.ref",
+                "  version: " + TEST_VERSION,
+                "  libraries:",
+                "  - name: " + nonExistentId,
+                "    version: " + nonExistentVersion,
+                "",
+                "services:",
+                "- type: " + SIMPLE_ENTITY_TYPE);
+            fail();
+        } catch (IllegalStateException e) {
+            Assert.assertEquals(e.getMessage(), "Bundle from null failed to install: Bundle CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=null} not previously registered, but URL is empty.");
+        }
+    }
+
+    @Test
+    public void testPartialBundleReferenceFails() {
+        try {
+            addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: my.catalog.app.id.non_existing.ref",
+                "  version: " + TEST_VERSION,
+                "  libraries:",
+                "  - name: io.brooklyn.brooklyn-test-osgi-entities",
+                "",
+                "services:",
+                "- type: " + SIMPLE_ENTITY_TYPE);
+            fail();
+        } catch (NullPointerException e) {
+            Assert.assertEquals(e.getMessage(), "both name and version are required");
+        }
+        try {
+            addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: my.catalog.app.id.non_existing.ref",
+                "  version: " + TEST_VERSION,
+                "  libraries:",
+                "  - version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
+                "",
+                "services:",
+                "- type: " + SIMPLE_ENTITY_TYPE);
+            fail();
+        } catch (NullPointerException e) {
+            Assert.assertEquals(e.getMessage(), "both name and version are required");
+        }
+    }
+
+    @Test
+    public void testFullBundleReference() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String itemId = "my.catalog.app.id.full_ref";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + itemId,
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME,
+            "    version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
+            "    url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE);
+        deleteCatalogEntity(itemId);
+    }
+
+    /**
+     * Test that the name:version contained in the OSGi bundle will
+     * override the values supplied in the YAML.
+     */
+    @Test
+    public void testFullBundleReferenceUrlMetaOverridesLocalNameVersion() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String firstItemId = "my.catalog.app.id.register_bundle";
+        String nonExistentId = "non_existent_id";
+        String nonExistentVersion = "9.9.9";
+        try {
+            addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + firstItemId,
+                "  version: " + TEST_VERSION,
+                "  libraries:",
+                "  - name: " + nonExistentId,
+                "    version: " + nonExistentVersion,
+                "    url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+                "",
+                "services:",
+                "- type: " + SIMPLE_ENTITY_TYPE);
+            fail();
+        } catch (IllegalStateException e) {
+            assertEquals(e.getMessage(), "Bundle from " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + " failed to install: " +
+                    "Bundle already installed as " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME + ":" +
+                    OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION + " but user explicitly requested " +
+                    "CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=" +
+                    OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + "}");
+        }
+    }
+
+    @Test
+    public void testUpdatingItemAllowedIfSame() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "my.catalog.app.id.duplicate";
+        addCatalogOSGiEntity(id);
+        addCatalogOSGiEntity(id);
+    }
+    
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testUpdatingItemFailsIfDifferent() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "my.catalog.app.id.duplicate";
+        addCatalogOSGiEntity(id);
+        addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE, true);
+    }
+
+    @Test
+    public void testForcedUpdatingItem() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "my.catalog.app.id.duplicate";
+        addCatalogOSGiEntity(id);
+        forceCatalogUpdate();
+        addCatalogOSGiEntity(id);
+        deleteCatalogEntity(id);
+    }
+
+    @Test
+    public void testCreateSpecFromCatalogItem() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "my.catalog.app.id.create_spec";
+        addCatalogOSGiEntity(id);
+        BrooklynCatalog catalog = mgmt().getCatalog();
+        CatalogItem<?, ?> item = catalog.getCatalogItem(id, TEST_VERSION);
+        Object spec = catalog.createSpec(item);
+        Assert.assertNotNull(spec);
+    }
+    
+    @Test
+    public void testLoadResourceFromBundle() throws Exception {
+        String id = "resource.test";
+        addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE);
+        String yaml =
+                "services: \n" +
+                "  - serviceType: "+ver(id);
+        Entity app = createAndStartApplication(yaml);
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        InputStream icon = new ResourceUtils(simpleEntity).getResourceFromUrl("classpath:/brooklyn/osgi/tests/icon.gif");
+        assertTrue(icon != null);
+        icon.close();
+    }
+    
+    @Test
+    public void testMissingTypeDoesNotRecurse() {
+        String symbolicName = "my.catalog.app.id.basic";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  version: " + TEST_VERSION,
+            "",
+            "services:",
+            "- type: brooklyn.entity.basic.BasicEntity");
+
+        try {
+            addCatalogItems(
+                    "brooklyn.catalog:",
+                    "  id: " + symbolicName,
+                    "  version: " + TEST_VERSION + "-update",
+                    "",
+                    "services:",
+                    "- type: " + symbolicName);
+            fail("Catalog addition expected to fail due to non-existent java type " + symbolicName);
+        } catch (IllegalStateException e) {
+            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
+        }
+    }
+    
+    @Test
+    public void testVersionedTypeDoesNotRecurse() {
+        String symbolicName = "my.catalog.app.id.basic";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  version: " + TEST_VERSION,
+            "",
+            "services:",
+            "- type: brooklyn.entity.basic.BasicEntity");
+
+        String versionedId = CatalogUtils.getVersionedId(symbolicName, TEST_VERSION);
+        try {
+            addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + symbolicName,
+                "  version: " + TEST_VERSION + "-update",
+                "",
+                "services:",
+                "- type: " + versionedId);
+            fail("Catalog addition expected to fail due to non-existent java type " + versionedId);
+        } catch (IllegalStateException e) {
+            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
+        }
+    }
+
+    @Test
+    public void testOsgiNotLeakingToParent() {
+        addCatalogOSGiEntity(SIMPLE_ENTITY_TYPE);
+        try {
+            addCatalogItems(
+                    "brooklyn.catalog:",
+                    "  id: " + SIMPLE_ENTITY_TYPE,
+                    "  version: " + TEST_VERSION + "-update",
+                    "",
+                    "services:",
+                    "- type: " + SIMPLE_ENTITY_TYPE);
+            fail("Catalog addition expected to fail due to non-existent java type " + SIMPLE_ENTITY_TYPE);
+        } catch (IllegalStateException e) {
+            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
+        }
+    }
+
+    @Test
+    public void testConfigAppliedToCatalogItem() throws Exception {
+        addCatalogOSGiEntity("test", TestEntity.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  brooklyn.config:",
+                "    test.confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+
+    @Test
+    public void testFlagsAppliesToCatalogItem() throws Exception {
+        addCatalogOSGiEntity("test", TestEntity.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+
+    @Test
+    public void testExplicitFlagsAppliesToCatalogItem() throws Exception {
+        addCatalogOSGiEntity("test", TestEntity.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  brooklyn.flags:",
+                "    confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+    
+
+    @Test
+    public void testConfigAppliedToCatalogItemImpl() throws Exception {
+        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  brooklyn.config:",
+                "    test.confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+
+    @Test
+    public void testFlagsAppliesToCatalogItemImpl() throws Exception {
+        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+
+    @Test
+    public void testExplicitFlagsAppliesToCatalogItemImpl() throws Exception {
+        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
+        String testName = "test-applies-config-on-catalog-item";
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + ver("test"),
+                "  brooklyn.flags:",
+                "    confName: " + testName);
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
+    }
+    
+    private void registerAndLaunchAndAssertSimpleEntity(String symbolicName, String serviceType) throws Exception {
+        addCatalogOSGiEntity(symbolicName, serviceType);
+        String yaml = "name: simple-app-yaml\n" +
+                      "location: localhost\n" +
+                      "services: \n" +
+                      "  - serviceType: "+ver(symbolicName);
+        Entity app = createAndStartApplication(yaml);
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    private void addCatalogOSGiEntity(String symbolicName) {
+        addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE);
+    }
+
+    private void addCatalogOSGiEntity(String symbolicName, String serviceType) {
+        addCatalogOSGiEntity(symbolicName, serviceType, false);
+    }
+    
+    private void addCatalogOSGiEntity(String symbolicName, String serviceType, boolean extraLib) {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL +
+            (extraLib ? "\n"+"  - url: "+OsgiStandaloneTest.BROOKLYN_OSGI_TEST_A_0_1_0_URL : ""),
+            "  item:",
+            "    type: " + serviceType);
+    }
+
+    private void addCatalogOSGiEntities(String ...namesAndTypes) {
+        List<String> lines = MutableList.of(
+            "brooklyn.catalog:",
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  items:");
+        
+        for (int i=0; i<namesAndTypes.length; i+=2) {
+            lines.addAll(MutableList.of(
+            "  - id: " + namesAndTypes[i],
+            "    item:",
+            "      type: " + namesAndTypes[i+1]));
+        }
+            
+        addCatalogItems(lines);
+    }
+    private void addCatalogChildOSGiEntityWithServicesBlock(String symbolicName, String serviceType) {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item:",
+            "    services:",
+            "    - type: " + BasicEntity.class.getName(),
+            "      brooklyn.children:",
+            "      - type: " + serviceType);
+    }
+    private void addCatalogChildOSGiEntity(String symbolicName, String serviceType) {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item:",
+            "    type: " + BasicEntity.class.getName(),
+            "    brooklyn.children:",
+            "    - type: " + serviceType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
new file mode 100644
index 0000000..b46ed92
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.CatalogItem;
+import org.apache.brooklyn.catalog.CatalogItem.CatalogBundle;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.Entity;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.location.Location;
+import brooklyn.location.LocationDefinition;
+import brooklyn.location.LocationSpec;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+import brooklyn.util.text.StringFunctions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class CatalogYamlLocationTest extends AbstractYamlTest {
+    private static final String LOCALHOST_LOCATION_SPEC = "localhost";
+    private static final String LOCALHOST_LOCATION_TYPE = LocalhostMachineProvisioningLocation.class.getName();
+    private static final String SIMPLE_LOCATION_TYPE = "brooklyn.osgi.tests.SimpleLocation";
+
+    @AfterMethod
+    public void tearDown() {
+        for (CatalogItem<Location, LocationSpec<?>> ci : mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) {
+            mgmt().getCatalog().deleteCatalogItem(ci.getSymbolicName(), ci.getVersion());
+        }
+    }
+    
+    @Test
+    public void testAddCatalogItem() throws Exception {
+        assertEquals(countCatalogLocations(), 0);
+
+        String symbolicName = "my.catalog.location.id.load";
+        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null);
+        assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE);
+        removeAndAssert(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemOsgi() throws Exception {
+        assertEquals(countCatalogLocations(), 0);
+
+        String symbolicName = "my.catalog.location.id.load";
+        addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
+        assertAdded(symbolicName, SIMPLE_LOCATION_TYPE);
+        assertOsgi(symbolicName);
+        removeAndAssert(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemTopLevelItemSyntax() throws Exception {
+        assertEquals(countCatalogLocations(), 0);
+
+        String symbolicName = "my.catalog.location.id.load";
+        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null);
+        assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE);
+        removeAndAssert(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemOsgiTopLevelItemSyntax() throws Exception {
+        assertEquals(countCatalogLocations(), 0);
+
+        String symbolicName = "my.catalog.location.id.load";
+        addCatalogLocationTopLevelItemSyntax(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
+        assertAdded(symbolicName, SIMPLE_LOCATION_TYPE);
+        assertOsgi(symbolicName);
+        removeAndAssert(symbolicName);
+    }
+
+    private void assertOsgi(String symbolicName) {
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        Collection<CatalogBundle> libs = item.getLibraries();
+        assertEquals(libs.size(), 1);
+        assertEquals(Iterables.getOnlyElement(libs).getUrl(), Iterables.getOnlyElement(getOsgiLibraries()));
+    }
+
+    private void assertAdded(String symbolicName, String expectedJavaType) {
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+        assertEquals(countCatalogLocations(), 1);
+
+        // Item added to catalog should automatically be available in location registry
+        LocationDefinition def = mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName);
+        assertEquals(def.getId(), symbolicName);
+        assertEquals(def.getName(), symbolicName);
+        
+        LocationSpec<?> spec = (LocationSpec<?>)mgmt().getCatalog().createSpec(item);
+        assertEquals(spec.getType().getName(), expectedJavaType);
+    }
+    
+    private void removeAndAssert(String symbolicName) {
+        // Deleting item: should be gone from catalog, and from location registry
+        deleteCatalogEntity(symbolicName);
+
+        assertEquals(countCatalogLocations(), 0);
+        assertNull(mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName));
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingLocationClass() throws Exception {
+        String symbolicName = "my.catalog.location.id.launch";
+        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null);
+        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingLocationSpec() throws Exception {
+        String symbolicName = "my.catalog.location.id.launch";
+        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_SPEC, null);
+        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingLocationClassTopLevelItemSyntax() throws Exception {
+        String symbolicName = "my.catalog.location.id.launch";
+        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null);
+        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingLocationSpecTopLevelSyntax() throws Exception {
+        String symbolicName = "my.catalog.location.id.launch";
+        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_SPEC, null);
+        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingOsgiLocation() throws Exception {
+        String symbolicName = "my.catalog.location.id.launch";
+        addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
+        runLaunchApplicationReferencingLocation(symbolicName, SIMPLE_LOCATION_TYPE);
+        
+        deleteCatalogEntity(symbolicName);
+    }
+    
+    protected void runLaunchApplicationReferencingLocation(String locTypeInYaml, String locType) throws Exception {
+        Entity app = createAndStartApplication(
+            "name: simple-app-yaml",
+            "location: ",
+            "  "+locTypeInYaml+":",
+            "    config2: config2 override",
+            "    config3: config3",
+            "services: ",
+            "  - type: brooklyn.entity.basic.BasicStartable");
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        Location location = Iterables.getOnlyElement(simpleEntity.getLocations());
+        assertEquals(location.getClass().getName(), locType);
+        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
+        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
+        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
+    }
+
+    private List<String> getOsgiLibraries() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        return ImmutableList.of(OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL);
+    }
+    
+    private void addCatalogLocation(String symbolicName, String locationType, List<String> libraries) {
+        ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
+                "brooklyn.catalog:",
+                "  id: " + symbolicName,
+                "  name: My Catalog Location",
+                "  description: My description",
+                "  version: " + TEST_VERSION);
+        if (libraries!=null && libraries.size() > 0) {
+            yaml.add("  libraries:")
+                .addAll(Lists.transform(libraries, StringFunctions.prepend("  - url: ")));
+        }
+        yaml.add(
+                "  item.type: location",
+                "  item:",
+                "    type: " + locationType,
+                "    brooklyn.config:",
+                "      config1: config1",
+                "      config2: config2");
+        
+        
+        addCatalogItems(yaml.build());
+    }
+
+    private void addCatalogLocationTopLevelItemSyntax(String symbolicName, String locationType, List<String> libraries) {
+        ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
+                "brooklyn.catalog:",
+                "  id: " + symbolicName,
+                "  name: My Catalog Location",
+                "  description: My description",
+                "  version: " + TEST_VERSION);
+        if (libraries!=null && libraries.size() > 0) {
+            yaml.add("  libraries:")
+                .addAll(Lists.transform(libraries, StringFunctions.prepend("  - url: ")));
+        }
+        yaml.add(
+                "",
+                "brooklyn.locations:",
+                "- type: " + locationType,
+                "  brooklyn.config:",
+                "    config1: config1",
+                "    config2: config2");
+        
+        
+        addCatalogItems(yaml.build());
+    }
+
+    private int countCatalogLocations() {
+        return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
new file mode 100644
index 0000000..ab738b6
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.Entity;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+import brooklyn.policy.Policy;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+
+import com.google.common.collect.Iterables;
+
+public class CatalogYamlPolicyTest extends AbstractYamlTest {
+    private static final String SIMPLE_POLICY_TYPE = "brooklyn.osgi.tests.SimplePolicy";
+    private static final String SIMPLE_ENTITY_TYPE = "brooklyn.osgi.tests.SimpleEntity";
+
+    @Test
+    public void testAddCatalogItem() throws Exception {
+        assertEquals(countCatalogPolicies(), 0);
+
+        String symbolicName = "my.catalog.policy.id.load";
+        addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+        assertEquals(countCatalogPolicies(), 1);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testAddCatalogItemTopLevelSyntax() throws Exception {
+        assertEquals(countCatalogPolicies(), 0);
+
+        String symbolicName = "my.catalog.policy.id.load";
+        addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+        assertEquals(countCatalogPolicies(), 1);
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingPolicy() throws Exception {
+        String symbolicName = "my.catalog.policy.id.launch";
+        addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE);
+        Entity app = createAndStartApplication(
+            "name: simple-app-yaml",
+            "location: localhost",
+            "services: ",
+            "  - type: brooklyn.entity.basic.BasicEntity\n" +
+            "    brooklyn.policies:\n" +
+            "    - type: " + ver(symbolicName),
+            "      brooklyn.config:",
+            "        config2: config2 override",
+            "        config3: config3");
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
+        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
+
+        deleteCatalogEntity(symbolicName);
+    }
+
+    @Test
+    public void testLaunchApplicationReferencingPolicyTopLevelSyntax() throws Exception {
+        String symbolicName = "my.catalog.policy.id.launch";
+        addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE);
+        Entity app = createAndStartApplication(
+            "name: simple-app-yaml",
+            "location: localhost",
+            "services: ",
+            "  - type: brooklyn.entity.basic.BasicEntity\n" +
+            "    brooklyn.policies:\n" +
+            "    - type: " + ver(symbolicName),
+            "      brooklyn.config:",
+            "        config2: config2 override",
+            "        config3: config3");
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
+        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
+        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
+
+        deleteCatalogEntity(symbolicName);
+    }
+    
+    @Test
+    public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception {
+        String referencedSymbolicName = "my.catalog.policy.id.referenced";
+        String referrerSymbolicName = "my.catalog.policy.id.referring";
+        addCatalogOsgiPolicy(referencedSymbolicName, SIMPLE_POLICY_TYPE);
+
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + referrerSymbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "services:",
+            "- type: " + SIMPLE_ENTITY_TYPE,
+            "  brooklyn.policies:",
+            "  - type: " + ver(referencedSymbolicName));
+
+        String yaml = "name: simple-app-yaml\n" +
+                      "location: localhost\n" +
+                      "services: \n" +
+                      "- type: "+ ver(referrerSymbolicName);
+
+        Entity app = createAndStartApplication(yaml);
+
+        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
+        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
+        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
+
+        deleteCatalogEntity(referencedSymbolicName);
+    }
+
+    private void addCatalogOsgiPolicy(String symbolicName, String policyType) {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog Policy",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item:",
+            "    type: " + policyType,
+            "    brooklyn.config:",
+            "      config1: config1",
+            "      config2: config2");
+    }
+
+    private void addCatalogOsgiPolicyTopLevelSyntax(String symbolicName, String policyType) {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog Policy",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "brooklyn.policies:",
+            "- type: " + policyType,
+            "  brooklyn.config:",
+            "    config1: config1",
+            "    config2: config2");
+    }
+
+    private int countCatalogPolicies() {
+        return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_POLICY));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
new file mode 100644
index 0000000..29a1227
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlRebindTest;
+import org.testng.annotations.Test;
+
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.internal.BrooklynFeatureEnablement;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.Policy;
+import brooklyn.test.policy.TestEnricher;
+import brooklyn.test.policy.TestPolicy;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
+
+    // TODO Other tests (relating to https://issues.apache.org/jira/browse/BROOKLYN-149) include:
+    //   - entities cannot be instantiated because class no longer on classpath (e.g. was OSGi)
+    //   - config/attribute cannot be instantiated (e.g. because class no longer on classpath)
+    //   - entity file corrupt
+    
+    enum RebindWithCatalogTestMode {
+        NO_OP,
+        DELETE_CATALOG,
+        REPLACE_CATALOG_WITH_NEWER_VERSION;
+    }
+    
+    @Test
+    public void testRebindWithCatalogAndApp() throws Exception {
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.NO_OP);
+    }
+    
+    // See https://issues.apache.org/jira/browse/BROOKLYN-149.
+    // Deletes the catalog item before rebind, but the referenced types are still on the 
+    // default classpath.
+    // Will fallback to loading from classpath.
+    @Test
+    public void testRebindWithCatalogDeletedAndAppExisting() throws Exception {
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DELETE_CATALOG);
+    }
+    
+    // Upgrades the catalog item before rebind, deleting the old version.
+    // Will automatically upgrade.
+    @Test
+    public void testRebindWithCatalogUpgradedWithOldDeletedAndAppExisting() throws Exception {
+        BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND);
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.REPLACE_CATALOG_WITH_NEWER_VERSION);
+    }
+    
+    @SuppressWarnings("unused")
+    protected void runRebindWithCatalogAndApp(RebindWithCatalogTestMode mode) throws Exception {
+        String symbolicName = "my.catalog.app.id.load";
+        String version = "0.1.2";
+        String catalogFormat = Joiner.on("\n").join(
+                "brooklyn.catalog:",
+                "  id: " + symbolicName,
+                "  version: %s",
+                "  item:",
+                "    type: "+ BasicEntity.class.getName(),
+                "    brooklyn.enrichers:",
+                "    - type: "+TestEnricher.class.getName(),
+                "    brooklyn.policies:",
+                "    - type: "+TestPolicy.class.getName());
+        
+        // Create the catalog item
+        addCatalogItems(String.format(catalogFormat, version));
+
+        // Create an app, using that catalog item
+        String yaml = "name: simple-app-yaml\n" +
+                "location: localhost\n" +
+                "services: \n" +
+                "- type: "+CatalogUtils.getVersionedId(symbolicName, version);
+        origApp = (StartableApplication) createAndStartApplication(yaml);
+        BasicEntity origEntity = (BasicEntity) Iterables.getOnlyElement(origApp.getChildren());
+        TestPolicy origPolicy = (TestPolicy) Iterables.getOnlyElement(origEntity.getPolicies());
+        TestEnricher origEnricher = (TestEnricher) Iterables.tryFind(origEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
+        assertEquals(origEntity.getCatalogItemId(), symbolicName+":"+version);
+
+        // Depending on test-mode, delete the catalog item, and then rebind
+        switch (mode) {
+            case DELETE_CATALOG:
+                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
+                break;
+            case REPLACE_CATALOG_WITH_NEWER_VERSION:
+                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
+                version = "0.1.3";
+                addCatalogItems(String.format(catalogFormat, version));
+                break;
+            case NO_OP:
+                // no-op
+        }
+        
+        rebind();
+
+        // Ensure app is still there
+        BasicEntity newEntity = (BasicEntity) Iterables.getOnlyElement(newApp.getChildren());
+        Policy newPolicy = Iterables.getOnlyElement(newEntity.getPolicies());
+        Enricher newEnricher = Iterables.tryFind(newEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
+        assertEquals(newEntity.getCatalogItemId(), symbolicName+":"+version);
+
+        // Ensure app is still usable - e.g. "stop" effector functions as expected
+        newApp.stop();
+        assertFalse(Entities.isManaged(newApp));
+        assertFalse(Entities.isManaged(newEntity));
+    }
+}



[08/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
new file mode 100644
index 0000000..6f79471
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.StringReader;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.location.Location;
+import brooklyn.location.MachineLocation;
+import brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.location.basic.MultiLocation;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.text.Strings;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class LocationsYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(LocationsYamlTest.class);
+
+    @Test
+    public void testLocationString() throws Exception {
+        String yaml = 
+                "location: localhost\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
+        assertNotNull(loc);
+    }
+
+    @Test
+    public void testLocationComplexString() throws Exception {
+        String yaml = 
+                "location: localhost:(name=myname)\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
+        assertEquals(loc.getDisplayName(), "myname");
+    }
+
+    @Test
+    public void testLocationSplitLineWithNoConfig() throws Exception {
+        String yaml = 
+                "location:\n"+
+                "  localhost\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
+        assertNotNull(loc);
+    }
+
+    @Test
+    public void testMultiLocations() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- localhost:(name=loc1)\n"+
+                "- localhost:(name=loc2)\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        List<Location> locs = ImmutableList.copyOf(app.getLocations());
+        assertEquals(locs.size(), 2, "locs="+locs);
+        LocalhostMachineProvisioningLocation loc1 = (LocalhostMachineProvisioningLocation) locs.get(0);
+        LocalhostMachineProvisioningLocation loc2 = (LocalhostMachineProvisioningLocation) locs.get(1);
+        assertEquals(loc1.getDisplayName(), "loc1");
+        assertEquals(loc2.getDisplayName(), "loc2");
+    }
+
+    @Test
+    public void testLocationConfig() throws Exception {
+        String yaml = 
+                "location:\n"+
+                "  localhost:\n"+
+                "    displayName: myname\n"+
+                "    myconfkey: myconfval\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
+        assertEquals(loc.getDisplayName(), "myname");
+        assertEquals(loc.config().getLocalBag().getStringKey("myconfkey"), "myconfval");
+    }
+
+    @Test
+    public void testMultiLocationConfig() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- localhost:\n"+
+                "    displayName: myname1\n"+
+                "    myconfkey: myconfval1\n"+
+                "- localhost:\n"+
+                "    displayName: myname2\n"+
+                "    myconfkey: myconfval2\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        List<Location> locs = ImmutableList.copyOf(app.getLocations());
+        assertEquals(locs.size(), 2, "locs="+locs);
+        LocalhostMachineProvisioningLocation loc1 = (LocalhostMachineProvisioningLocation) locs.get(0);
+        LocalhostMachineProvisioningLocation loc2 = (LocalhostMachineProvisioningLocation) locs.get(1);
+        assertEquals(loc1.getDisplayName(), "myname1");
+        assertEquals(loc1.config().getLocalBag().getStringKey("myconfkey"), "myconfval1");
+        assertEquals(loc2.getDisplayName(), "myname2");
+        assertEquals(loc2.config().getLocalBag().getStringKey("myconfkey"), "myconfval2");
+    }
+
+    // TODO Fails because PlanInterpretationContext constructor throws NPE on location's value (using ImmutableMap).
+    @Test(groups="WIP")
+    public void testLocationBlank() throws Exception {
+        String yaml = 
+                "location: \n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        assertTrue(app.getLocations().isEmpty(), "locs="+app.getLocations());
+    }
+
+    @Test
+    public void testInvalidLocationAndLocations() throws Exception {
+        String yaml = 
+                "location: localhost\n"+
+                "locations:\n"+
+                "- localhost\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        try {
+            createStartWaitAndLogApplication(new StringReader(yaml));
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("Conflicting 'location' and 'locations'")) throw e;
+        }
+    }
+
+    @Test
+    public void testInvalidLocationList() throws Exception {
+        // should have used "locations:" instead of "location:"
+        String yaml = 
+                "location:\n"+
+                "- localhost\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        try {
+            createStartWaitAndLogApplication(new StringReader(yaml));
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("must be a string or map")) throw e;
+        }
+    }
+    
+    @Test
+    public void testRootLocationPassedToChild() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- localhost:(name=loc1)\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(child.getLocations());
+        assertEquals(loc.getDisplayName(), "loc1");
+    }
+
+    @Test
+    public void testByonYamlHosts() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- byon:\n"+
+                "    user: root\n"+
+                "    privateKeyFile: /tmp/key_file\n"+
+                "    hosts: \n"+
+                "    - 127.0.0.1\n"+
+                "    - brooklyn@127.0.0.2\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        FixedListMachineProvisioningLocation<?> loc = (FixedListMachineProvisioningLocation<?>) Iterables.getOnlyElement(child.getLocations());
+        Assert.assertEquals(loc.getChildren().size(), 2);
+        
+        SshMachineLocation l1 = (SshMachineLocation)loc.obtain();
+        assertUserAddress(l1, "root", "127.0.0.1");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.2");
+        Assert.assertEquals(l1.getConfig(SshMachineLocation.PRIVATE_KEY_FILE), "/tmp/key_file");
+    }
+
+    @Test
+    public void testByonYamlHostsString() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- byon:\n"+
+                "    user: root\n"+
+                "    hosts: \"{127.0.{0,127}.{1-2},brooklyn@127.0.0.127}\"\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        FixedListMachineProvisioningLocation<?> loc = (FixedListMachineProvisioningLocation<?>) Iterables.getOnlyElement(child.getLocations());
+        Assert.assertEquals(loc.getChildren().size(), 5);
+        
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.1");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.2");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.1");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.2");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.127");
+    }
+
+    @Test
+    public void testMultiByonYaml() throws Exception {
+        String yaml = 
+                "locations:\n"+
+                "- multi:\n"+
+                "   targets:\n"+
+                "   - byon:\n"+
+                "      user: root\n"+
+                "      hosts: 127.0.{0,127}.{1-2}\n"+
+                "   - byon:\n"+
+                "      user: brooklyn\n"+
+                "      hosts:\n"+
+                "      - 127.0.0.127\n"+
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n";
+        
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        MultiLocation<?> loc = (MultiLocation<?>) Iterables.getOnlyElement(child.getLocations());
+        Assert.assertEquals(loc.getSubLocations().size(), 2);
+        
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.1");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.2");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.1");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.2");
+        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.127");
+    }
+
+    public static void assertUserAddress(MachineLocation l, String user, String address) {
+        Assert.assertEquals(l.getAddress().getHostAddress(), address);
+        if (!Strings.isBlank(user)) Assert.assertEquals(((SshMachineLocation)l).getUser(), user);        
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/MapReferenceYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
new file mode 100644
index 0000000..bd000e9
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/MapReferenceYamlTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxy.ProxySslConfig;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.task.Tasks;
+
+import com.google.common.collect.Iterables;
+
+@Test
+public class MapReferenceYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(MapReferenceYamlTest.class);
+
+    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-reference-map-template.yaml", extras));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-reference-map-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertEquals(Iterables.size(app.getChildren()), 3, "Expected app to have child entity");
+        Iterable<BasicEntity> basicEntities = Iterables.filter(app.getChildren(), BasicEntity.class);
+        Iterable<TestEntity> testEntities = Iterables.filter(app.getChildren(), TestEntity.class);
+        Assert.assertEquals(Iterables.size(basicEntities), 2, "Expected app to have two basic entities");
+        Assert.assertEquals(Iterables.size(testEntities), 1, "Expected app to have one test entity");
+
+        return Iterables.getOnlyElement(testEntities);
+    }
+
+    @Test
+    public void testSingleEntity() throws Exception {
+        setupAndCheckTestEntityInBasicYamlWith();
+    }
+
+    @Test
+    public void testBrooklynConfigWithMapFunction() throws Exception {
+        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confMapThing.obj:",
+            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
+            "      object:",
+            "        $brooklyn:object:",
+            "          type: brooklyn.entity.proxy.ProxySslConfig",
+            "      one: $brooklyn:entity(\"one\")",
+            "      two: $brooklyn:entity(\"two\")");
+
+        Map<?,?> testMap = (Map<?,?>) Entities.submit(testEntity, Tasks.builder().body(new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                return testEntity.getConfig(TestEntity.CONF_MAP_THING_OBJECT);
+            }
+        }).build()).get();
+        Object frog = testMap.get("frog");
+        Object one = testMap.get("one");
+        Object two = testMap.get("two");
+        Object object = testMap.get("object");
+
+        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
+        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
+        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig: " + object);
+        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: " + one);
+        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: " + two);
+    }
+
+    @Test
+    public void testBrooklynConfigWithPlainMapFunction() throws Exception {
+        final Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confMapPlain:",
+            "      frog: $brooklyn:formatString(\"%s\", \"frog\")",
+            "      object:",
+            "        $brooklyn:object:",
+            "          type: brooklyn.entity.proxy.ProxySslConfig",
+            "      one: $brooklyn:entity(\"one\")",
+            "      two: $brooklyn:entity(\"two\")");
+
+        Map<?,?> testMap = (Map<?,?>) Entities.submit(testEntity, Tasks.builder().body(new Callable<Object>() {
+            @Override
+            public Object call() throws Exception {
+                return testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
+            }
+        }).build()).get();
+        Object frog = testMap.get("frog");
+        Object one = testMap.get("one");
+        Object two = testMap.get("two");
+        Object object = testMap.get("object");
+
+        Assert.assertTrue(frog instanceof String, "Should have found a String: " + frog);
+        Assert.assertEquals(frog, "frog", "Should have found a formatted String: " + frog);
+        Assert.assertTrue(object instanceof ProxySslConfig, "Should have found a ProxySslConfig: " + object);
+        Assert.assertTrue(one instanceof BasicEntity, "Should have found a BasicEntity: " + one);
+        Assert.assertTrue(two instanceof BasicEntity, "Should have found a BasicEntity: " + two);
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
new file mode 100644
index 0000000..174b5bf
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
@@ -0,0 +1,280 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxy.ProxySslConfig;
+import brooklyn.entity.trait.Configurable;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ManagementContextInjectable;
+import brooklyn.management.Task;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.flags.TypeCoercions;
+
+import com.google.common.collect.Lists;
+
+@Test
+public class ObjectsYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(ObjectsYamlTest.class);
+
+    private static final AtomicBoolean managementContextInjected = new AtomicBoolean(false);
+    private static final List<String> configKeys = Lists.newLinkedList();
+
+    public static class TestObject implements ManagementContextInjectable {
+        private String string;
+        private Integer number;
+        private Object object;
+
+        public TestObject() { }
+
+        public String getString() { return string; }
+        public void setString(String string) { this.string = string; }
+
+        public Integer getNumber() { return number; }
+        public void setNumber(Integer number) { this.number = number; }
+
+        public Object getObject() { return object; }
+        public void setObject(Object object) { this.object = object; }
+
+        @Override
+        public void injectManagementContext(ManagementContext managementContext) {
+            log.info("Detected injection of {}", managementContext);
+            managementContextInjected.set(true);
+        }
+    }
+
+    public static class ConfigurableObject implements Configurable {
+        public static final ConfigKey<Integer> INTEGER = ConfigKeys.newIntegerConfigKey("config.number");
+        @SetFromFlag("object")
+        public static final ConfigKey<Object> OBJECT = ConfigKeys.newConfigKey(Object.class, "config.object");
+
+        @SetFromFlag("flag")
+        private String string;
+
+        private Integer number;
+        private Object object;
+        private Double value;
+        BasicConfigurationSupport configSupport = new BasicConfigurationSupport();
+        
+        public ConfigurableObject() { }
+
+        public String getString() { return string; }
+
+        public Integer getNumber() { return number; }
+
+        public Object getObject() { return object; }
+
+        public Double getDouble() { return value; }
+        public void setDouble(Double value) { this.value = value; }
+
+        @Override
+        public <T> T setConfig(ConfigKey<T> key, T value) {
+            return config().set(key, value);
+        }
+        
+        @Override
+        public ConfigurationSupport config() {
+            return configSupport;
+        }
+        
+        private class BasicConfigurationSupport implements ConfigurationSupport {
+            private final ConfigBag bag = new ConfigBag();
+            
+            @Override
+            public <T> T get(ConfigKey<T> key) {
+                return bag.get(key);
+            }
+
+            @Override
+            public <T> T get(HasConfigKey<T> key) {
+                return get(key.getConfigKey());
+            }
+
+            @Override
+            public <T> T set(ConfigKey<T> key, T val) {
+                log.info("Detected configuration injection for {}: {}", key.getName(), val);
+                configKeys.add(key.getName());
+                if ("config.number".equals(key.getName())) number = TypeCoercions.coerce(val, Integer.class);
+                if ("config.object".equals(key.getName())) object = val;
+                T old = bag.get(key);
+                bag.configure(key, val);
+                return old;
+            }
+
+            @Override
+            public <T> T set(HasConfigKey<T> key, T val) {
+                return set(key.getConfigKey(), val);
+            }
+
+            @Override
+            public <T> T set(ConfigKey<T> key, Task<T> val) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public <T> T set(HasConfigKey<T> key, Task<T> val) {
+                return set(key.getConfigKey(), val);
+            }
+        }
+    }
+
+    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
+        managementContextInjected.set(false);
+        configKeys.clear();
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+
+        return (TestEntity)entity;
+    }
+
+    @Test
+    public void testSingleEntity() throws Exception {
+        setupAndCheckTestEntityInBasicYamlWith();
+    }
+
+    @Test
+    public void testBrooklynObject() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        type: "+ObjectsYamlTest.class.getName()+"$TestObject",
+            "        object.fields:",
+            "          number: 7",
+            "          object:",
+            "            $brooklyn:object:",
+            "              type: brooklyn.entity.proxy.ProxySslConfig",
+            "          string: \"frog\"");
+
+        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
+
+        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
+        Assert.assertTrue(managementContextInjected.get());
+        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
+        Assert.assertEquals(((TestObject) testObject).getString(), "frog");
+
+        Object testObjectObject = ((TestObject) testObject).getObject();
+        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
+    }
+
+    @Test
+    public void testBrooklynConfigurableObject() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        type: "+ObjectsYamlTest.class.getName()+"$ConfigurableObject",
+            "        object.fields:",
+            "          double: 1.4",
+            "        brooklyn.config:",
+            "          flag: frog",
+            "          config.number: 7",
+            "          object:",
+            "            $brooklyn:object:",
+            "              type: brooklyn.entity.proxy.ProxySslConfig");
+
+        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
+
+        Assert.assertTrue(testObject instanceof ConfigurableObject, "Expected a ConfigurableObject: "+testObject);
+        Assert.assertEquals(((ConfigurableObject) testObject).getDouble(), Double.valueOf(1.4));
+        Assert.assertEquals(((ConfigurableObject) testObject).getString(), "frog");
+        Assert.assertEquals(((ConfigurableObject) testObject).getNumber(), Integer.valueOf(7));
+
+        Object testObjectObject = ((ConfigurableObject) testObject).getObject();
+        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
+
+        Assert.assertTrue(configKeys.contains(ConfigurableObject.INTEGER.getName()), "Expected INTEGER key: "+configKeys);
+        Assert.assertTrue(configKeys.contains(ConfigurableObject.OBJECT.getName()), "Expected OBJECT key: "+configKeys);
+    }
+
+    @Test
+    public void testBrooklynObjectPrefix() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confListPlain:",
+            "    - $brooklyn:object:",
+            "        objectType: brooklyn.entity.proxy.ProxySslConfig",
+            "    - $brooklyn:object:",
+            "        object_type: brooklyn.entity.proxy.ProxySslConfig",
+            "    - $brooklyn:object:",
+            "        type: brooklyn.entity.proxy.ProxySslConfig");
+
+        List<?> testList = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
+
+        Assert.assertEquals(testList.size(), 3);
+        for (Object entry : testList) {
+            Assert.assertTrue(entry instanceof ProxySslConfig, "Expected a ProxySslConfig: "+entry);
+        }
+    }
+
+    @Test
+    public void testBrooklynObjectWithFunction() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+            "  brooklyn.config:",
+            "    test.confObject:",
+            "      $brooklyn:object:",
+            "        type: "+ObjectsYamlTest.class.getName()+"$TestObject",
+            "        object.fields:",
+            "          number: 7",
+            "          object:",
+            "            $brooklyn:object:",
+            "              type: brooklyn.entity.proxy.ProxySslConfig",
+            "          string:",
+            "            $brooklyn:formatString(\"%s\", \"frog\")");
+
+        Object testObject = testEntity.getConfig(TestEntity.CONF_OBJECT);
+
+        Assert.assertTrue(testObject instanceof TestObject, "Expected a TestObject: "+testObject);
+        Assert.assertTrue(managementContextInjected.get());
+        Assert.assertEquals(((TestObject) testObject).getNumber(), Integer.valueOf(7));
+        Assert.assertEquals(((TestObject) testObject).getString(), "frog");
+
+        Object testObjectObject = ((TestObject) testObject).getObject();
+        Assert.assertTrue(testObjectObject instanceof ProxySslConfig, "Expected a ProxySslConfig: "+testObjectObject);
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/PoliciesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/PoliciesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/PoliciesYamlTest.java
new file mode 100644
index 0000000..241fefb
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/PoliciesYamlTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.policy.Policy;
+import brooklyn.test.Asserts;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.test.policy.TestPolicy;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+@Test
+public class PoliciesYamlTest extends AbstractYamlTest {
+    static final Logger log = LoggerFactory.getLogger(PoliciesYamlTest.class);
+
+    @Test
+    public void testWithAppPolicy() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-app-with-policy.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-app-with-policy");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertEquals(app.getPolicies().size(), 1);
+        Policy policy = app.getPolicies().iterator().next();
+        Assert.assertTrue(policy instanceof TestPolicy);
+        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_NAME), "Name from YAML");
+        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
+        Map<?, ?> leftoverProperties = ((TestPolicy) policy).getLeftoverProperties();
+        Assert.assertEquals(leftoverProperties.get("policyLiteralValue1"), "Hello");
+        Assert.assertEquals(leftoverProperties.get("policyLiteralValue2"), "World");
+        Assert.assertEquals(leftoverProperties.size(), 2);
+    }
+    
+    @Test
+    public void testWithEntityPolicy() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-with-policy.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-entity-with-policy");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertEquals(app.getPolicies().size(), 0);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity child = app.getChildren().iterator().next();
+        Assert.assertEquals(child.getPolicies().size(), 1);
+        Policy policy = child.getPolicies().iterator().next();
+        Assert.assertNotNull(policy);
+        Assert.assertTrue(policy instanceof TestPolicy, "policy=" + policy + "; type=" + policy.getClass());
+        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_NAME), "Name from YAML");
+        Assert.assertEquals(policy.getConfig(TestPolicy.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
+        Assert.assertEquals(((TestPolicy) policy).getLeftoverProperties(),
+                ImmutableMap.of("policyLiteralValue1", "Hello", "policyLiteralValue2", "World"));
+        Assert.assertEquals(policy.getConfig(TestPolicy.TEST_ATTRIBUTE_SENSOR), TestEntity.NAME);
+    }
+    
+    @Test
+    public void testChildWithPolicy() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
+                    "  brooklyn.config:",
+                    "    test.confName: parent entity",
+                    "  brooklyn.children:",
+                    "  - serviceType: brooklyn.test.entity.TestEntity",
+                    "    name: Child Entity",
+                    "    brooklyn.policies:",
+                    "    - policyType: brooklyn.test.policy.TestPolicy",
+                    "      brooklyn.config:",
+                    "        test.confName: Name from YAML",
+                    "        test.attributeSensor: $brooklyn:sensor(\"brooklyn.test.entity.TestEntity\", \"test.name\")"));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity firstEntity = app.getChildren().iterator().next();
+        Assert.assertEquals(firstEntity.getChildren().size(), 1);
+        final Entity child = firstEntity.getChildren().iterator().next();
+        Assert.assertEquals(child.getChildren().size(), 0);
+
+        Assert.assertEquals(app.getPolicies().size(), 0);
+        Assert.assertEquals(firstEntity.getPolicies().size(), 0);
+        
+        Asserts.eventually(new Supplier<Integer>() {
+            @Override
+            public Integer get() {
+                return child.getPolicies().size();
+            }
+        }, Predicates.<Integer> equalTo(1));
+        
+        Policy policy = child.getPolicies().iterator().next();
+        Assert.assertTrue(policy instanceof TestPolicy);
+        Assert.assertEquals(policy.getConfig(TestPolicy.TEST_ATTRIBUTE_SENSOR), TestEntity.NAME);
+    }
+    
+    @Test
+    public void testMultiplePolicyReferences() throws Exception {
+        final Entity app = createAndStartApplication(loadYaml("test-referencing-policies.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-referencing-policies");
+        
+        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
+        
+        Assert.assertEquals(app.getChildren().size(), 2);
+        for (Entity child : app.getChildren()) {
+            if (child.getDisplayName().equals("entity 1"))
+                entity1 = child;
+            if (child.getDisplayName().equals("entity 2"))
+                entity2 = child;
+        }
+        Assert.assertNotNull(entity1);
+        Assert.assertNotNull(entity2);
+        
+        Assert.assertEquals(entity1.getChildren().size(), 2);
+        for (Entity child : entity1.getChildren()) {
+            if (child.getDisplayName().equals("child 1"))
+                child1 = child;
+            if (child.getDisplayName().equals("child 2"))
+                child2 = child;
+        }
+        Assert.assertNotNull(child1);
+        Assert.assertNotNull(child2);
+        
+        Assert.assertEquals(child1.getChildren().size(), 2);
+        for (Entity child : child1.getChildren()) {
+            if (child.getDisplayName().equals("grandchild 1"))
+               grandchild1 = child;
+            if (child.getDisplayName().equals("grandchild 2"))
+                grandchild2 = child;
+        }
+        Assert.assertNotNull(grandchild1);
+        Assert.assertNotNull(grandchild2);
+        
+        ImmutableSet<Policy> policies = new ImmutableSet.Builder<Policy>()
+                .add(getPolicy(app))
+                .add(getPolicy(entity1))
+                .add(getPolicy(entity2))
+                .add(getPolicy(child1))
+                .add(getPolicy(child2))
+                .add(getPolicy(grandchild1))
+                .add(getPolicy(grandchild2))
+                .build();
+        
+        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY2, entity2)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD1, child1)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD2, child2)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD1, grandchild1)
+                .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD2, grandchild2)
+                .build();
+        
+        for (Policy policy : policies)
+            checkReferences(policy, keyToEntity);
+        
+    }
+    
+    private void checkReferences(final Policy policy, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
+        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
+            final Entity entity = keyToEntity.get(key); // Grab an entity whose execution context we can use
+            Entity fromConfig = ((EntityInternal)entity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
+                @Override
+                public Entity call() throws Exception {
+                    return (Entity) policy.getConfig(key);
+                }
+            }).get();
+            Assert.assertEquals(fromConfig, keyToEntity.get(key));
+        }
+    }
+    
+    private Policy getPolicy(Entity entity) {
+        Assert.assertEquals(entity.getPolicies().size(), 1);
+        Policy policy = entity.getPolicies().iterator().next();
+        Assert.assertTrue(policy instanceof TestReferencingPolicy);
+        return policy;
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencedYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencedYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencedYamlTest.java
new file mode 100644
index 0000000..1d1997e
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencedYamlTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+
+import com.google.common.collect.Iterables;
+
+public class ReferencedYamlTest extends AbstractYamlTest {
+    
+    @Test
+    public void testReferenceEntityYamlAsPlatformComponent() throws Exception {
+        String entityName = "Reference child name";
+        Entity app = createAndStartApplication(
+            "services:",
+            "- name: " + entityName,
+            "  type: classpath://yaml-ref-entity.yaml");
+        
+        checkChildEntitySpec(app, entityName);
+    }
+
+    @Test
+    public void testAnonymousReferenceEntityYamlAsPlatformComponent() throws Exception {
+        Entity app = createAndStartApplication(
+            "services:",
+            "- type: classpath://yaml-ref-entity.yaml");
+        
+        checkChildEntitySpec(app, "service");
+    }
+
+    @Test
+    public void testReferenceAppYamlAsPlatformComponent() throws Exception {
+        Entity app = createAndStartApplication(
+            "services:",
+            "- name: Reference child name",
+            "  type: classpath://yaml-ref-app.yaml");
+        
+        Assert.assertEquals(app.getChildren().size(), 0);
+        Assert.assertEquals(app.getDisplayName(), "Reference child name");
+
+        //child is a proxy so equality test won't do
+        Assert.assertEquals(app.getEntityType().getName(), BasicApplication.class.getName());
+    }
+
+    @Test
+    public void testReferenceYamlAsChild() throws Exception {
+        String entityName = "Reference child name";
+        Entity createAndStartApplication = createAndStartApplication(
+            "services:",
+            "- type: brooklyn.entity.basic.BasicEntity",
+            "  brooklyn.children:",
+            "  - name: " + entityName,
+            "    type: classpath://yaml-ref-entity.yaml");
+        
+        checkGrandchildEntitySpec(createAndStartApplication, entityName);
+    }
+
+    @Test
+    public void testAnonymousReferenceYamlAsChild() throws Exception {
+        Entity createAndStartApplication = createAndStartApplication(
+            "services:",
+            "- type: brooklyn.entity.basic.BasicEntity",
+            "  brooklyn.children:",
+            "  - type: classpath://yaml-ref-entity.yaml");
+        
+        checkGrandchildEntitySpec(createAndStartApplication, "service");
+    }
+
+    @Test
+    public void testCatalogReferencingYamlUrl() throws Exception {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: yaml.reference",
+            "  version: " + TEST_VERSION,
+            "services:",
+            "- type: classpath://yaml-ref-entity.yaml");
+        
+        String entityName = "YAML -> catalog item -> yaml url";
+        Entity app = createAndStartApplication(
+            "services:",
+            "- name: " + entityName,
+            "  type: " + ver("yaml.reference"));
+        
+        checkChildEntitySpec(app, entityName);
+    }
+
+    @Test
+    public void testYamlUrlReferencingCatalog() throws Exception {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: yaml.basic",
+            "  version: " + TEST_VERSION,
+            "services:",
+            "- type: brooklyn.entity.basic.BasicEntity");
+        
+        String entityName = "YAML -> yaml url -> catalog item";
+        Entity app = createAndStartApplication(
+            "services:",
+            "- name: " + entityName,
+            "  type: classpath://yaml-ref-catalog.yaml");
+        
+        checkChildEntitySpec(app, entityName);
+    }
+
+    /**
+     * Tests that a YAML referenced by URL from a catalog item
+     * will have access to the catalog item's bundles.
+     */
+    @Test
+    public void testCatalogLeaksBundlesToReferencedYaml() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String parentCatalogId = "my.catalog.app.id.url.parent";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + parentCatalogId,
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "",
+            "services:",
+            "- type: classpath://yaml-ref-bundle-without-libraries.yaml");
+
+        Entity app = createAndStartApplication(
+            "services:",
+                "- type: " + ver(parentCatalogId));
+        
+        Collection<Entity> children = app.getChildren();
+        Assert.assertEquals(children.size(), 1);
+        Entity child = Iterables.getOnlyElement(children);
+        Assert.assertEquals(child.getEntityType().getName(), "brooklyn.osgi.tests.SimpleEntity");
+
+        deleteCatalogEntity(parentCatalogId);
+    }
+
+    private void checkChildEntitySpec(Entity app, String entityName) {
+        Collection<Entity> children = app.getChildren();
+        Assert.assertEquals(children.size(), 1);
+        Entity child = Iterables.getOnlyElement(children);
+        Assert.assertEquals(child.getDisplayName(), entityName);
+        Assert.assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
+    }
+
+    private void checkGrandchildEntitySpec(Entity createAndStartApplication, String entityName) {
+        Collection<Entity> children = createAndStartApplication.getChildren();
+        Assert.assertEquals(children.size(), 1);
+        Entity child = Iterables.getOnlyElement(children);
+        Collection<Entity> grandChildren = child.getChildren();
+        Assert.assertEquals(grandChildren.size(), 1);
+        Entity grandChild = Iterables.getOnlyElement(grandChildren);
+        Assert.assertEquals(grandChild.getDisplayName(), entityName);
+        Assert.assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
new file mode 100644
index 0000000..bab503d
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.event.basic.BasicConfigKey;
+
+import com.google.common.reflect.TypeToken;
+
+@ImplementedBy(ReferencingYamlTestEntityImpl.class)
+public interface ReferencingYamlTestEntity extends Entity {
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_APP = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.app")
+            .build();
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.entity1")
+            .build();    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY1_ALT = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.entity1a")
+            .build();    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_ENTITY2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.entity2")
+            .build();
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_CHILD1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.child1")
+            .build();
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_CHILD2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.child2")
+            .build(); 
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_GRANDCHILD1 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.grandchild1")
+            .build();
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_GRANDCHILD2 = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.grandchild2")
+            .build(); 
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_BOGUS = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.bogus")
+            .build(); 
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
new file mode 100644
index 0000000..4d98c6b
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReferencingYamlTestEntityImpl.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+import brooklyn.entity.basic.AbstractApplication;
+
+public class ReferencingYamlTestEntityImpl extends AbstractApplication implements ReferencingYamlTestEntity {
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
new file mode 100644
index 0000000..23aa759
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ReloadBrooklynPropertiesTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.CampPlatform;
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+
+import java.io.Reader;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+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 brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.trait.Startable;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.stream.Streams;
+
+public class ReloadBrooklynPropertiesTest {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ReloadBrooklynPropertiesTest.class);
+    
+    private ManagementContext brooklynMgmt;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setup() {
+        brooklynMgmt = new BrooklynCampPlatformLauncherNoServer().launch().getBrooklynMgmt();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void teardown() {
+        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
+    }
+    
+    @Test
+    public void testReloadBrooklynPropertiesNonDeploy() {
+        CampPlatform platform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
+        Assert.assertNotNull(platform);
+        brooklynMgmt.reloadBrooklynProperties();
+        CampPlatform reloadedPlatform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
+        Assert.assertEquals(reloadedPlatform, platform);
+    }
+    
+    @Test
+    public void testReloadBrooklynPropertiesDeploy() {
+        brooklynMgmt.reloadBrooklynProperties();
+        CampPlatform reloadedPlatform = brooklynMgmt.getConfig().getConfig(BrooklynCampConstants.CAMP_PLATFORM);
+        Assert.assertNotNull(reloadedPlatform);
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("test-entity-basic-template.yaml"));
+        AssemblyTemplate template = reloadedPlatform.pdp().registerDeploymentPlan(input);
+        try {
+            Assembly assembly = template.getInstantiator().newInstance().instantiate(template, reloadedPlatform);
+            LOG.info("Test - created " + assembly);
+            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+            LOG.info("App - " + app);
+            Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+            EntityTestUtils.assertAttributeEqualsEventually(app, Startable.SERVICE_UP, true);
+        } catch (Exception e) {
+            LOG.warn("Unable to instantiate " + template + " (rethrowing): " + e);
+            throw Exceptions.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfig.java
new file mode 100644
index 0000000..2e557c7
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfig.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;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.entity.trait.Startable;
+import brooklyn.event.basic.BasicConfigKey;
+
+@ImplementedBy(TestEntityWithInitConfigImpl.class)
+public interface TestEntityWithInitConfig extends Entity, Startable, EntityLocal, EntityInternal {
+    public static final ConfigKey<Entity> TEST_ENTITY = BasicConfigKey.builder(Entity.class)
+            .name("test.entity")
+            .build();
+    public Entity getEntityCachedOnInit();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
new file mode 100644
index 0000000..b17ce4f
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import java.util.Collection;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.location.Location;
+
+public class TestEntityWithInitConfigImpl extends AbstractEntity implements TestEntityWithInitConfig {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TestEntityWithInitConfigImpl.class);
+    private Entity entityCachedOnInit;
+    
+    @Override
+    public void init() {
+        super.init();
+        entityCachedOnInit = getConfig(TEST_ENTITY);
+    }
+    
+    @Override
+    public void start(Collection<? extends Location> locations) {
+        LOG.trace("Starting {}", this);
+    }
+
+    @Override
+    public void stop() {
+        LOG.trace("Stopping {}", this);
+    }
+
+    @Override
+    public void restart() {
+        LOG.trace("Restarting {}", this);
+    }
+
+    public Entity getEntityCachedOnInit() {
+        return entityCachedOnInit;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
new file mode 100644
index 0000000..2db2667
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.Entity;
+import brooklyn.event.basic.BasicConfigKey;
+
+public class TestReferencingEnricher extends AbstractEnricher {
+    public static final ConfigKey<Entity> TEST_APPLICATION = new BasicConfigKey<Entity>(Entity.class, "test.reference.app");
+    public static final ConfigKey<Entity> TEST_ENTITY_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity1");
+    public static final ConfigKey<Entity> TEST_ENTITY_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity2");
+    public static final ConfigKey<Entity> TEST_CHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child1");
+    public static final ConfigKey<Entity> TEST_CHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child2");
+    public static final ConfigKey<Entity> TEST_GRANDCHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild1");
+    public static final ConfigKey<Entity> TEST_GRANDCHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild2");
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingPolicy.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingPolicy.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingPolicy.java
new file mode 100644
index 0000000..0718cf4
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingPolicy.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.policy.basic.AbstractPolicy;
+
+public class TestReferencingPolicy extends AbstractPolicy {
+    public static final ConfigKey<Entity> TEST_APPLICATION = new BasicConfigKey<Entity>(Entity.class, "test.reference.app");
+    public static final ConfigKey<Entity> TEST_ENTITY_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity1");
+    public static final ConfigKey<Entity> TEST_ENTITY_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.entity2");
+    public static final ConfigKey<Entity> TEST_CHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child1");
+    public static final ConfigKey<Entity> TEST_CHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.child2");
+    public static final ConfigKey<Entity> TEST_GRANDCHILD_1 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild1");
+    public static final ConfigKey<Entity> TEST_GRANDCHILD_2 = new BasicConfigKey<Entity>(Entity.class, "test.reference.grandchild2");
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
new file mode 100644
index 0000000..1aa70e6
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+import org.testng.Assert;
+
+import com.google.common.base.Preconditions;
+
+import brooklyn.entity.Effector;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.effector.EffectorBody;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.proxying.EntityInitializer;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.util.config.ConfigBag;
+
+public class TestSensorAndEffectorInitializer implements EntityInitializer {
+
+    public static final String EFFECTOR_SAY_HELLO = "sayHello";
+    public static final String SENSOR_LAST_HELLO = "lastHello";
+    public static final String SENSOR_HELLO_DEFINED = "sensorHelloDefined";
+    public static final String SENSOR_HELLO_DEFINED_EMITTED = "sensorHelloDefinedEmitted";
+
+    protected String helloWord() { return "Hello"; }
+    
+    @Override
+    public void apply(EntityLocal entity) {
+        Effector<String> eff = Effectors.effector(String.class, EFFECTOR_SAY_HELLO).parameter(String.class, "name").impl(
+            new EffectorBody<String>() {
+                @Override
+                public String call(ConfigBag parameters) {
+                    Object name = parameters.getStringKey("name");
+                    entity().setAttribute(Sensors.newStringSensor(SENSOR_LAST_HELLO), ""+name);
+                    return helloWord()+" "+name;
+                }
+            }).build();
+        ((EntityInternal)entity).getMutableEntityType().addEffector(eff);
+        
+        ((EntityInternal)entity).getMutableEntityType().addSensor(Sensors.newStringSensor(SENSOR_HELLO_DEFINED));
+        
+        AttributeSensor<String> emitted = Sensors.newStringSensor(SENSOR_HELLO_DEFINED_EMITTED);
+        ((EntityInternal)entity).getMutableEntityType().addSensor(emitted);
+        entity.setAttribute(emitted, "1");
+    }
+
+    public static class TestConfigurableInitializer extends TestSensorAndEffectorInitializer {
+        public static final String HELLO_WORD = "helloWord";
+        final String helloWord;
+        public TestConfigurableInitializer(Map<String,String> params) {
+            Preconditions.checkNotNull(params);
+            if (params.containsKey(HELLO_WORD)) {
+                helloWord = params.get(HELLO_WORD);
+                Assert.assertEquals(params.size(), 1);
+            } else {
+                helloWord = "Hello";
+                Assert.assertEquals(params.size(), 0);
+            }
+        }
+        
+        @Override
+        protected String helloWord() {
+            return helloWord;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
new file mode 100644
index 0000000..bde5016
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Effector;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityPredicates;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.management.Task;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+import brooklyn.util.text.StringPredicates;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+@Test
+public class VanillaBashNetcatYamlTest extends AbstractYamlTest {
+
+    private static final Logger log = LoggerFactory.getLogger(VanillaBashNetcatYamlTest.class);
+
+    private static final AttributeSensor<String> SENSOR_OUTPUT_ALL = Sensors.newStringSensor("output.all");
+    final static Effector<String> EFFECTOR_SAY_HI = Effectors.effector(String.class, "sayHiNetcat").buildAbstract();
+    
+    @Test(groups="Integration")
+    public void testInvocationSensorAndEnricher() throws Exception {
+        Preconditions.checkArgument(Networking.isPortAvailable(4321), "port 4321 must not be in use (no leaked nc instances) for this test to succeed!");
+        
+        Entity app = createAndStartApplication(loadYaml("vanilla-bash-netcat-w-client.yaml"));
+        waitForApplicationTasks(app);
+        
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        Assert.assertEquals(app.getDisplayName(), "Simple Netcat with Client");
+        
+        // comparing by plan ID is one common way
+        Iterable<Entity> netcatI = Iterables.filter(app.getChildren(), EntityPredicates.configEqualTo(BrooklynCampConstants.PLAN_ID, "netcat-server"));
+        Assert.assertTrue(netcatI.iterator().hasNext(), "no 'netcat-server' child of app: "+app.getChildren());
+        Entity netcat = Iterables.getOnlyElement(netcatI);
+        
+        // make sure netcat is running
+        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.RUNNING));
+        
+        // find the pinger, now comparing by name
+        Iterable<Entity> pingerI = Iterables.filter(app.getChildren(), EntityPredicates.displayNameEqualTo("Simple Pinger"));
+        Assert.assertTrue(pingerI.iterator().hasNext(), "no 'Simple Pinger' child of app: "+app.getChildren());
+        Entity pinger = Iterables.getOnlyElement(pingerI);
+
+        // invoke effector
+        Task<String> ping;
+        ping = pinger.invoke(EFFECTOR_SAY_HI, MutableMap.<String,Object>of());
+        Assert.assertEquals(ping.get().trim(), "hello");
+        // and check we get the right result 
+        EntityTestUtils.assertAttributeEventually(netcat, SENSOR_OUTPUT_ALL, StringPredicates.containsLiteral("hi netcat"));
+        log.info("invoked ping from "+pinger+" to "+netcat+", 'all' sensor shows:\n"+
+                netcat.getAttribute(SENSOR_OUTPUT_ALL));
+
+        // netcat should now fail and restart
+        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.not(Predicates.equalTo(Lifecycle.RUNNING)));
+        log.info("detected failure, state is: "+netcat.getAttribute(Attributes.SERVICE_STATE_ACTUAL));
+        EntityTestUtils.assertAttributeEventually(netcat, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.RUNNING));
+        log.info("detected recovery, state is: "+netcat.getAttribute(Attributes.SERVICE_STATE_ACTUAL));
+
+        // invoke effector again, now with a parameter
+        ping = pinger.invoke(EFFECTOR_SAY_HI, MutableMap.<String,Object>of("message", "yo yo yo"));
+        Assert.assertEquals(ping.get().trim(), "hello");
+        // checking right result
+        EntityTestUtils.assertAttributeEventually(netcat, SENSOR_OUTPUT_ALL, StringPredicates.containsLiteral("yo yo yo"));
+        log.info("invoked ping again from "+pinger+" to "+netcat+", 'all' sensor shows:\n"+
+                netcat.getAttribute(SENSOR_OUTPUT_ALL));
+        
+        // and it's propagated to the app
+        EntityTestUtils.assertAttributeEventually(app, Sensors.newStringSensor("output.last"), StringPredicates.containsLiteral("yo yo yo"));
+        
+        log.info("after all is said and done, app is:");
+        Entities.dumpInfo(app);
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/WrapAppTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/WrapAppTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/WrapAppTest.java
new file mode 100644
index 0000000..e94e8c5
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/WrapAppTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+import java.io.StringReader;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.StartableApplication;
+
+public class WrapAppTest extends AbstractYamlTest {
+    private static final String NO_WRAP_APP_IMPLICIT =
+            "name: Empty App\n" +
+            "services:\n" +
+            "   - type: brooklyn.test.entity.TestApplication";
+        
+    private static final String NO_WRAP_APP_EXPLICIT =
+            "name: Empty App\n" +
+            "wrappedApp: false\n" +
+            "services:\n" +
+            "   - type: brooklyn.test.entity.TestApplication";
+        
+    private static final String WRAP_APP_IMPLICIT =
+            "name: Empty App\n" +
+            "services:\n" +
+            "   - type: brooklyn.test.entity.TestApplication\n" +
+            "   - type: brooklyn.test.entity.TestApplication";
+        
+    private static final String WRAP_APP_EXPLICIT =
+            "name: Empty App\n" +
+            "wrappedApp: true\n" +
+            "services:\n" +
+            "   - type: brooklyn.test.entity.TestApplication";
+    
+    private static final String WRAP_ENTITY =
+            "name: Empty App\n" +
+            "services:\n" +
+            "   - type: brooklyn.test.entity.TestEntity";
+    
+    @Test
+    public void testNoWrapAppImplicit() throws Exception {
+        StartableApplication app = createApp(NO_WRAP_APP_IMPLICIT);
+        Assert.assertTrue(app.getChildren().size() == 0);
+    }
+    
+    @Test
+    public void testNoWrapAppExplicit() throws Exception {
+        StartableApplication app = createApp(NO_WRAP_APP_EXPLICIT);
+        Assert.assertTrue(app.getChildren().size() == 0);
+    }
+    
+    @Test
+    public void testWrapAppImplicit() throws Exception {
+        StartableApplication app = createApp(WRAP_APP_IMPLICIT);
+        Assert.assertTrue(app.getChildren().size() == 2);
+    }
+    
+    @Test
+    public void testWrapAppExplicit() throws Exception {
+        StartableApplication app = createApp(WRAP_APP_EXPLICIT);
+        Assert.assertTrue(app.getChildren().size() == 1);
+    }
+    
+    @Test
+    public void testWrapEntity() throws Exception {
+        StartableApplication app = createApp(WRAP_ENTITY);
+        Assert.assertTrue(app.getChildren().size() == 1);
+    }
+    
+    private StartableApplication createApp(String yaml) throws Exception {
+        StringReader in = new StringReader(yaml);
+        StartableApplication app = (StartableApplication)createAndStartApplication(in);
+        in.close();
+        return app;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
new file mode 100644
index 0000000..d8675c9
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/AbstractCatalogXmlTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.catalog;
+
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.Entity;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.management.osgi.OsgiTestResources;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.os.Os;
+import brooklyn.util.stream.ReaderInputStream;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.io.ByteStreams;
+
+public class AbstractCatalogXmlTest extends AbstractYamlTest {
+    
+    private String catalogUrl;
+    
+    public AbstractCatalogXmlTest(String catalogUrl) {
+        this.catalogUrl = catalogUrl;
+    }
+    
+    @Override
+    protected LocalManagementContext newTestManagementContext() {
+        ResourceUtils ru = new ResourceUtils(this);
+        File jar = createJar(ru);
+        File catalog = createCatalog(ru, jar);
+
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put(BrooklynServerConfig.BROOKLYN_CATALOG_URL, catalog.toURI().toString());
+        return LocalManagementContextForTests.builder(true)
+                .useProperties(properties)
+                .disableOsgi(false)
+                .build();
+    }
+
+    protected Entity startApp(String type) throws Exception {
+        String yaml = "name: simple-app-yaml\n" +
+                "location: localhost\n" +
+                "services: \n" +
+                "  - type: " + type;
+        return createAndStartApplication(yaml);
+    }
+
+    private File createCatalog(ResourceUtils ru, File tmpJar) {
+        String catalogTemplate = ru.getResourceAsString(catalogUrl);
+        String catalog = catalogTemplate.replace("${osgi-entities-path}", tmpJar.toURI().toString());
+        File catalogTmp = Os.newTempFile("simple-catalog-", ".xml");
+        copy(catalog, catalogTmp);
+        return catalogTmp;
+    }
+
+    private File createJar(ResourceUtils ru) {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        File tmpJar = Os.newTempFile("osgi-entities-", ".jar");
+        InputStream in = ru.getResourceFromUrl("classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        copy(in, tmpJar);
+        return tmpJar;
+    }
+
+    private void copy(String src, File dst) {
+        try {
+            copy(new ReaderInputStream(new StringReader(src), "UTF-8"), dst);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    private void copy(InputStream in, File tmpJar) {
+        try {
+            OutputStream out = new FileOutputStream(tmpJar);
+            ByteStreams.copy(in, out);
+            Streams.closeQuietly(in);
+            Streams.closeQuietly(out);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+}



[11/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
deleted file mode 100644
index 798a0dc..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
+++ /dev/null
@@ -1,261 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertTrue;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.basic.BrooklynTypes;
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import org.apache.brooklyn.catalog.CatalogItem;
-import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.location.LocationSpec;
-import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
-import brooklyn.policy.Policy;
-import brooklyn.policy.PolicySpec;
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.Iterables;
-
-/** Many of the same tests as per {@link OsgiVersionMoreEntityTest} but using YAML for catalog and entities, so catalog item ID is set automatically */
-public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest {
-    
-    private static final Logger log = LoggerFactory.getLogger(CatalogOsgiVersionMoreEntityTest.class);
-    
-    private static String getLocalResource(String filename) {
-        return ResourceUtils.create(CatalogOsgiVersionMoreEntityTest.class).getResourceAsString(
-            "classpath:/"+CatalogOsgiVersionMoreEntityTest.class.getPackage().getName().replace('.', '/')+"/"+filename);
-    }
-    
-    @Test
-    public void testMoreEntityV1() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
-
-        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
-        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity");
-        Assert.assertNotNull(item);
-        Assert.assertEquals(item.getVersion(), "1.0");
-        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY);
-        Assert.assertEquals(item.getLibraries().size(), 1);
-        
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
-        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity);
-        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity);
-    }
-
-    /** TODO we get warnings from {@link BrooklynEntityMatcher#extractValidConfigFlagsOrKeys};
-     * if we passed the correct loader at that point we could avoid those warnings. */ 
-    @Test
-    public void testMoreEntityV1WithPolicy() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("simple-policy-osgi-catalog.yaml"));
-        addCatalogItems(getLocalResource("more-entity-v1-with-policy-osgi-catalog.yaml"));
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
-        
-        Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies());
-        Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies());
-        // it was loaded by yaml w ref to catalog, so should have the simple-policy catalog-id
-        Assert.assertEquals(policy.getCatalogItemId(), "simple-policy:1.0");
-    }
-
-    @Test
-    public void testMoreEntityV2() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:1.0");
-        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
-        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
-        
-        Assert.assertEquals(moreEntity.getPolicies().size(), 1, "wrong policies: "+moreEntity.getPolicies());
-        Policy policy = Iterables.getOnlyElement(moreEntity.getPolicies());
-        // it was loaded from the java so should have the base more-entity catalog id
-        Assert.assertEquals(policy.getCatalogItemId(), "more-entity:1.0");
-    }
-
-    @Test
-    /** TODO this test works if we assume most recent version wins, but semantics TBC */
-    public void testMoreEntityV2ThenV1GivesV1() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
-        forceCatalogUpdate();
-        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntity);
-        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntity);
-    }
-
-    /** unlike {@link #testMoreEntityV2ThenV1GivesV1()} this test should always work,
-     * because default should probably be either most-recent version or highest version,
-     * in either case this works */
-    @Test
-    public void testMoreEntityV1ThenV2GivesV2() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("more-entity-v1-osgi-catalog.yaml"));
-        forceCatalogUpdate();
-        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
-        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
-    }
-
-    @Test
-    public void testMoreEntityBothV1AndV2() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("more-entity-v1-called-v1-osgi-catalog.yaml"));
-        addCatalogItems(getLocalResource("more-entity-v2-osgi-catalog.yaml"));
-        Entity v1 = createAndStartApplication("services: [ { type: 'more-entity-v1:1.0' } ]");
-        Entity v2 = createAndStartApplication("services: [ { type: 'more-entity:1.0' } ]");
-        
-        Entity moreEntityV1 = Iterables.getOnlyElement(v1.getChildren());
-        Entity moreEntityV2 = Iterables.getOnlyElement(v2.getChildren());
-        
-        OsgiVersionMoreEntityTest.assertV1EffectorCall(moreEntityV1);
-        OsgiVersionMoreEntityTest.assertV1MethodCall(moreEntityV1);
-        
-        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntityV2);
-        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntityV2);
-    }
-
-    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
-    public void testMoreEntityV2AutoscanWithClasspath() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-        
-        addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml"));
-        
-        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
-
-        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-entity");
-        Assert.assertNotNull(item);
-        Assert.assertEquals(item.getVersion(), "2.0.test");
-        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.ENTITY);
-        
-        // this refers to the java item, where the libraries are defined
-        item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MoreEntity");
-        Assert.assertEquals(item.getVersion(), "2.0.test_java");
-        Assert.assertEquals(item.getLibraries().size(), 2);
-        
-        Entity app = createAndStartApplication("services: [ { type: 'more-entity:2.0.test' } ]");
-        Entity moreEntity = Iterables.getOnlyElement(app.getChildren());
-        
-        Assert.assertEquals(moreEntity.getCatalogItemId(), "more-entity:2.0.test");
-        OsgiVersionMoreEntityTest.assertV2EffectorCall(moreEntity);
-        OsgiVersionMoreEntityTest.assertV2MethodCall(moreEntity);
-    }
-
-    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
-    public void testMorePolicyV2AutoscanWithClasspath() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-        
-        addCatalogItems(getLocalResource("more-policies-osgi-catalog-scan.yaml"));
-        
-        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
-
-        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "more-policy");
-        Assert.assertNotNull(item);
-        Assert.assertEquals(item.getVersion(), "2.0.test");
-        Assert.assertEquals(item.getCatalogItemType(), CatalogItemType.POLICY);
-        
-        // this refers to the java item, where the libraries are defined
-        item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), "brooklyn.osgi.tests.more.MorePolicy");
-        Assert.assertEquals(item.getVersion(), "2.0.test_java");
-        Assert.assertEquals(item.getLibraries().size(), 2);
-        
-        Entity app = createAndStartApplication(
-                "services: ",
-                "- type: brooklyn.entity.basic.BasicEntity",
-                "  brooklyn.policies:",
-                "  - type: more-policy:2.0.test");
-        Entity basicEntity = Iterables.getOnlyElement(app.getChildren());
-        Policy morePolicy = Iterables.getOnlyElement(basicEntity.getPolicies());
-        
-        Assert.assertEquals(morePolicy.getCatalogItemId(), "more-policy:2.0.test");
-        OsgiVersionMoreEntityTest.assertV2MethodCall(morePolicy);
-    }
-
-    // @Test FIXME: https://issues.apache.org/jira/browse/BROOKLYN-161
-    public void testAutoscanWithClasspathCanCreateSpecs() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar");
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/brooklyn/osgi/brooklyn-test-osgi-entities.jar");
-
-        addCatalogItems(getLocalResource("more-entities-osgi-catalog-scan.yaml"));
-
-        log.info("autoscan for osgi found catalog items: "+Strings.join(mgmt().getCatalog().getCatalogItems(), ", "));
-
-        BrooklynCatalog catalog = mgmt().getCatalog();
-        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems();
-        for (CatalogItem<Object, Object> item: items) {
-            Object spec = catalog.createSpec(item);
-            switch (item.getCatalogItemType()) {
-                case TEMPLATE:
-                case ENTITY:
-                    assertTrue(spec instanceof EntitySpec, "Not an EntitySpec: " + spec);
-                    BrooklynTypes.getDefinedEntityType(((EntitySpec<?>)spec).getType());
-                    break;
-                case POLICY:
-                    assertTrue(spec instanceof PolicySpec, "Not a PolicySpec: " + spec);
-                    BrooklynTypes.getDefinedBrooklynType(((PolicySpec<?>)spec).getType());
-                    break;
-                case LOCATION:
-                    assertTrue(spec instanceof LocationSpec, "Not a LocationSpec: " + spec);
-                    BrooklynTypes.getDefinedBrooklynType(((LocationSpec<?>)spec).getType());
-                    break;
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
deleted file mode 100644
index bac2991..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlOsgiTest.java
+++ /dev/null
@@ -1,37 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import org.testng.annotations.Test;
-
-public class CatalogXmlOsgiTest extends AbstractCatalogXmlTest {
-
-    public CatalogXmlOsgiTest(String catalogUrl) {
-        super("classpath://osgi-catalog.xml");
-    }
-
-    //OSGi libraries not supported with old-style catalog items
-    //We treat those catalog items just as an alias to the java type they hold.
-    //No loader wrapping their libraries is ever created.
-    @Test(expectedExceptions=IllegalStateException.class)
-    public void testOsgiItem() throws Exception {
-        startApp("OsgiApp");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
deleted file mode 100644
index 93e23e6..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogXmlVersionTest.java
+++ /dev/null
@@ -1,58 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertTrue;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-
-public class CatalogXmlVersionTest extends AbstractCatalogXmlTest {
-
-    public CatalogXmlVersionTest(String catalogUrl) {
-        super("classpath://simple-catalog.xml");
-    }
-
-    @DataProvider(name = "types")
-    public Object[][] createTypes() {
-        return new Object[][] {
-                {"brooklyn.entity.basic.BasicApplication"},
-                {"brooklyn.entity.basic.BasicApplication:0.0.0.SNAPSHOT"},
-                {"brooklyn.entity.basic.BasicApplication:2.0"},
-                {"BasicApp"}, // test that items with symbolicName not matching the type work
-                {"BasicApp:0.0.0.SNAPSHOT"},
-                {"BasicApp:2.0"},
-                {"brooklyn.osgi.tests.SimpleApplication"}, //test that classpath is used
-        };
-    }
-
-    @Test(dataProvider = "types")
-    public void testXmlCatalogItem(String type) throws Exception {
-        startApp(type);
-    }
-
-    @Test
-    public void testJavaPrefixDoesNotLoadXMLCatalogItem() throws Exception {
-        Entity entity = startApp("java:io.brooklyn.camp.brooklyn.catalog.TestBasicApp");
-        assertTrue(entity instanceof TestBasicApp, "Entity is not a " + TestBasicApp.class.getName() + ", instead the type is " + entity.getEntityType().getName());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
deleted file mode 100644
index 49fd5b5..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlCombiTest.java
+++ /dev/null
@@ -1,145 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.entity.basic.BasicStartable;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.policy.Policy;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.collect.Iterables;
-
-
-public class CatalogYamlCombiTest extends AbstractYamlTest {
-
-    private static final Logger log = LoggerFactory.getLogger(CatalogYamlCombiTest.class);
-    
-    @Test
-    public void testBRefEntityA() throws Exception {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  version: "+TEST_VERSION,
-            "  items:",
-            "  - item:",
-            "      id: A",
-            "      type: "+BasicEntity.class.getName(),
-            "      brooklyn.config: { a: 1, b: 0 }",
-            "  - item:",
-            "      id: B",
-            "      type: A",
-            "      brooklyn.config: { b: 1 }");
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("B", TEST_VERSION);
-        Assert.assertNotNull(item);
-
-        Entity a = launchEntity("A");
-        Assert.assertTrue(BasicEntity.class.isInstance(a), "Wrong type: "+a);
-        Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1);
-        Assert.assertEquals(a.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)0);
-
-        Entity b = launchEntity("B");
-        Assert.assertTrue(BasicEntity.class.isInstance(b), "Wrong type: "+b);
-        Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("a")), (Integer)1);
-        Assert.assertEquals(b.config().get(ConfigKeys.newIntegerConfigKey("b")), (Integer)1);
-
-        deleteCatalogEntity("A");
-        
-        // now loading B makes an error
-        try {
-            launchEntity("B");
-            Assert.fail("B should not be launchable");
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            log.info("Got expected error: "+e);
-        }
-        
-        deleteCatalogEntity("B");
-    }
-
-    @Test
-    public void testBRefPolicyALocationZ() throws Exception {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  version: "+TEST_VERSION,
-            "  id: Z",
-            "  items:",
-            "  - item: ",
-            "      type: localhost",
-            "      brooklyn.config: { z: 9 }");
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  version: "+TEST_VERSION,
-            "  items:",
-            "  - item_type: policy", 
-            "    item:",
-            "      id: A",
-            "      type: "+ServiceRestarter.class.getName(),
-            "      brooklyn.config: { a: 99 }",
-            "  - item:",
-            "      id: B",
-            "      type: "+BasicStartable.class.getName(),
-            "      location: Z",
-            "      brooklyn.policies:",
-            "      - type: A");
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("A", TEST_VERSION);
-        Assert.assertNotNull(item);
-
-        Entity b = launchEntity("B", false);
-        Assert.assertTrue(BasicStartable.class.isInstance(b), "Wrong type: "+b);
-        Entities.dumpInfo(b);
-        
-        Assert.assertEquals(Iterables.getOnlyElement(b.getLocations()).getConfig(ConfigKeys.newIntegerConfigKey("z")), (Integer)9);
-        
-        Policy p = Iterables.getOnlyElement(b.getPolicies());
-        Assert.assertTrue(ServiceRestarter.class.isInstance(p), "Wrong type: "+p);
-        Assert.assertEquals(p.getConfig(ConfigKeys.newIntegerConfigKey("a")), (Integer)99);
-        
-        deleteCatalogEntity("A");
-        deleteCatalogEntity("B");
-        deleteCatalogEntity("Z");
-    }
-
-    private Entity launchEntity(String symbolicName) throws Exception {
-        return launchEntity(symbolicName, true);
-    }
-    
-    private Entity launchEntity(String symbolicName, boolean includeLocation) throws Exception {
-        String yaml = "name: simple-app-yaml\n" +
-                      (includeLocation ? "location: localhost\n" : "") +
-                      "services: \n" +
-                      "  - type: "+ver(symbolicName);
-        Entity app = createAndStartApplication(yaml);
-        return Iterables.getOnlyElement(app.getChildren());
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
deleted file mode 100644
index 937ed9c..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
+++ /dev/null
@@ -1,781 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.List;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.management.osgi.OsgiStandaloneTest;
-import brooklyn.management.osgi.OsgiTestResources;
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.test.entity.TestEntityImpl;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.collect.Iterables;
-
-
-public class CatalogYamlEntityTest extends AbstractYamlTest {
-    
-    private static final String SIMPLE_ENTITY_TYPE = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY;
-
-    @Test
-    public void testAddCatalogItemVerySimple() throws Exception {
-        String symbolicName = "my.catalog.app.id.load";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  version: " + TEST_VERSION,
-            "  item:",
-            "    type: "+ BasicEntity.class.getName());
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertTrue(item.getPlanYaml().indexOf("services:")>=0, "expected 'services:' block: "+item+"\n"+item.getPlanYaml());
-
-        deleteCatalogEntity(symbolicName);
-    }
-    @Test
-    public void testAddCatalogItem() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.load";
-        addCatalogOSGiEntity(symbolicName);
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemTypeAsString() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.load";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item: " + SIMPLE_ENTITY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemTypeExplicitTypeAsString() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.load";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  item_type: entity",
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item: " + SIMPLE_ENTITY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemTopLevelSyntax() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.load";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemWithoutVersion() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "unversioned.app";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  name: " + id,
-            "  libraries:",
-            "  - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item:",
-            "    type: "+ SIMPLE_ENTITY_TYPE);
-        CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, BrooklynCatalog.DEFAULT_VERSION);
-        assertEquals(catalogItem.getVersion(), "0.0.0.SNAPSHOT");
-        mgmt().getCatalog().deleteCatalogItem(id, "0.0.0.SNAPSHOT");
-    }
-
-    @Test
-    public void testAddCatalogItemWithInlinedVersion() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "inline_version.app";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  name: " + id+":"+TEST_VERSION,
-            "  libraries:",
-            "  - " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE);
-        CatalogItem<?, ?> catalogItem = mgmt().getCatalog().getCatalogItem(id, TEST_VERSION);
-        assertEquals(catalogItem.getVersion(), TEST_VERSION);
-        mgmt().getCatalog().deleteCatalogItem(id, TEST_VERSION);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingCatalog() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.launch";
-        registerAndLaunchAndAssertSimpleEntity(symbolicName, SIMPLE_ENTITY_TYPE);
-    }
-
-    @Test
-    public void testLaunchApplicationUnversionedCatalogReference() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = "my.catalog.app.id.fail";
-        addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE);
-        try {
-            String yaml = "name: simple-app-yaml\n" +
-                          "location: localhost\n" +
-                          "services: \n" +
-                          "  - serviceType: " + symbolicName;
-            createAndStartApplication(yaml);
-        } finally {
-            deleteCatalogEntity(symbolicName);
-        }
-    }
-
-    @Test
-    public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String referencedSymbolicName = "my.catalog.app.id.referenced";
-        String referrerSymbolicName = "my.catalog.app.id.referring";
-        addCatalogOSGiEntities(referencedSymbolicName, SIMPLE_ENTITY_TYPE, referrerSymbolicName, ver(referencedSymbolicName));
-
-        CatalogItem<?, ?> referrer = mgmt().getCatalog().getCatalogItem(referrerSymbolicName, TEST_VERSION);
-        Assert.assertTrue(referrer.getPlanYaml().indexOf("services")>=0, "expected services in: "+referrer.getPlanYaml());
-        
-        String yaml = "name: simple-app-yaml\n" +
-                      "location: localhost\n" +
-                      "services: \n" +
-                      "  - type: " + ver(referrerSymbolicName);
-        Entity app = createAndStartApplication(yaml);
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(referencedSymbolicName);
-        deleteCatalogEntity(referrerSymbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationWithCatalogReferencingOtherCatalogInTwoSteps() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String referencedSymbolicName = "my.catalog.app.id.referenced";
-        String referrerSymbolicName = "my.catalog.app.id.referring";
-        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
-        addCatalogOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName));
-
-        String yaml = "name: simple-app-yaml\n" +
-                      "location: localhost\n" +
-                      "services: \n" +
-                      "  - serviceType: " + ver(referrerSymbolicName);
-        Entity app = createAndStartApplication(yaml);
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(referencedSymbolicName);
-        deleteCatalogEntity(referrerSymbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationChildWithCatalogReferencingOtherCatalog() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String referencedSymbolicName = "my.catalog.app.id.child.referenced";
-        String referrerSymbolicName = "my.catalog.app.id.child.referring";
-        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
-        addCatalogChildOSGiEntity(referrerSymbolicName, ver(referencedSymbolicName));
-
-        Entity app = createAndStartApplication(
-            "name: simple-app-yaml",
-            "location: localhost",
-            "services:",
-            "- type: "+BasicEntity.class.getName(),
-            "  brooklyn.children:",
-            "  - type: " + ver(referrerSymbolicName));
-
-        Collection<Entity> children = app.getChildren();
-        assertEquals(children.size(), 1);
-        Entity child = Iterables.getOnlyElement(children);
-        assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
-        Collection<Entity> grandChildren = child.getChildren();
-        assertEquals(grandChildren.size(), 1);
-        Entity grandChild = Iterables.getOnlyElement(grandChildren);
-        assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
-        Collection<Entity> grandGrandChildren = grandChild.getChildren();
-        assertEquals(grandGrandChildren.size(), 1);
-        Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren);
-        assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(referencedSymbolicName);
-        deleteCatalogEntity(referrerSymbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationChildWithCatalogReferencingOtherCatalogServicesBlock() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String referencedSymbolicName = "my.catalog.app.id.child.referenced";
-        String referrerSymbolicName = "my.catalog.app.id.child.referring";
-        addCatalogOSGiEntity(referencedSymbolicName, SIMPLE_ENTITY_TYPE);
-        addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referencedSymbolicName));
-
-        Entity app = createAndStartApplication(
-            "name: simple-app-yaml",
-            "location: localhost",
-            "services:",
-            "- serviceType: "+BasicEntity.class.getName(),
-            "  brooklyn.children:",
-            "  - type: " + ver(referrerSymbolicName));
-
-        Collection<Entity> children = app.getChildren();
-        assertEquals(children.size(), 1);
-        Entity child = Iterables.getOnlyElement(children);
-        assertEquals(child.getEntityType().getName(), BasicEntity.class.getName());
-        Collection<Entity> grandChildren = child.getChildren();
-        assertEquals(grandChildren.size(), 1);
-        Entity grandChild = Iterables.getOnlyElement(grandChildren);
-        assertEquals(grandChild.getEntityType().getName(), BasicEntity.class.getName());
-        Collection<Entity> grandGrandChildren = grandChild.getChildren();
-        assertEquals(grandGrandChildren.size(), 1);
-        Entity grandGrandChild = Iterables.getOnlyElement(grandGrandChildren);
-        assertEquals(grandGrandChild.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(referencedSymbolicName);
-        deleteCatalogEntity(referrerSymbolicName);
-    }
-    
-    @Test
-    public void testLaunchApplicationWithTypeUsingJavaColonPrefix() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = SIMPLE_ENTITY_TYPE;
-        String serviceName = "java:"+SIMPLE_ENTITY_TYPE;
-        registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName);
-    }
-
-    @Test
-    public void testLaunchApplicationLoopWithJavaTypeName() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String symbolicName = SIMPLE_ENTITY_TYPE;
-        String serviceName = SIMPLE_ENTITY_TYPE;
-        registerAndLaunchAndAssertSimpleEntity(symbolicName, serviceName);
-    }
-
-    @Test
-    public void testLaunchApplicationChildLoopCatalogIdFails() throws Exception {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String referrerSymbolicName = "my.catalog.app.id.child.referring";
-        try {
-            // TODO only fails if using 'services', because that forces plan parsing; should fail in all cases
-            addCatalogChildOSGiEntityWithServicesBlock(referrerSymbolicName, ver(referrerSymbolicName));
-            fail("Expected to throw");
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            assertTrue(e.getMessage().contains(referrerSymbolicName), "message was: "+e);
-        }
-    }
-
-    @Test
-    public void testReferenceInstalledBundleByName() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String firstItemId = "my.catalog.app.id.register_bundle";
-        String secondItemId = "my.catalog.app.id.reference_bundle";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + firstItemId,
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE);
-        deleteCatalogEntity(firstItemId);
-
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + secondItemId,
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME,
-            "    version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
-            "",
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(secondItemId);
-    }
-
-    @Test
-    public void testReferenceNonInstalledBundledByNameFails() {
-        String nonExistentId = "none-existent-id";
-        String nonExistentVersion = "9.9.9";
-        try {
-            addCatalogItems(
-                "brooklyn.catalog:",
-                "  id: my.catalog.app.id.non_existing.ref",
-                "  version: " + TEST_VERSION,
-                "  libraries:",
-                "  - name: " + nonExistentId,
-                "    version: " + nonExistentVersion,
-                "",
-                "services:",
-                "- type: " + SIMPLE_ENTITY_TYPE);
-            fail();
-        } catch (IllegalStateException e) {
-            Assert.assertEquals(e.getMessage(), "Bundle from null failed to install: Bundle CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=null} not previously registered, but URL is empty.");
-        }
-    }
-
-    @Test
-    public void testPartialBundleReferenceFails() {
-        try {
-            addCatalogItems(
-                "brooklyn.catalog:",
-                "  id: my.catalog.app.id.non_existing.ref",
-                "  version: " + TEST_VERSION,
-                "  libraries:",
-                "  - name: io.brooklyn.brooklyn-test-osgi-entities",
-                "",
-                "services:",
-                "- type: " + SIMPLE_ENTITY_TYPE);
-            fail();
-        } catch (NullPointerException e) {
-            Assert.assertEquals(e.getMessage(), "both name and version are required");
-        }
-        try {
-            addCatalogItems(
-                "brooklyn.catalog:",
-                "  id: my.catalog.app.id.non_existing.ref",
-                "  version: " + TEST_VERSION,
-                "  libraries:",
-                "  - version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
-                "",
-                "services:",
-                "- type: " + SIMPLE_ENTITY_TYPE);
-            fail();
-        } catch (NullPointerException e) {
-            Assert.assertEquals(e.getMessage(), "both name and version are required");
-        }
-    }
-
-    @Test
-    public void testFullBundleReference() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String itemId = "my.catalog.app.id.full_ref";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + itemId,
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - name: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME,
-            "    version: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION,
-            "    url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE);
-        deleteCatalogEntity(itemId);
-    }
-
-    /**
-     * Test that the name:version contained in the OSGi bundle will
-     * override the values supplied in the YAML.
-     */
-    @Test
-    public void testFullBundleReferenceUrlMetaOverridesLocalNameVersion() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String firstItemId = "my.catalog.app.id.register_bundle";
-        String nonExistentId = "non_existent_id";
-        String nonExistentVersion = "9.9.9";
-        try {
-            addCatalogItems(
-                "brooklyn.catalog:",
-                "  id: " + firstItemId,
-                "  version: " + TEST_VERSION,
-                "  libraries:",
-                "  - name: " + nonExistentId,
-                "    version: " + nonExistentVersion,
-                "    url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-                "",
-                "services:",
-                "- type: " + SIMPLE_ENTITY_TYPE);
-            fail();
-        } catch (IllegalStateException e) {
-            assertEquals(e.getMessage(), "Bundle from " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + " failed to install: " +
-                    "Bundle already installed as " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_NAME + ":" +
-                    OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION + " but user explicitly requested " +
-                    "CatalogBundleDto{symbolicName=" + nonExistentId + ", version=" + nonExistentVersion + ", url=" +
-                    OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + "}");
-        }
-    }
-
-    @Test
-    public void testUpdatingItemAllowedIfSame() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "my.catalog.app.id.duplicate";
-        addCatalogOSGiEntity(id);
-        addCatalogOSGiEntity(id);
-    }
-    
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testUpdatingItemFailsIfDifferent() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "my.catalog.app.id.duplicate";
-        addCatalogOSGiEntity(id);
-        addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE, true);
-    }
-
-    @Test
-    public void testForcedUpdatingItem() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "my.catalog.app.id.duplicate";
-        addCatalogOSGiEntity(id);
-        forceCatalogUpdate();
-        addCatalogOSGiEntity(id);
-        deleteCatalogEntity(id);
-    }
-
-    @Test
-    public void testCreateSpecFromCatalogItem() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        String id = "my.catalog.app.id.create_spec";
-        addCatalogOSGiEntity(id);
-        BrooklynCatalog catalog = mgmt().getCatalog();
-        CatalogItem<?, ?> item = catalog.getCatalogItem(id, TEST_VERSION);
-        Object spec = catalog.createSpec(item);
-        Assert.assertNotNull(spec);
-    }
-    
-    @Test
-    public void testLoadResourceFromBundle() throws Exception {
-        String id = "resource.test";
-        addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE);
-        String yaml =
-                "services: \n" +
-                "  - serviceType: "+ver(id);
-        Entity app = createAndStartApplication(yaml);
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        InputStream icon = new ResourceUtils(simpleEntity).getResourceFromUrl("classpath:/brooklyn/osgi/tests/icon.gif");
-        assertTrue(icon != null);
-        icon.close();
-    }
-    
-    @Test
-    public void testMissingTypeDoesNotRecurse() {
-        String symbolicName = "my.catalog.app.id.basic";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  version: " + TEST_VERSION,
-            "",
-            "services:",
-            "- type: brooklyn.entity.basic.BasicEntity");
-
-        try {
-            addCatalogItems(
-                    "brooklyn.catalog:",
-                    "  id: " + symbolicName,
-                    "  version: " + TEST_VERSION + "-update",
-                    "",
-                    "services:",
-                    "- type: " + symbolicName);
-            fail("Catalog addition expected to fail due to non-existent java type " + symbolicName);
-        } catch (IllegalStateException e) {
-            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
-        }
-    }
-    
-    @Test
-    public void testVersionedTypeDoesNotRecurse() {
-        String symbolicName = "my.catalog.app.id.basic";
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  version: " + TEST_VERSION,
-            "",
-            "services:",
-            "- type: brooklyn.entity.basic.BasicEntity");
-
-        String versionedId = CatalogUtils.getVersionedId(symbolicName, TEST_VERSION);
-        try {
-            addCatalogItems(
-                "brooklyn.catalog:",
-                "  id: " + symbolicName,
-                "  version: " + TEST_VERSION + "-update",
-                "",
-                "services:",
-                "- type: " + versionedId);
-            fail("Catalog addition expected to fail due to non-existent java type " + versionedId);
-        } catch (IllegalStateException e) {
-            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
-        }
-    }
-
-    @Test
-    public void testOsgiNotLeakingToParent() {
-        addCatalogOSGiEntity(SIMPLE_ENTITY_TYPE);
-        try {
-            addCatalogItems(
-                    "brooklyn.catalog:",
-                    "  id: " + SIMPLE_ENTITY_TYPE,
-                    "  version: " + TEST_VERSION + "-update",
-                    "",
-                    "services:",
-                    "- type: " + SIMPLE_ENTITY_TYPE);
-            fail("Catalog addition expected to fail due to non-existent java type " + SIMPLE_ENTITY_TYPE);
-        } catch (IllegalStateException e) {
-            assertTrue(e.toString().contains("recursive"), "Unexpected error message: "+e);
-        }
-    }
-
-    @Test
-    public void testConfigAppliedToCatalogItem() throws Exception {
-        addCatalogOSGiEntity("test", TestEntity.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  brooklyn.config:",
-                "    test.confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-
-    @Test
-    public void testFlagsAppliesToCatalogItem() throws Exception {
-        addCatalogOSGiEntity("test", TestEntity.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-
-    @Test
-    public void testExplicitFlagsAppliesToCatalogItem() throws Exception {
-        addCatalogOSGiEntity("test", TestEntity.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  brooklyn.flags:",
-                "    confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-    
-
-    @Test
-    public void testConfigAppliedToCatalogItemImpl() throws Exception {
-        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  brooklyn.config:",
-                "    test.confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-
-    @Test
-    public void testFlagsAppliesToCatalogItemImpl() throws Exception {
-        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-
-    @Test
-    public void testExplicitFlagsAppliesToCatalogItemImpl() throws Exception {
-        addCatalogOSGiEntity("test", TestEntityImpl.class.getName());
-        String testName = "test-applies-config-on-catalog-item";
-        Entity app = createAndStartApplication(
-                "services:",
-                "- type: " + ver("test"),
-                "  brooklyn.flags:",
-                "    confName: " + testName);
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.config().get(TestEntity.CONF_NAME), testName);
-    }
-    
-    private void registerAndLaunchAndAssertSimpleEntity(String symbolicName, String serviceType) throws Exception {
-        addCatalogOSGiEntity(symbolicName, serviceType);
-        String yaml = "name: simple-app-yaml\n" +
-                      "location: localhost\n" +
-                      "services: \n" +
-                      "  - serviceType: "+ver(symbolicName);
-        Entity app = createAndStartApplication(yaml);
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(simpleEntity.getEntityType().getName(), SIMPLE_ENTITY_TYPE);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    private void addCatalogOSGiEntity(String symbolicName) {
-        addCatalogOSGiEntity(symbolicName, SIMPLE_ENTITY_TYPE);
-    }
-
-    private void addCatalogOSGiEntity(String symbolicName, String serviceType) {
-        addCatalogOSGiEntity(symbolicName, serviceType, false);
-    }
-    
-    private void addCatalogOSGiEntity(String symbolicName, String serviceType, boolean extraLib) {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL +
-            (extraLib ? "\n"+"  - url: "+OsgiStandaloneTest.BROOKLYN_OSGI_TEST_A_0_1_0_URL : ""),
-            "  item:",
-            "    type: " + serviceType);
-    }
-
-    private void addCatalogOSGiEntities(String ...namesAndTypes) {
-        List<String> lines = MutableList.of(
-            "brooklyn.catalog:",
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  items:");
-        
-        for (int i=0; i<namesAndTypes.length; i+=2) {
-            lines.addAll(MutableList.of(
-            "  - id: " + namesAndTypes[i],
-            "    item:",
-            "      type: " + namesAndTypes[i+1]));
-        }
-            
-        addCatalogItems(lines);
-    }
-    private void addCatalogChildOSGiEntityWithServicesBlock(String symbolicName, String serviceType) {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item:",
-            "    services:",
-            "    - type: " + BasicEntity.class.getName(),
-            "      brooklyn.children:",
-            "      - type: " + serviceType);
-    }
-    private void addCatalogChildOSGiEntity(String symbolicName, String serviceType) {
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item:",
-            "    type: " + BasicEntity.class.getName(),
-            "    brooklyn.children:",
-            "    - type: " + serviceType);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
deleted file mode 100644
index b5c765c..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
+++ /dev/null
@@ -1,248 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import org.apache.brooklyn.catalog.CatalogItem.CatalogBundle;
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.entity.Entity;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.management.osgi.OsgiStandaloneTest;
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-import brooklyn.util.text.StringFunctions;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class CatalogYamlLocationTest extends AbstractYamlTest {
-    private static final String LOCALHOST_LOCATION_SPEC = "localhost";
-    private static final String LOCALHOST_LOCATION_TYPE = LocalhostMachineProvisioningLocation.class.getName();
-    private static final String SIMPLE_LOCATION_TYPE = "brooklyn.osgi.tests.SimpleLocation";
-
-    @AfterMethod
-    public void tearDown() {
-        for (CatalogItem<Location, LocationSpec<?>> ci : mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) {
-            mgmt().getCatalog().deleteCatalogItem(ci.getSymbolicName(), ci.getVersion());
-        }
-    }
-    
-    @Test
-    public void testAddCatalogItem() throws Exception {
-        assertEquals(countCatalogLocations(), 0);
-
-        String symbolicName = "my.catalog.location.id.load";
-        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null);
-        assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE);
-        removeAndAssert(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemOsgi() throws Exception {
-        assertEquals(countCatalogLocations(), 0);
-
-        String symbolicName = "my.catalog.location.id.load";
-        addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
-        assertAdded(symbolicName, SIMPLE_LOCATION_TYPE);
-        assertOsgi(symbolicName);
-        removeAndAssert(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemTopLevelItemSyntax() throws Exception {
-        assertEquals(countCatalogLocations(), 0);
-
-        String symbolicName = "my.catalog.location.id.load";
-        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null);
-        assertAdded(symbolicName, LOCALHOST_LOCATION_TYPE);
-        removeAndAssert(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemOsgiTopLevelItemSyntax() throws Exception {
-        assertEquals(countCatalogLocations(), 0);
-
-        String symbolicName = "my.catalog.location.id.load";
-        addCatalogLocationTopLevelItemSyntax(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
-        assertAdded(symbolicName, SIMPLE_LOCATION_TYPE);
-        assertOsgi(symbolicName);
-        removeAndAssert(symbolicName);
-    }
-
-    private void assertOsgi(String symbolicName) {
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        Collection<CatalogBundle> libs = item.getLibraries();
-        assertEquals(libs.size(), 1);
-        assertEquals(Iterables.getOnlyElement(libs).getUrl(), Iterables.getOnlyElement(getOsgiLibraries()));
-    }
-
-    private void assertAdded(String symbolicName, String expectedJavaType) {
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-        assertEquals(countCatalogLocations(), 1);
-
-        // Item added to catalog should automatically be available in location registry
-        LocationDefinition def = mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName);
-        assertEquals(def.getId(), symbolicName);
-        assertEquals(def.getName(), symbolicName);
-        
-        LocationSpec<?> spec = (LocationSpec<?>)mgmt().getCatalog().createSpec(item);
-        assertEquals(spec.getType().getName(), expectedJavaType);
-    }
-    
-    private void removeAndAssert(String symbolicName) {
-        // Deleting item: should be gone from catalog, and from location registry
-        deleteCatalogEntity(symbolicName);
-
-        assertEquals(countCatalogLocations(), 0);
-        assertNull(mgmt().getLocationRegistry().getDefinedLocationByName(symbolicName));
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingLocationClass() throws Exception {
-        String symbolicName = "my.catalog.location.id.launch";
-        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_TYPE, null);
-        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingLocationSpec() throws Exception {
-        String symbolicName = "my.catalog.location.id.launch";
-        addCatalogLocation(symbolicName, LOCALHOST_LOCATION_SPEC, null);
-        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingLocationClassTopLevelItemSyntax() throws Exception {
-        String symbolicName = "my.catalog.location.id.launch";
-        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_TYPE, null);
-        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingLocationSpecTopLevelSyntax() throws Exception {
-        String symbolicName = "my.catalog.location.id.launch";
-        addCatalogLocationTopLevelItemSyntax(symbolicName, LOCALHOST_LOCATION_SPEC, null);
-        runLaunchApplicationReferencingLocation(symbolicName, LOCALHOST_LOCATION_TYPE);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingOsgiLocation() throws Exception {
-        String symbolicName = "my.catalog.location.id.launch";
-        addCatalogLocation(symbolicName, SIMPLE_LOCATION_TYPE, getOsgiLibraries());
-        runLaunchApplicationReferencingLocation(symbolicName, SIMPLE_LOCATION_TYPE);
-        
-        deleteCatalogEntity(symbolicName);
-    }
-    
-    protected void runLaunchApplicationReferencingLocation(String locTypeInYaml, String locType) throws Exception {
-        Entity app = createAndStartApplication(
-            "name: simple-app-yaml",
-            "location: ",
-            "  "+locTypeInYaml+":",
-            "    config2: config2 override",
-            "    config3: config3",
-            "services: ",
-            "  - type: brooklyn.entity.basic.BasicStartable");
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        Location location = Iterables.getOnlyElement(simpleEntity.getLocations());
-        assertEquals(location.getClass().getName(), locType);
-        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
-        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
-        assertEquals(location.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
-    }
-
-    private List<String> getOsgiLibraries() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-        return ImmutableList.of(OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL);
-    }
-    
-    private void addCatalogLocation(String symbolicName, String locationType, List<String> libraries) {
-        ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
-                "brooklyn.catalog:",
-                "  id: " + symbolicName,
-                "  name: My Catalog Location",
-                "  description: My description",
-                "  version: " + TEST_VERSION);
-        if (libraries!=null && libraries.size() > 0) {
-            yaml.add("  libraries:")
-                .addAll(Lists.transform(libraries, StringFunctions.prepend("  - url: ")));
-        }
-        yaml.add(
-                "  item.type: location",
-                "  item:",
-                "    type: " + locationType,
-                "    brooklyn.config:",
-                "      config1: config1",
-                "      config2: config2");
-        
-        
-        addCatalogItems(yaml.build());
-    }
-
-    private void addCatalogLocationTopLevelItemSyntax(String symbolicName, String locationType, List<String> libraries) {
-        ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add(
-                "brooklyn.catalog:",
-                "  id: " + symbolicName,
-                "  name: My Catalog Location",
-                "  description: My description",
-                "  version: " + TEST_VERSION);
-        if (libraries!=null && libraries.size() > 0) {
-            yaml.add("  libraries:")
-                .addAll(Lists.transform(libraries, StringFunctions.prepend("  - url: ")));
-        }
-        yaml.add(
-                "",
-                "brooklyn.locations:",
-                "- type: " + locationType,
-                "  brooklyn.config:",
-                "    config1: config1",
-                "    config2: config2");
-        
-        
-        addCatalogItems(yaml.build());
-    }
-
-    private int countCatalogLocations() {
-        return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
deleted file mode 100644
index 00f5c71..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlPolicyTest.java
+++ /dev/null
@@ -1,196 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
-
-import org.testng.annotations.Test;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.entity.Entity;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.management.osgi.OsgiStandaloneTest;
-import brooklyn.policy.Policy;
-import org.apache.brooklyn.test.TestResourceUnavailableException;
-
-import com.google.common.collect.Iterables;
-
-public class CatalogYamlPolicyTest extends AbstractYamlTest {
-    private static final String SIMPLE_POLICY_TYPE = "brooklyn.osgi.tests.SimplePolicy";
-    private static final String SIMPLE_ENTITY_TYPE = "brooklyn.osgi.tests.SimpleEntity";
-
-    @Test
-    public void testAddCatalogItem() throws Exception {
-        assertEquals(countCatalogPolicies(), 0);
-
-        String symbolicName = "my.catalog.policy.id.load";
-        addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-        assertEquals(countCatalogPolicies(), 1);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testAddCatalogItemTopLevelSyntax() throws Exception {
-        assertEquals(countCatalogPolicies(), 0);
-
-        String symbolicName = "my.catalog.policy.id.load";
-        addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE);
-
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, TEST_VERSION);
-        assertEquals(item.getSymbolicName(), symbolicName);
-        assertEquals(countCatalogPolicies(), 1);
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingPolicy() throws Exception {
-        String symbolicName = "my.catalog.policy.id.launch";
-        addCatalogOsgiPolicy(symbolicName, SIMPLE_POLICY_TYPE);
-        Entity app = createAndStartApplication(
-            "name: simple-app-yaml",
-            "location: localhost",
-            "services: ",
-            "  - type: brooklyn.entity.basic.BasicEntity\n" +
-            "    brooklyn.policies:\n" +
-            "    - type: " + ver(symbolicName),
-            "      brooklyn.config:",
-            "        config2: config2 override",
-            "        config3: config3");
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
-        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
-
-        deleteCatalogEntity(symbolicName);
-    }
-
-    @Test
-    public void testLaunchApplicationReferencingPolicyTopLevelSyntax() throws Exception {
-        String symbolicName = "my.catalog.policy.id.launch";
-        addCatalogOsgiPolicyTopLevelSyntax(symbolicName, SIMPLE_POLICY_TYPE);
-        Entity app = createAndStartApplication(
-            "name: simple-app-yaml",
-            "location: localhost",
-            "services: ",
-            "  - type: brooklyn.entity.basic.BasicEntity\n" +
-            "    brooklyn.policies:\n" +
-            "    - type: " + ver(symbolicName),
-            "      brooklyn.config:",
-            "        config2: config2 override",
-            "        config3: config3");
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
-        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config1")), "config1");
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config2")), "config2 override");
-        assertEquals(policy.getConfig(new BasicConfigKey<String>(String.class, "config3")), "config3");
-
-        deleteCatalogEntity(symbolicName);
-    }
-    
-    @Test
-    public void testLaunchApplicationWithCatalogReferencingOtherCatalog() throws Exception {
-        String referencedSymbolicName = "my.catalog.policy.id.referenced";
-        String referrerSymbolicName = "my.catalog.policy.id.referring";
-        addCatalogOsgiPolicy(referencedSymbolicName, SIMPLE_POLICY_TYPE);
-
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + referrerSymbolicName,
-            "  name: My Catalog App",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "services:",
-            "- type: " + SIMPLE_ENTITY_TYPE,
-            "  brooklyn.policies:",
-            "  - type: " + ver(referencedSymbolicName));
-
-        String yaml = "name: simple-app-yaml\n" +
-                      "location: localhost\n" +
-                      "services: \n" +
-                      "- type: "+ ver(referrerSymbolicName);
-
-        Entity app = createAndStartApplication(yaml);
-
-        Entity simpleEntity = Iterables.getOnlyElement(app.getChildren());
-        Policy policy = Iterables.getOnlyElement(simpleEntity.getPolicies());
-        assertEquals(policy.getPolicyType().getName(), SIMPLE_POLICY_TYPE);
-
-        deleteCatalogEntity(referencedSymbolicName);
-    }
-
-    private void addCatalogOsgiPolicy(String symbolicName, String policyType) {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog Policy",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "  item:",
-            "    type: " + policyType,
-            "    brooklyn.config:",
-            "      config1: config1",
-            "      config2: config2");
-    }
-
-    private void addCatalogOsgiPolicyTopLevelSyntax(String symbolicName, String policyType) {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        addCatalogItems(
-            "brooklyn.catalog:",
-            "  id: " + symbolicName,
-            "  name: My Catalog Policy",
-            "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
-            "  version: " + TEST_VERSION,
-            "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
-            "",
-            "brooklyn.policies:",
-            "- type: " + policyType,
-            "  brooklyn.config:",
-            "    config1: config1",
-            "    config2: config2");
-    }
-
-    private int countCatalogPolicies() {
-        return Iterables.size(mgmt().getCatalog().getCatalogItems(CatalogPredicates.IS_POLICY));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
deleted file mode 100644
index a5dde16..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
+++ /dev/null
@@ -1,132 +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 io.brooklyn.camp.brooklyn.catalog;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import io.brooklyn.camp.brooklyn.AbstractYamlRebindTest;
-
-import org.testng.annotations.Test;
-
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
-import brooklyn.test.policy.TestEnricher;
-import brooklyn.test.policy.TestPolicy;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
-
-    // TODO Other tests (relating to https://issues.apache.org/jira/browse/BROOKLYN-149) include:
-    //   - entities cannot be instantiated because class no longer on classpath (e.g. was OSGi)
-    //   - config/attribute cannot be instantiated (e.g. because class no longer on classpath)
-    //   - entity file corrupt
-    
-    enum RebindWithCatalogTestMode {
-        NO_OP,
-        DELETE_CATALOG,
-        REPLACE_CATALOG_WITH_NEWER_VERSION;
-    }
-    
-    @Test
-    public void testRebindWithCatalogAndApp() throws Exception {
-        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.NO_OP);
-    }
-    
-    // See https://issues.apache.org/jira/browse/BROOKLYN-149.
-    // Deletes the catalog item before rebind, but the referenced types are still on the 
-    // default classpath.
-    // Will fallback to loading from classpath.
-    @Test
-    public void testRebindWithCatalogDeletedAndAppExisting() throws Exception {
-        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DELETE_CATALOG);
-    }
-    
-    // Upgrades the catalog item before rebind, deleting the old version.
-    // Will automatically upgrade.
-    @Test
-    public void testRebindWithCatalogUpgradedWithOldDeletedAndAppExisting() throws Exception {
-        BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND);
-        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.REPLACE_CATALOG_WITH_NEWER_VERSION);
-    }
-    
-    @SuppressWarnings("unused")
-    protected void runRebindWithCatalogAndApp(RebindWithCatalogTestMode mode) throws Exception {
-        String symbolicName = "my.catalog.app.id.load";
-        String version = "0.1.2";
-        String catalogFormat = Joiner.on("\n").join(
-                "brooklyn.catalog:",
-                "  id: " + symbolicName,
-                "  version: %s",
-                "  item:",
-                "    type: "+ BasicEntity.class.getName(),
-                "    brooklyn.enrichers:",
-                "    - type: "+TestEnricher.class.getName(),
-                "    brooklyn.policies:",
-                "    - type: "+TestPolicy.class.getName());
-        
-        // Create the catalog item
-        addCatalogItems(String.format(catalogFormat, version));
-
-        // Create an app, using that catalog item
-        String yaml = "name: simple-app-yaml\n" +
-                "location: localhost\n" +
-                "services: \n" +
-                "- type: "+CatalogUtils.getVersionedId(symbolicName, version);
-        origApp = (StartableApplication) createAndStartApplication(yaml);
-        BasicEntity origEntity = (BasicEntity) Iterables.getOnlyElement(origApp.getChildren());
-        TestPolicy origPolicy = (TestPolicy) Iterables.getOnlyElement(origEntity.getPolicies());
-        TestEnricher origEnricher = (TestEnricher) Iterables.tryFind(origEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
-        assertEquals(origEntity.getCatalogItemId(), symbolicName+":"+version);
-
-        // Depending on test-mode, delete the catalog item, and then rebind
-        switch (mode) {
-            case DELETE_CATALOG:
-                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
-                break;
-            case REPLACE_CATALOG_WITH_NEWER_VERSION:
-                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
-                version = "0.1.3";
-                addCatalogItems(String.format(catalogFormat, version));
-                break;
-            case NO_OP:
-                // no-op
-        }
-        
-        rebind();
-
-        // Ensure app is still there
-        BasicEntity newEntity = (BasicEntity) Iterables.getOnlyElement(newApp.getChildren());
-        Policy newPolicy = Iterables.getOnlyElement(newEntity.getPolicies());
-        Enricher newEnricher = Iterables.tryFind(newEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
-        assertEquals(newEntity.getCatalogItemId(), symbolicName+":"+version);
-
-        // Ensure app is still usable - e.g. "stop" effector functions as expected
-        newApp.stop();
-        assertFalse(Entities.isManaged(newApp));
-        assertFalse(Entities.isManaged(newEntity));
-    }
-}



[13/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlTest.java
deleted file mode 100644
index ec0d6bd..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ /dev/null
@@ -1,919 +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 io.brooklyn.camp.brooklyn;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import io.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
-import io.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
-import io.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
-
-import java.io.StringReader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-import org.testng.collections.Lists;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Application;
-import brooklyn.entity.Effector;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.BasicApplication;
-import brooklyn.entity.basic.BasicEntity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityFunctions;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.EntityPredicates;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.SameServerEntity;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.management.Task;
-import brooklyn.management.internal.EntityManagementUtils;
-import brooklyn.management.internal.EntityManagerInternal;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.test.entity.TestEntityImpl;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Functionals;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-@Test
-public class EntitiesYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(EntitiesYamlTest.class);
-
-    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-        
-        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-        
-        return (TestEntity)entity;
-    }
-    
-    @Test
-    public void testSingleEntity() throws Exception {
-        setupAndCheckTestEntityInBasicYamlWith();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testBrooklynConfig() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  brooklyn.config:",
-            "    test.confName: Test Entity Name",
-            "    test.confMapPlain:",
-            "      foo: bar",
-            "      baz: qux",
-            "    test.confListPlain:",
-            "      - dogs",
-            "      - cats",
-            "      - badgers",
-            "    test.confSetThing: !!set",
-            "      ? square",
-            "      ? circle",
-            "      ? triangle",
-            "    test.confObject: 5");
-        
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Test Entity Name");
-        List<String> list = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
-        Assert.assertEquals(list, ImmutableList.of("dogs", "cats", "badgers"));
-        Map<String, String> map = testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
-        Assert.assertEquals(map, ImmutableMap.of("foo", "bar", "baz", "qux"));
-        Set<String> set = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_THING);
-        Assert.assertEquals(set, ImmutableSet.of("square", "circle", "triangle"));
-        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
-        Assert.assertEquals(object, 5);
-    }
-
-    @Test
-    public void testFlagInBrooklynConfig() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  brooklyn.config:",
-            "    confName: Foo Bar");
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testUndeclaredItemInBrooklynConfig() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  brooklyn.config:",
-            "    test.dynamic.confName: Foo Bar");
-        Assert.assertEquals(testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName")), "Foo Bar");
-    }
-
-    @Test
-    public void testFlagAtRoot() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  confName: Foo Bar");
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testFlagAtRootEntityImpl() throws Exception {
-        Entity app = createAndStartApplication(
-                "services:",
-                "- serviceType: " + TestEntityImpl.class.getName(),
-                "  confName: Foo Bar");
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testConfigKeyAtRoot() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  test.confName: Foo Bar");
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testUndeclaredItemAtRootIgnored() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  test.dynamic.confName: Foo Bar");
-        // should NOT be set (and there should be a warning in the log)
-        String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
-        Assert.assertNull(dynamicConfNameValue);
-    }
-
-    @Test
-    public void testExplicitFlags() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  brooklyn.flags:",
-            "    confName: Foo Bar");
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testExplicitFlagsEntityImpl() throws Exception {
-        Entity app = createAndStartApplication(
-                "services:",
-                "- serviceType: " + TestEntityImpl.class.getName(),
-                "  brooklyn.flags:",
-                "    confName: Foo Bar");
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
-    }
-
-    @Test
-    public void testUndeclaredExplicitFlagsIgnored() throws Exception {
-        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
-            "  brooklyn.flags:",
-            "    test.dynamic.confName: Foo Bar");
-        String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
-        Assert.assertNull(dynamicConfNameValue);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testEmptyConfig() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
-            "  brooklyn.config:",
-            "    test.confName: \"\"",
-            "    test.confListPlain: !!seq []",
-            "    test.confMapPlain: !!map {}",
-            "    test.confSetPlain: !!set {}",
-            "    test.confObject: \"\""));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertNotNull(entity, "Expected app to have child entity");
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-        TestEntity testEntity = (TestEntity) entity;
-        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "");
-        List<String> list = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
-        Assert.assertEquals(list, ImmutableList.of());
-        Map<String, String> map = testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
-        Assert.assertEquals(map, ImmutableMap.of());
-        // TODO: CONF_SET_PLAIN is being set to an empty ArrayList - may be a snakeyaml issue?
-        //        Set<String> plainSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_PLAIN);
-        //        Assert.assertEquals(plainSet, ImmutableSet.of());
-        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
-        Assert.assertEquals(object, "");
-    }
-    
-    @SuppressWarnings("unchecked")
-    public void testEmptyStructuredConfig() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
-            "  brooklyn.config:",
-            "    test.confName: \"\"",
-            "    test.confListThing: !!seq []",
-            "    test.confSetThing: !!set {}",
-            "    test.confMapThing: !!map {}"));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertNotNull(entity, "Expected app to have child entity");
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-        TestEntity testEntity = (TestEntity) entity;
-        List<String> thingList = (List<String>)testEntity.getConfig(TestEntity.CONF_LIST_THING);
-        Set<String> thingSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_THING);
-        Map<String, String> thingMap = (Map<String, String>)testEntity.getConfig(TestEntity.CONF_MAP_THING);
-        Assert.assertEquals(thingList, Lists.newArrayList());
-        Assert.assertEquals(thingSet, ImmutableSet.of());
-        Assert.assertEquals(thingMap, ImmutableMap.of());
-    }
-
-    @Test
-    public void testSensor() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
-            "  brooklyn.config:",
-            "    test.confObject: $brooklyn:sensor(\"brooklyn.test.entity.TestEntity\", \"test.sequence\")"));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertNotNull(entity, "Expected app to have child entity");
-        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
-        TestEntity testEntity = (TestEntity) entity;
-        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof AttributeSensor, "attributeSensor="+object);
-        Assert.assertEquals(object, TestEntity.SEQUENCE);
-    }
-
-    @Test
-    public void testSensorOnArbitraryClass() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
-            "  brooklyn.config:",
-            "    test.confObject: $brooklyn:sensor(\"io.brooklyn.camp.brooklyn.EntitiesYamlTest$ArbitraryClassWithSensor\", \"mysensor\")"));
-        waitForApplicationTasks(app);
-
-        log.info("App started:");
-        Entities.dumpInfo(app);
-
-        TestEntity entity = (TestEntity) app.getChildren().iterator().next();
-        Object object = entity.getConfig(TestEntity.CONF_OBJECT);
-        Assert.assertEquals(object, ArbitraryClassWithSensor.MY_SENSOR);
-    }
-    public static class ArbitraryClassWithSensor {
-        public static final AttributeSensor<String> MY_SENSOR = Sensors.newStringSensor("mysensor");
-    }
-    
-    @Test
-    public void testComponent() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
-            "  brooklyn.config:",
-            "    test.confName: first entity",
-            "  id: te1",
-            "- serviceType: brooklyn.test.entity.TestEntity",
-            "  name: second entity",
-            "  brooklyn.config:",
-            "    test.confObject: $brooklyn:component(\"te1\")"));
-        waitForApplicationTasks(app);
-        Entity firstEntity = null;
-        Entity secondEntity = null;
-        Assert.assertEquals(app.getChildren().size(), 2);
-        for (Entity entity : app.getChildren()) {
-            if (entity.getDisplayName().equals("testentity"))
-                firstEntity = entity;
-            else if (entity.getDisplayName().equals("second entity"))
-                secondEntity = entity;
-        }
-        final Entity[] entities = {firstEntity, secondEntity};
-        Assert.assertNotNull(entities[0], "Expected app to contain child named 'testentity'");
-        Assert.assertNotNull(entities[1], "Expected app to contain child named 'second entity'");
-        Object object = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Object>() {
-            public Object call() {
-                return entities[1].getConfig(TestEntity.CONF_OBJECT);
-            }}).get();
-        Assert.assertNotNull(object);
-        Assert.assertEquals(object, firstEntity, "Expected second entity's test.confObject to contain first entity");
-    }
-
-    @Test
-    public void testGrandchildEntities() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
-            "  brooklyn.config:",
-            "    test.confName: first entity",
-            "  brooklyn.children:",
-            "  - serviceType: brooklyn.test.entity.TestEntity",
-            "    name: Child Entity",
-            "    brooklyn.config:",
-            "      test.confName: Name of the first Child",
-            "    brooklyn.children:",
-            "    - serviceType: brooklyn.test.entity.TestEntity",
-            "      name: Grandchild Entity",
-            "      brooklyn.config:",
-            "        test.confName: Name of the Grandchild",
-            "  - serviceType: brooklyn.test.entity.TestEntity",
-            "    name: Second Child",
-            "    brooklyn.config:",
-            "      test.confName: Name of the second Child"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity firstEntity = app.getChildren().iterator().next();
-        Assert.assertEquals(firstEntity.getConfig(TestEntity.CONF_NAME), "first entity");
-        Assert.assertEquals(firstEntity.getChildren().size(), 2);
-        Entity firstChild = null;
-        Entity secondChild = null;
-        for (Entity entity : firstEntity.getChildren()) {
-            if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the first Child"))
-                firstChild = entity;
-            if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the second Child"))
-                secondChild = entity;
-        }
-        Assert.assertNotNull(firstChild, "Expected a child of 'first entity' with the name 'Name of the first Child'");
-        Assert.assertNotNull(secondChild, "Expected a child of 'first entity' with the name 'Name of the second Child'");
-        Assert.assertEquals(firstChild.getChildren().size(), 1);
-        Entity grandchild = firstChild.getChildren().iterator().next();
-        Assert.assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "Name of the Grandchild");
-        Assert.assertEquals(secondChild.getChildren().size(), 0);
-    }
-
-    @Test
-    public void testWithInitConfig() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-with-init-config.yaml"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getDisplayName(), "test-entity-with-init-config");
-        TestEntityWithInitConfig testWithConfigInit = null;
-        TestEntity testEntity = null;
-        Assert.assertEquals(app.getChildren().size(), 2);
-        for (Entity entity : app.getChildren()) {
-            if (entity instanceof TestEntity)
-                testEntity = (TestEntity) entity;
-            if (entity instanceof TestEntityWithInitConfig)
-                testWithConfigInit = (TestEntityWithInitConfig) entity;
-        }
-        Assert.assertNotNull(testEntity, "Expected app to contain TestEntity child");
-        Assert.assertNotNull(testWithConfigInit, "Expected app to contain TestEntityWithInitConfig child");
-        Assert.assertEquals(testWithConfigInit.getEntityCachedOnInit(), testEntity);
-        log.info("App started:");
-        Entities.dumpInfo(app);
-    }
-
-    @Test
-    public void testMultipleReferencesJava() throws Exception {
-        final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
-        waitForApplicationTasks(app);
-        
-        Entity c1 = Tasks.resolving(new DslComponent("c1").newTask(), Entity.class).context( ((EntityInternal)app).getExecutionContext() ).embedResolutionInTask(true).get();
-        Assert.assertEquals(c1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("child 1")).iterator().next());
-        
-        Entity e1 = Tasks.resolving(new DslComponent(Scope.PARENT, "xxx").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
-        Assert.assertEquals(e1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("entity 1")).iterator().next());
-        
-        Entity c1a = Tasks.resolving(BrooklynDslCommon.descendant("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
-        Assert.assertEquals(c1a, c1);
-        Entity e1a = Tasks.resolving(BrooklynDslCommon.ancestor("e1").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
-        Assert.assertEquals(e1a, e1);
-        try {
-            Tasks.resolving(BrooklynDslCommon.ancestor("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
-            Assert.fail("Should not have found c1 as ancestor of e1");
-        } catch (Exception e) { /* expected */ }
-    }
-    
-    @Test
-    public void testMultipleReferences() throws Exception {
-        final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
-        waitForApplicationTasks(app);
-        
-        Entities.dumpInfo(app);
-        
-        Assert.assertEquals(app.getDisplayName(), "test-referencing-entities");
-
-        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
-
-        Assert.assertEquals(app.getChildren().size(), 2);
-        for (Entity child : app.getChildren()) {
-            if (child.getDisplayName().equals("entity 1"))
-                entity1 = child;
-            if (child.getDisplayName().equals("entity 2"))
-                entity2 = child;
-        }
-        Assert.assertNotNull(entity1);
-        Assert.assertNotNull(entity2);
-
-        Assert.assertEquals(entity1.getChildren().size(), 2);
-        for (Entity child : entity1.getChildren()) {
-            if (child.getDisplayName().equals("child 1"))
-                child1 = child;
-            if (child.getDisplayName().equals("child 2"))
-                child2 = child;
-        }
-        Assert.assertNotNull(child1);
-        Assert.assertNotNull(child2);
-
-        Assert.assertEquals(child1.getChildren().size(), 2);
-        for (Entity child : child1.getChildren()) {
-            if (child.getDisplayName().equals("grandchild 1"))
-                grandchild1 = child;
-            if (child.getDisplayName().equals("grandchild 2"))
-                grandchild2 = child;
-        }
-        Assert.assertNotNull(grandchild1);
-        Assert.assertNotNull(grandchild2);
-
-        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1_ALT, entity1)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY2, entity2)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD1, child1)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD2, child2)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD1, grandchild1)
-            .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD2, grandchild2)
-            .build();
-
-        Iterable<Entity> entitiesInApp = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Iterable<Entity>>() {
-            @Override
-            public Iterable<Entity> call() throws Exception {
-                return ((EntityManagerInternal)((EntityInternal)app).getManagementContext().getEntityManager()).getAllEntitiesInApplication((Application)app);
-            }
-        }).get();
-
-        for (Entity entityInApp : entitiesInApp) {
-            checkReferences(entityInApp, keyToEntity);
-            try {
-                getResolvedConfigInTask(entityInApp, ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS);
-                Assert.fail("Should not have resolved "+ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS+" at "+entityInApp);
-            } catch (Exception e) {
-                /* expected */
-            }
-        }
-    }
-
-    private void checkReferences(final Entity entity, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
-        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
-            try {
-                Assert.assertEquals(getResolvedConfigInTask(entity, key).get(), keyToEntity.get(key));
-            } catch (Throwable t) {
-                Exceptions.propagateIfFatal(t);
-                Assert.fail("Wrong value for "+entity+":"+key+", "+((EntityInternal)entity).config().getLocalRaw(key)+": "+t, t);
-            }
-        }
-    }
-
-    private Maybe<Entity> getResolvedConfigInTask(final Entity entity, final ConfigKey<Entity> key) {
-        return Tasks.resolving(Tasks.<Entity>builder().body(
-            Functionals.callable(Suppliers.compose(EntityFunctions.config(key), Suppliers.ofInstance(entity))) ).build())
-            .as(Entity.class)
-            .context( ((EntityInternal)entity).getExecutionContext() ).embedResolutionInTask(true)
-            .getMaybe();
-    }
-
-    public void testWithAppLocation() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
-            "location: localhost:(name=yaml name)"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getLocations().size(), 1);
-        Location location = app.getLocations().iterator().next();
-        Assert.assertNotNull(location);
-        Assert.assertEquals(location.getDisplayName(), "yaml name");
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getLocations().size(), 1);
-    }
-
-    @Test
-    public void testWithEntityLocation() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
-            "  location: localhost:(name=yaml name)\n"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getLocations().size(), 0);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertEquals(entity.getLocations().size(), 1);
-        Location location = entity.getLocations().iterator().next();
-        Assert.assertNotNull(location);
-        Assert.assertEquals(location.getDisplayName(), "yaml name");
-        Assert.assertNotNull(entity);
-    }
-
-    @Test
-    public void testWith2AppLocations() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
-            "locations:",
-            "- localhost:(name=localhost name)",
-            "- byon:(hosts=\"1.1.1.1\", name=byon name)"));
-        waitForApplicationTasks(app);
-
-        Assert.assertEquals(app.getLocations().size(), 2);
-        Location localhostLocation = null, byonLocation = null; 
-        for (Location location : app.getLocations()) {
-            if (location.getDisplayName().equals("localhost name"))
-                localhostLocation = location;
-            else if (location.getDisplayName().equals("byon name"))
-                byonLocation = location;
-        }
-        Assert.assertNotNull(localhostLocation);
-        Assert.assertNotNull(byonLocation);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getLocations().size(), 2);
-    }
-
-    @Test
-    public void testWith2EntityLocations() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
-            "  locations:",
-            "  - localhost:(name=localhost name)",
-            "  - byon:(hosts=\"1.1.1.1\", name=byon name)"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getLocations().size(), 0);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        Assert.assertEquals(entity.getLocations().size(), 2);
-        Location localhostLocation = null, byonLocation = null; 
-        for (Location location : entity.getLocations()) {
-            if (location.getDisplayName().equals("localhost name"))
-                localhostLocation = location;
-            else if (location.getDisplayName().equals("byon name"))
-                byonLocation = location;
-        }
-        Assert.assertNotNull(localhostLocation);
-        Assert.assertNotNull(byonLocation);
-    }
-
-    @Test
-    public void testWithAppAndEntityLocations() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
-            "  location: localhost:(name=localhost name)",
-            "location: byon:(hosts=\"1.1.1.1\", name=byon name)"));
-        waitForApplicationTasks(app);
-        Assert.assertEquals(app.getLocations().size(), 1);
-        Assert.assertEquals(app.getChildren().size(), 1);
-        Entity entity = app.getChildren().iterator().next();
-        
-        Assert.assertEquals(entity.getLocations().size(), 2);
-        Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
-        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost name");
-        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "byon name");
-        
-        Location appLocation = app.getLocations().iterator().next();
-        Assert.assertEquals(appLocation.getDisplayName(), "byon name");
-    }
-
-    @Test
-    public void testCreateClusterWithMemberSpec() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("test-cluster-with-member-spec.yaml"));
-        waitForApplicationTasks(app);
-        assertEquals(app.getChildren().size(), 1);
-
-        Entity clusterEntity = Iterables.getOnlyElement(app.getChildren());
-        assertTrue(clusterEntity instanceof DynamicCluster, "cluster="+clusterEntity);
-
-        DynamicCluster cluster = DynamicCluster.class.cast(clusterEntity);
-        assertEquals(cluster.getMembers().size(), 2, "members="+cluster.getMembers());
-
-        for (Entity member : cluster.getMembers()) {
-            assertTrue(member instanceof TestEntity, "member="+member);
-            assertEquals(member.getConfig(TestEntity.CONF_NAME), "yamlTest");
-        }
-    }
-
-    @Test
-    public void testEntitySpecConfig() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  brooklyn.config:\n"+
-                "   test.childSpec:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       brooklyn.config:\n"+
-                "         test.confName: inchildspec\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
-        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
-    }
-
-    @Test
-    public void testEntitySpecFlags() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  confName: inParent\n"+
-                "  brooklyn.config:\n"+
-                "   test.childSpec:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       confName: inchildspec\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
-        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
-    }
-
-    @Test
-    public void testEntitySpecExplicitFlags() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  brooklyn.flags:\n"+
-                "    confName: inParent\n"+
-                "  brooklyn.config:\n"+
-                "   test.childSpec:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       brooklyn.flags:\n"+
-                "         confName: inchildspec\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
-        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
-    }
-
-    @Test
-    public void testEntitySpecWithChildren() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  brooklyn.config:\n"+
-                "   test.childSpec:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       brooklyn.config:\n"+
-                "         test.confName: child\n"+
-                "       brooklyn.children:\n"+
-                "       - type: brooklyn.test.entity.TestEntity\n" +
-                "         brooklyn.config:\n" +
-                "           test.confName: grandchild\n" +
-                "         brooklyn.children:\n"+
-                "         - type: brooklyn.test.entity.TestEntity\n" +
-                "           brooklyn.config:\n" +
-                "             test.confName: greatgrandchild\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
-        assertEquals(child.getConfig(TestEntity.CONF_NAME), "child");
-        assertEquals(child.getChildren().size(), 1, "Child entity should have exactly one child of its own");
-
-        TestEntity grandchild = (TestEntity) Iterables.getOnlyElement(child.getChildren());
-        assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "grandchild");
-        assertEquals(grandchild.getChildren().size(), 1, "Grandchild entity should have exactly one child of its own");
-
-        TestEntity greatgrandchild = (TestEntity) Iterables.getOnlyElement(grandchild.getChildren());
-        assertEquals(greatgrandchild.getConfig(TestEntity.CONF_NAME), "greatgrandchild");
-    }
-    
-    @Test
-    public void testNestedEntitySpecConfigs() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  brooklyn.config:\n"+
-                "   test.childSpec:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       brooklyn.config:\n"+
-                "         test.confName: inchildspec\n"+
-                "         test.childSpec:\n"+
-                "           $brooklyn:entitySpec:\n"+
-                "             type: brooklyn.test.entity.TestEntity\n"+
-                "             brooklyn.config:\n"+
-                "               test.confName: ingrandchildspec\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
-        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
-        
-        TestEntity grandchild = (TestEntity) child.createAndManageChildFromConfig();
-        assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "ingrandchildspec");
-    }
-    
-    @Test
-    public void testEntitySpecInUnmatchedConfig() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n"+
-                "  brooklyn.config:\n"+
-                "   key.does.not.match:\n"+
-                "     $brooklyn:entitySpec:\n"+
-                "       type: brooklyn.test.entity.TestEntity\n"+
-                "       brooklyn.config:\n"+
-                "         test.confName: inchildspec\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        EntitySpec<?> entitySpec = (EntitySpec<?>) entity.config().getBag().getStringKey("key.does.not.match");
-        assertEquals(entitySpec.getType(), TestEntity.class);
-        assertEquals(entitySpec.getConfig(), ImmutableMap.of(TestEntity.CONF_NAME, "inchildspec"));
-    }
-
-    @Test
-    public void testAppWithSameServerEntityStarts() throws Exception {
-        Entity app = createAndStartApplication(loadYaml("same-server-entity-test.yaml"));
-        waitForApplicationTasks(app);
-        assertNotNull(app);
-        assertEquals(app.getAttribute(Attributes.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING, "service state");
-        assertTrue(app.getAttribute(Attributes.SERVICE_UP), "service up");
-
-        assertEquals(app.getChildren().size(), 1);
-        Entity entity = Iterables.getOnlyElement(app.getChildren());
-        assertTrue(entity instanceof SameServerEntity, "entity="+entity);
-
-        SameServerEntity sse = (SameServerEntity) entity;
-        assertEquals(sse.getChildren().size(), 2);
-        for (Entity child : sse.getChildren()) {
-            assertTrue(child instanceof BasicEntity, "child="+child);
-        }
-    }
-    
-    @Test
-    public void testEntityImplExposesAllInterfacesIncludingStartable() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntityImpl\n";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        assertTrue(entity.getCallHistory().contains("start"), "history="+entity.getCallHistory());
-    }
-
-    @Test
-    public void testEntityWithInitializer() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- type: "+TestEntity.class.getName()+"\n"+
-                "  brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.class.getName()+" } ]";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        Effector<?> hi = entity.getEffector(TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO);
-        Assert.assertNotNull(hi);
-        
-        Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED) );
-        Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED) );
-        Assert.assertNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO) );
-        
-        Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)) );
-        Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED)) );
-        Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED)),
-            "1");
-        
-        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
-            MutableMap.of("name", "Bob"));
-        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
-        Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)),
-            "Bob");
-    }
-
-    @Test
-    public void testEntityWithConfigurableInitializerEmpty() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- type: "+TestEntity.class.getName()+"\n"+
-                "  brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+" } ]";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
-            MutableMap.of("name", "Bob"));
-        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
-    }
-
-    @Test
-    public void testEntityWithConfigurableInitializerNonEmpty() throws Exception {
-        String yaml =
-                "services:\n"+
-                "- type: "+TestEntity.class.getName()+"\n"+
-                "  brooklyn.initializers: [ { "
-                  + "type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+","
-                  + "brooklyn.config: { "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.HELLO_WORD+": Hey }"
-                  + " } ]";
-        
-        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
-        
-        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
-            MutableMap.of("name", "Bob"));
-        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hey Bob");
-    }
-
-    @Test
-    public void testEntityTypeAsImpl() throws Exception {
-        String yaml =
-                "services:"+"\n"+
-                "- type: "+CustomTestEntityImpl.class.getName()+"\n";
-
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-
-        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
-        assertEquals(testEntity.getEntityType().getName(), "CustomTestEntityImpl");
-    }
-    
-    public static class CustomTestEntityImpl extends TestEntityImpl {
-        public CustomTestEntityImpl() {
-            System.out.println("in CustomTestEntityImpl");
-        }
-        @Override
-        protected String getEntityTypeName() {
-            return "CustomTestEntityImpl";
-        }
-    }
-
-    @Test
-    public void testWrapperAppMarkerExists() throws Exception {
-        Entity entity = createAndStartApplication(
-                "services:",
-                "- type: " + BasicEntity.class.getName());
-        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerDoesntExist() throws Exception {
-        Entity entity = createAndStartApplication(
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerForced() throws Exception {
-        Entity entity = createAndStartApplication(
-                "wrappedApp: true",
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerUnforced() throws Exception {
-        Entity entity = createAndStartApplication(
-                "wrappedApp: false",
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
deleted file mode 100644
index 77ca882..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
+++ /dev/null
@@ -1,125 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-
-import java.io.File;
-import java.io.Reader;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Application;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.io.Files;
-
-@Test
-public class JavaWebAppWithDslYamlRebindIntegrationTest extends AbstractYamlTest {
-    
-    private static final Logger log = LoggerFactory.getLogger(JavaWebAppWithDslYamlRebindIntegrationTest.class);
-    
-    protected ClassLoader classLoader = getClass().getClassLoader();
-    protected File mementoDir;
-    protected Set<ManagementContext> mgmtContexts = MutableSet.of();
-
-    @Override
-    protected LocalManagementContext newTestManagementContext() {
-        if (mementoDir!=null) throw new IllegalStateException("already created mgmt context");
-        mementoDir = Files.createTempDir();
-        log.info("Test "+getClass()+" persisting to "+mementoDir);
-
-        LocalManagementContext mgmt =
-            RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
-        mgmtContexts.add(mgmt);
-        return mgmt;
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    @Override
-    public void tearDown() {
-        for (ManagementContext mgmt: mgmtContexts) Entities.destroyAll(mgmt);
-        super.tearDown();
-        mementoDir = null;
-        mgmtContexts.clear();
-    }
-
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-
-    public Application rebind(Application app) throws Exception {
-        RebindTestUtils.waitForPersisted(app);
-        // optionally for good measure can also check this:
-//        RebindTestUtils.checkCurrentMementoSerializable(app);
-        Application result = RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
-        mgmtContexts.add(result.getManagementContext());
-        return result;
-    }
-
-    /** as {@link JavaWebAppsIntegrationTest#testWithDbDeploy()} but with rebind */
-    @Test(groups="Integration")
-    public void testJavaWebAppDeployAndRebind() throws Exception {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-        final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());
-
-        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
-        for (Task<?> t: tasks) t.blockUntilEnded();
-        Entities.dumpInfo(app);
-
-        Application app2 = rebind(app);
-        Assert.assertEquals(app2.getChildren().size(), 2);
-    }
-
-    // test for https://github.com/brooklyncentral/brooklyn/issues/1422
-    @Test(groups="Integration")
-    public void testJavaWebWithMemberSpecRebind() throws Exception {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("test-java-web-app-spec-and-db-with-function.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-        final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());
-
-        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
-        for (Task<?> t: tasks) t.blockUntilEnded();
-        Entities.dumpInfo(app);
-        
-        Application app2 = rebind(app);
-        Assert.assertEquals(app2.getChildren().size(), 2);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
deleted file mode 100644
index eb14811..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
+++ /dev/null
@@ -1,272 +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 io.brooklyn.camp.brooklyn;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.PlatformComponent;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.atomic.AtomicInteger;
-
-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 brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.webapp.DynamicWebAppCluster;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.WebAppService;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.policy.Policy;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.test.Asserts;
-import brooklyn.test.EntityTestUtils;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.net.Urls;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.Iterables;
-
-@Test(groups="Integration")
-public class JavaWebAppsIntegrationTest {
-
-    private static final Logger log = LoggerFactory.getLogger(JavaWebAppsIntegrationTest.class);
-    
-    private ManagementContext brooklynMgmt;
-    private BrooklynCampPlatform platform;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        BrooklynCampPlatformLauncherNoServer launcher = new BrooklynCampPlatformLauncherNoServer();
-        launcher.launch();
-        brooklynMgmt = launcher.getBrooklynMgmt();
-      
-        platform = new BrooklynCampPlatform(
-              PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
-              brooklynMgmt);
-    }
-    
-    @AfterMethod
-    public void teardown() {
-        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
-    }
-    
-    public void testSimpleYamlDeploy() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-        try {
-            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-            log.info("Test - created "+assembly);
-            
-            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-            log.info("App - "+app);
-            Assert.assertEquals(app.getDisplayName(), "sample-single-jboss");
-                        
-            // locations set on AT in this yaml
-            Assert.assertEquals(app.getLocations().size(), 1);
-
-            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
-            log.info("Waiting on "+tasks.size()+" task(s)");
-            for (Task<?> t: tasks) {
-                t.blockUntilEnded();
-            }
-
-            log.info("App started:");
-            Entities.dumpInfo(app);
-
-            Assert.assertEquals(app.getChildren().size(), 1);
-            Assert.assertEquals(app.getChildren().iterator().next().getDisplayName(), "tomcat1");
-            Assert.assertEquals(app.getChildren().iterator().next().getLocations().size(), 1);
-            
-            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                @Override public String call() throws Exception {
-                    String url = app.getChildren().iterator().next().getAttribute(JavaWebAppService.ROOT_URL);
-                    return checkNotNull(url, "url of %s", app);
-                }});
-        
-            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                    @Override public String call() throws Exception {
-                        return new ResourceUtils(this).getResourceAsString(url);
-                    }});
-            
-            log.info("App URL for "+app+": "+url);
-            Assert.assertTrue(url.contains("928"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
-            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
-            Assert.assertTrue(!platform.assemblies().isEmpty());
-        } catch (Exception e) {
-            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    public void testWithDbDeploy() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-        try {
-            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-            log.info("Test - created "+assembly);
-            
-            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-            log.info("App - "+app);
-            
-            // locations set on individual services here
-            Assert.assertEquals(app.getLocations().size(), 0);
-            
-            Iterator<ResolvableLink<PlatformComponent>> pcs = assembly.getPlatformComponents().links().iterator();
-            PlatformComponent pc1 = pcs.next().resolve();
-            Entity cluster = brooklynMgmt.getEntityManager().getEntity(pc1.getId());
-            log.info("pc1 - "+pc1+" - "+cluster);
-            
-            PlatformComponent pc2 = pcs.next().resolve();
-            log.info("pc2 - "+pc2);
-            
-            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
-            log.info("Waiting on "+tasks.size()+" task(s)");
-            AtomicInteger i = new AtomicInteger(0);
-            for (Task<?> t: tasks) {
-                t.blockUntilEnded();
-                log.info("Completed task #" + i.incrementAndGet());
-            }
-
-            log.info("App started:");
-            Entities.dumpInfo(app);
-
-            EntityTestUtils.assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-            Assert.assertEquals(app.getAttribute(Attributes.SERVICE_UP), Boolean.TRUE);
-            
-            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                    @Override public String call() throws Exception {
-                        Entity cluster = Iterables.getOnlyElement( Iterables.filter(app.getChildren(), WebAppService.class) );
-                        String url = cluster.getAttribute(JavaWebAppService.ROOT_URL);
-                        return checkNotNull(url, "url of %s", cluster);
-                    }});
-            
-            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                    @Override public String call() throws Exception {
-                        return new ResourceUtils(this).getResourceAsString(url);
-                    }});
-            
-            log.info("App URL for "+app+": "+url);
-            Assert.assertTrue(url.contains("921"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
-            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
-            Assert.assertTrue(!platform.assemblies().isEmpty());
-            
-            String dbPage = new ResourceUtils(this).getResourceAsString(Urls.mergePaths(url, "db.jsp"));
-            Assert.assertTrue(dbPage.contains("Isaac Asimov"), "db.jsp does not mention Isaac Asimov, probably the DB did not get initialised:\n"+dbPage);
-        } catch (Exception e) {
-            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    public void testWithPolicyDeploy() {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-policy.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-
-        try {
-            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-            log.info("Test - created "+assembly);
-            
-            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
-            log.info("App - "+app);
-            
-            // locations set on individual services here
-            Assert.assertEquals(app.getLocations().size(), 0);
-            
-            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
-            log.info("Waiting on "+tasks.size()+" task(s)");
-            for (Task<?> t: tasks) {
-                t.blockUntilEnded();
-            }
-            
-            log.info("App started:");
-            Entities.dumpInfo(app);
-            
-            Iterator<ResolvableLink<PlatformComponent>> pcs = assembly.getPlatformComponents().links().iterator();
-            PlatformComponent clusterComponent = null;
-            while (pcs.hasNext() && clusterComponent == null) {
-                PlatformComponent component = pcs.next().resolve();
-                if (component.getName().equals("My Web with Policy"))
-                    clusterComponent = component;
-            }
-            Assert.assertNotNull(clusterComponent, "Database PlatformComponent not found");
-            Entity cluster = brooklynMgmt.getEntityManager().getEntity(clusterComponent.getId());
-            log.info("pc1 - "+clusterComponent+" - "+cluster);
-            
-            Assert.assertEquals(cluster.getPolicies().size(), 1);
-            Policy policy = cluster.getPolicies().iterator().next();
-            Assert.assertNotNull(policy);
-            Assert.assertTrue(policy instanceof AutoScalerPolicy, "policy="+policy);
-            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.MAX_POOL_SIZE), (Integer)5);
-            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.MIN_POOL_SIZE), (Integer)1);
-            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC), DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE);
-            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC_LOWER_BOUND), (Integer)10);
-            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC_UPPER_BOUND), (Integer)100);
-            Assert.assertTrue(policy.isRunning());
-
-            EntityTestUtils.assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-            Assert.assertEquals(app.getAttribute(Attributes.SERVICE_UP), Boolean.TRUE);
-            
-            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                    @Override public String call() throws Exception {
-                        Entity cluster = Iterables.getOnlyElement( Iterables.filter(app.getChildren(), WebAppService.class) );
-                        String url = cluster.getAttribute(JavaWebAppService.ROOT_URL);
-                        return checkNotNull(url, "url of %s", cluster);
-                    }});
-            
-            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
-                    @Override public String call() throws Exception {
-                        return new ResourceUtils(this).getResourceAsString(url);
-                    }});
-            
-            log.info("App URL for "+app+": "+url);
-            Assert.assertTrue(url.contains("921"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
-            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
-            Assert.assertTrue(!platform.assemblies().isEmpty());
-            
-            String dbPage = new ResourceUtils(this).getResourceAsString(Urls.mergePaths(url, "db.jsp"));
-            Assert.assertTrue(dbPage.contains("Isaac Asimov"), "db.jsp does not mention Isaac Asimov, probably the DB did not get initialised:\n"+dbPage);
-        } catch (Exception e) {
-            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
deleted file mode 100644
index a9ddf63..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
+++ /dev/null
@@ -1,144 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-import io.brooklyn.camp.spi.pdp.DeploymentPlan;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Iterator;
-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 brooklyn.entity.basic.Entities;
-import brooklyn.management.ManagementContext;
-import brooklyn.test.entity.LocalManagementContextForTests;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.DeferredSupplier;
-
-@Test
-public class JavaWebAppsMatchingTest {
-
-    private static final Logger log = LoggerFactory.getLogger(JavaWebAppsMatchingTest.class);
-    
-    private ManagementContext brooklynMgmt;
-    private BrooklynCampPlatform platform;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        brooklynMgmt = new LocalManagementContextForTests();
-        platform = new BrooklynCampPlatform(
-              PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
-              brooklynMgmt);
-    }
-    
-    // FIXME all commented-out lines require camp server
-    
-    @AfterMethod(alwaysRun=true)
-    public void teardown() {
-        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
-    }
-    
-    public void testSimpleYamlParse() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
-        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
-        log.info("DP is:\n"+plan.toString());
-        Assert.assertEquals(plan.getServices().size(), 1);
-        Assert.assertEquals(plan.getName(), "sample-single-jboss");
-    }
-    
-    public void testSimpleYamlMatch() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-        
-        Assert.assertEquals(at.getName(), "sample-single-jboss");
-    }
-
-    public void testExampleFunctionsYamlMatch() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("example-with-function.yaml"));
-        
-        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
-        log.info("DP is:\n"+plan.toString());
-        Map<?,?> cfg1 = (Map<?, ?>) plan.getServices().get(0).getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
-        Map<?,?> cfg = MutableMap.copyOf(cfg1);
-        
-        Assert.assertEquals(cfg.remove("literalValue1"), "$brooklyn: is a fun place");
-        Assert.assertEquals(cfg.remove("literalValue2"), "$brooklyn: is a fun place");
-        Assert.assertEquals(cfg.remove("literalValue3"), "$brooklyn: is a fun place");
-        Assert.assertEquals(cfg.remove("literalValue4"), "$brooklyn: is a fun place");
-        Assert.assertEquals(cfg.remove("$brooklyn:1"), "key to the city");
-        Assert.assertTrue(cfg.isEmpty(), ""+cfg);
-
-        Assert.assertEquals(plan.getName(), "example-with-function");
-        Assert.assertEquals(plan.getCustomAttributes().get("location"), "localhost");
-        
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(plan);
-        
-        Assert.assertEquals(at.getName(), "example-with-function");
-        Assert.assertEquals(at.getCustomAttributes().get("location"), "localhost");
-        
-        PlatformComponentTemplate pct = at.getPlatformComponentTemplates().links().iterator().next().resolve();
-        Object cfg2 = pct.getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
-        Assert.assertEquals(cfg2, cfg1);
-    }
-
-    public void testJavaAndDbWithFunctionYamlMatch() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
-        assertWebDbWithFunctionValid(input);
-    }
-    
-    public void testJavaAndDbWithFunctionYamlMatch2() throws IOException {
-        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function-2.yaml"));
-        assertWebDbWithFunctionValid(input);
-    }
-    
-    protected void assertWebDbWithFunctionValid(Reader input) { 
-        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
-        log.info("DP is:\n"+plan.toString());
-        
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(plan);
-        
-        Assert.assertEquals(at.getName(), "java-cluster-db-example");
-
-        Iterator<ResolvableLink<PlatformComponentTemplate>> pcti = at.getPlatformComponentTemplates().links().iterator();
-        PlatformComponentTemplate pct1 = pcti.next().resolve(); 
-
-        PlatformComponentTemplate pct2 = pcti.next().resolve(); 
-
-        Map<?,?> config = (Map<?, ?>) pct1.getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
-        Map<?,?> javaSysProps = (Map<?, ?>) config.get("java.sysprops");
-        Object dbUrl = javaSysProps.get("brooklyn.example.db.url");
-        Assert.assertTrue(dbUrl instanceof DeferredSupplier<?>, "url is: "+dbUrl);
-        
-        Assert.assertEquals(pct2.getCustomAttributes().get("planId"), "db");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/LocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/LocationsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/LocationsYamlTest.java
deleted file mode 100644
index d22b73e..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/LocationsYamlTest.java
+++ /dev/null
@@ -1,285 +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 io.brooklyn.camp.brooklyn;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-import java.io.StringReader;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.Entity;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.MultiLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class LocationsYamlTest extends AbstractYamlTest {
-    private static final Logger log = LoggerFactory.getLogger(LocationsYamlTest.class);
-
-    @Test
-    public void testLocationString() throws Exception {
-        String yaml = 
-                "location: localhost\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
-        assertNotNull(loc);
-    }
-
-    @Test
-    public void testLocationComplexString() throws Exception {
-        String yaml = 
-                "location: localhost:(name=myname)\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
-        assertEquals(loc.getDisplayName(), "myname");
-    }
-
-    @Test
-    public void testLocationSplitLineWithNoConfig() throws Exception {
-        String yaml = 
-                "location:\n"+
-                "  localhost\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
-        assertNotNull(loc);
-    }
-
-    @Test
-    public void testMultiLocations() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- localhost:(name=loc1)\n"+
-                "- localhost:(name=loc2)\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        List<Location> locs = ImmutableList.copyOf(app.getLocations());
-        assertEquals(locs.size(), 2, "locs="+locs);
-        LocalhostMachineProvisioningLocation loc1 = (LocalhostMachineProvisioningLocation) locs.get(0);
-        LocalhostMachineProvisioningLocation loc2 = (LocalhostMachineProvisioningLocation) locs.get(1);
-        assertEquals(loc1.getDisplayName(), "loc1");
-        assertEquals(loc2.getDisplayName(), "loc2");
-    }
-
-    @Test
-    public void testLocationConfig() throws Exception {
-        String yaml = 
-                "location:\n"+
-                "  localhost:\n"+
-                "    displayName: myname\n"+
-                "    myconfkey: myconfval\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(app.getLocations());
-        assertEquals(loc.getDisplayName(), "myname");
-        assertEquals(loc.config().getLocalBag().getStringKey("myconfkey"), "myconfval");
-    }
-
-    @Test
-    public void testMultiLocationConfig() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- localhost:\n"+
-                "    displayName: myname1\n"+
-                "    myconfkey: myconfval1\n"+
-                "- localhost:\n"+
-                "    displayName: myname2\n"+
-                "    myconfkey: myconfval2\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        List<Location> locs = ImmutableList.copyOf(app.getLocations());
-        assertEquals(locs.size(), 2, "locs="+locs);
-        LocalhostMachineProvisioningLocation loc1 = (LocalhostMachineProvisioningLocation) locs.get(0);
-        LocalhostMachineProvisioningLocation loc2 = (LocalhostMachineProvisioningLocation) locs.get(1);
-        assertEquals(loc1.getDisplayName(), "myname1");
-        assertEquals(loc1.config().getLocalBag().getStringKey("myconfkey"), "myconfval1");
-        assertEquals(loc2.getDisplayName(), "myname2");
-        assertEquals(loc2.config().getLocalBag().getStringKey("myconfkey"), "myconfval2");
-    }
-
-    // TODO Fails because PlanInterpretationContext constructor throws NPE on location's value (using ImmutableMap).
-    @Test(groups="WIP")
-    public void testLocationBlank() throws Exception {
-        String yaml = 
-                "location: \n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        assertTrue(app.getLocations().isEmpty(), "locs="+app.getLocations());
-    }
-
-    @Test
-    public void testInvalidLocationAndLocations() throws Exception {
-        String yaml = 
-                "location: localhost\n"+
-                "locations:\n"+
-                "- localhost\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        try {
-            createStartWaitAndLogApplication(new StringReader(yaml));
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("Conflicting 'location' and 'locations'")) throw e;
-        }
-    }
-
-    @Test
-    public void testInvalidLocationList() throws Exception {
-        // should have used "locations:" instead of "location:"
-        String yaml = 
-                "location:\n"+
-                "- localhost\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        try {
-            createStartWaitAndLogApplication(new StringReader(yaml));
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("must be a string or map")) throw e;
-        }
-    }
-    
-    @Test
-    public void testRootLocationPassedToChild() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- localhost:(name=loc1)\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        Entity child = Iterables.getOnlyElement(app.getChildren());
-        LocalhostMachineProvisioningLocation loc = (LocalhostMachineProvisioningLocation) Iterables.getOnlyElement(child.getLocations());
-        assertEquals(loc.getDisplayName(), "loc1");
-    }
-
-    @Test
-    public void testByonYamlHosts() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- byon:\n"+
-                "    user: root\n"+
-                "    privateKeyFile: /tmp/key_file\n"+
-                "    hosts: \n"+
-                "    - 127.0.0.1\n"+
-                "    - brooklyn@127.0.0.2\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        Entity child = Iterables.getOnlyElement(app.getChildren());
-        FixedListMachineProvisioningLocation<?> loc = (FixedListMachineProvisioningLocation<?>) Iterables.getOnlyElement(child.getLocations());
-        Assert.assertEquals(loc.getChildren().size(), 2);
-        
-        SshMachineLocation l1 = (SshMachineLocation)loc.obtain();
-        assertUserAddress(l1, "root", "127.0.0.1");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.2");
-        Assert.assertEquals(l1.getConfig(SshMachineLocation.PRIVATE_KEY_FILE), "/tmp/key_file");
-    }
-
-    @Test
-    public void testByonYamlHostsString() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- byon:\n"+
-                "    user: root\n"+
-                "    hosts: \"{127.0.{0,127}.{1-2},brooklyn@127.0.0.127}\"\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        Entity child = Iterables.getOnlyElement(app.getChildren());
-        FixedListMachineProvisioningLocation<?> loc = (FixedListMachineProvisioningLocation<?>) Iterables.getOnlyElement(child.getLocations());
-        Assert.assertEquals(loc.getChildren().size(), 5);
-        
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.1");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.2");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.1");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.2");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.127");
-    }
-
-    @Test
-    public void testMultiByonYaml() throws Exception {
-        String yaml = 
-                "locations:\n"+
-                "- multi:\n"+
-                "   targets:\n"+
-                "   - byon:\n"+
-                "      user: root\n"+
-                "      hosts: 127.0.{0,127}.{1-2}\n"+
-                "   - byon:\n"+
-                "      user: brooklyn\n"+
-                "      hosts:\n"+
-                "      - 127.0.0.127\n"+
-                "services:\n"+
-                "- serviceType: brooklyn.test.entity.TestEntity\n";
-        
-        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
-        Entity child = Iterables.getOnlyElement(app.getChildren());
-        MultiLocation<?> loc = (MultiLocation<?>) Iterables.getOnlyElement(child.getLocations());
-        Assert.assertEquals(loc.getSubLocations().size(), 2);
-        
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.1");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.2");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.1");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.127.2");
-        assertUserAddress((SshMachineLocation)loc.obtain(), "brooklyn", "127.0.0.127");
-    }
-
-    public static void assertUserAddress(MachineLocation l, String user, String address) {
-        Assert.assertEquals(l.getAddress().getHostAddress(), address);
-        if (!Strings.isBlank(user)) Assert.assertEquals(((SshMachineLocation)l).getUser(), user);        
-    }
-    
-    @Override
-    protected Logger getLogger() {
-        return log;
-    }
-    
-}


[20/20] incubator-brooklyn git commit: This closes #797

Posted by ha...@apache.org.
This closes #797


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

Branch: refs/heads/master
Commit: 7bc08a05ff9ca539a5674405c8d626284003d68a
Parents: 846143c e406d1a
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Wed Aug 5 16:37:51 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Wed Aug 5 16:37:51 2015 -0400

----------------------------------------------------------------------
 .../com/acme/sample/brooklyn/SampleMain.java    |   2 +-
 .../camp/brooklyn/BrooklynCampConstants.java    |  50 -
 .../camp/brooklyn/BrooklynCampPlatform.java     |  76 --
 .../BrooklynCampPlatformLauncherAbstract.java   |  73 --
 .../BrooklynCampPlatformLauncherNoServer.java   |  36 -
 .../camp/brooklyn/BrooklynCampReservedKeys.java |  29 -
 .../camp/brooklyn/YamlLauncherAbstract.java     | 133 ---
 .../camp/brooklyn/YamlLauncherNoServer.java     |  39 -
 .../BrooklynAssemblyTemplateInstantiator.java   | 282 ------
 .../BrooklynComponentTemplateResolver.java      | 491 ---------
 .../BrooklynEntityDecorationResolver.java       | 181 ----
 .../spi/creation/BrooklynEntityMatcher.java     | 193 ----
 .../creation/BrooklynYamlLocationResolver.java  | 142 ---
 .../creation/BrooklynYamlTypeInstantiator.java  | 208 ----
 .../spi/creation/EntitySpecConfiguration.java   |  58 --
 .../service/BrooklynServiceTypeResolver.java    |  72 --
 .../service/CatalogServiceTypeResolver.java     |  78 --
 .../service/ChefServiceTypeResolver.java        |  62 --
 .../service/JavaServiceTypeResolver.java        |  39 -
 .../creation/service/ServiceTypeResolver.java   |  73 --
 .../spi/dsl/BrooklynDslDeferredSupplier.java    |  99 --
 .../spi/dsl/BrooklynDslInterpreter.java         | 188 ----
 .../camp/brooklyn/spi/dsl/DslUtils.java         |  44 -
 .../spi/dsl/methods/BrooklynDslCommon.java      | 302 ------
 .../brooklyn/spi/dsl/methods/DslComponent.java  | 320 ------
 .../camp/brooklyn/spi/dsl/parse/DslParser.java  | 144 ---
 .../spi/dsl/parse/FunctionWithArgs.java         |  57 --
 .../brooklyn/spi/dsl/parse/QuotedString.java    |  49 -
 .../lookup/AbstractBrooklynResourceLookup.java  |  36 -
 .../lookup/AbstractTemplateBrooklynLookup.java  |  62 --
 .../spi/lookup/AssemblyBrooklynLookup.java      |  69 --
 .../lookup/AssemblyTemplateBrooklynLookup.java  |  70 --
 .../brooklyn/spi/lookup/BrooklynUrlLookup.java  |  38 -
 .../lookup/PlatformComponentBrooklynLookup.java |  61 --
 ...PlatformComponentTemplateBrooklynLookup.java |  59 --
 .../platform/BrooklynImmutableCampPlatform.java | 107 --
 .../camp/brooklyn/BrooklynCampConstants.java    |  50 +
 .../camp/brooklyn/BrooklynCampPlatform.java     |  78 ++
 .../BrooklynCampPlatformLauncherAbstract.java   |  73 ++
 .../BrooklynCampPlatformLauncherNoServer.java   |  36 +
 .../camp/brooklyn/BrooklynCampReservedKeys.java |  29 +
 .../camp/brooklyn/YamlLauncherAbstract.java     | 133 +++
 .../camp/brooklyn/YamlLauncherNoServer.java     |  39 +
 .../BrooklynAssemblyTemplateInstantiator.java   | 283 ++++++
 .../BrooklynComponentTemplateResolver.java      | 490 +++++++++
 .../BrooklynEntityDecorationResolver.java       | 180 ++++
 .../spi/creation/BrooklynEntityMatcher.java     | 193 ++++
 .../creation/BrooklynYamlLocationResolver.java  | 142 +++
 .../creation/BrooklynYamlTypeInstantiator.java  | 208 ++++
 .../spi/creation/EntitySpecConfiguration.java   |  58 ++
 .../service/BrooklynServiceTypeResolver.java    |  71 ++
 .../service/CatalogServiceTypeResolver.java     |  78 ++
 .../service/ChefServiceTypeResolver.java        |  61 ++
 .../service/JavaServiceTypeResolver.java        |  39 +
 .../creation/service/ServiceTypeResolver.java   |  73 ++
 .../spi/dsl/BrooklynDslDeferredSupplier.java    |  99 ++
 .../spi/dsl/BrooklynDslInterpreter.java         | 188 ++++
 .../camp/brooklyn/spi/dsl/DslUtils.java         |  44 +
 .../spi/dsl/methods/BrooklynDslCommon.java      | 301 ++++++
 .../brooklyn/spi/dsl/methods/DslComponent.java  | 320 ++++++
 .../camp/brooklyn/spi/dsl/parse/DslParser.java  | 144 +++
 .../spi/dsl/parse/FunctionWithArgs.java         |  57 ++
 .../brooklyn/spi/dsl/parse/QuotedString.java    |  49 +
 .../lookup/AbstractBrooklynResourceLookup.java  |  36 +
 .../lookup/AbstractTemplateBrooklynLookup.java  |  62 ++
 .../spi/lookup/AssemblyBrooklynLookup.java      |  69 ++
 .../lookup/AssemblyTemplateBrooklynLookup.java  |  70 ++
 .../brooklyn/spi/lookup/BrooklynUrlLookup.java  |  38 +
 .../lookup/PlatformComponentBrooklynLookup.java |  61 ++
 ...PlatformComponentTemplateBrooklynLookup.java |  59 ++
 .../platform/BrooklynImmutableCampPlatform.java | 109 ++
 ...lyn.spi.creation.service.ServiceTypeResolver |  22 -
 ...lyn.spi.creation.service.ServiceTypeResolver |  22 +
 .../camp/brooklyn/AbstractYamlRebindTest.java   | 206 ----
 .../camp/brooklyn/AbstractYamlTest.java         | 182 ----
 .../io/brooklyn/camp/brooklyn/AppYamlTest.java  | 119 ---
 .../BrooklynYamlTypeInstantiatorTest.java       |  76 --
 .../camp/brooklyn/ByonLocationsYamlTest.java    | 281 ------
 .../camp/brooklyn/DslAndRebindYamlTest.java     | 245 -----
 .../brooklyn/EmptySoftwareProcessYamlTest.java  | 103 --
 .../EnrichersSlightlySimplerYamlTest.java       | 134 ---
 .../camp/brooklyn/EnrichersYamlTest.java        | 257 -----
 .../brooklyn/EntitiesYamlIntegrationTest.java   |  71 --
 .../camp/brooklyn/EntitiesYamlTest.java         | 919 -----------------
 ...aWebAppWithDslYamlRebindIntegrationTest.java | 125 ---
 .../brooklyn/JavaWebAppsIntegrationTest.java    | 272 -----
 .../camp/brooklyn/JavaWebAppsMatchingTest.java  | 144 ---
 .../camp/brooklyn/LocationsYamlTest.java        | 285 ------
 .../camp/brooklyn/MapReferenceYamlTest.java     | 130 ---
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 280 ------
 .../camp/brooklyn/PoliciesYamlTest.java         | 215 ----
 .../camp/brooklyn/ReferencedYamlTest.java       | 180 ----
 .../brooklyn/ReferencingYamlTestEntity.java     |  66 --
 .../brooklyn/ReferencingYamlTestEntityImpl.java |  25 -
 .../brooklyn/ReloadBrooklynPropertiesTest.java  |  87 --
 .../camp/brooklyn/TestEntityWithInitConfig.java |  35 -
 .../brooklyn/TestEntityWithInitConfigImpl.java  |  59 --
 .../camp/brooklyn/TestReferencingEnricher.java  |  34 -
 .../camp/brooklyn/TestReferencingPolicy.java    |  34 -
 .../TestSensorAndEffectorInitializer.java       |  86 --
 .../brooklyn/VanillaBashNetcatYamlTest.java     | 113 ---
 .../io/brooklyn/camp/brooklyn/WrapAppTest.java  |  93 --
 .../catalog/AbstractCatalogXmlTest.java         | 109 --
 .../CatalogOsgiVersionMoreEntityTest.java       | 261 -----
 .../brooklyn/catalog/CatalogXmlOsgiTest.java    |  37 -
 .../brooklyn/catalog/CatalogXmlVersionTest.java |  58 --
 .../brooklyn/catalog/CatalogYamlCombiTest.java  | 145 ---
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 781 ---------------
 .../catalog/CatalogYamlLocationTest.java        | 248 -----
 .../brooklyn/catalog/CatalogYamlPolicyTest.java | 196 ----
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 132 ---
 .../catalog/CatalogYamlTemplateTest.java        |  96 --
 .../catalog/CatalogYamlVersioningTest.java      | 258 -----
 .../camp/brooklyn/catalog/TestBasicApp.java     |  27 -
 .../camp/brooklyn/catalog/TestBasicAppImpl.java |  24 -
 .../camp/brooklyn/spi/dsl/DslParseTest.java     |  79 --
 .../camp/brooklyn/AbstractYamlRebindTest.java   | 208 ++++
 .../camp/brooklyn/AbstractYamlTest.java         | 184 ++++
 .../brooklyn/camp/brooklyn/AppYamlTest.java     | 119 +++
 .../BrooklynYamlTypeInstantiatorTest.java       |  75 ++
 .../camp/brooklyn/ByonLocationsYamlTest.java    | 281 ++++++
 .../camp/brooklyn/DslAndRebindYamlTest.java     | 245 +++++
 .../brooklyn/EmptySoftwareProcessYamlTest.java  | 103 ++
 .../EnrichersSlightlySimplerYamlTest.java       | 134 +++
 .../camp/brooklyn/EnrichersYamlTest.java        | 257 +++++
 .../brooklyn/EntitiesYamlIntegrationTest.java   |  71 ++
 .../camp/brooklyn/EntitiesYamlTest.java         | 919 +++++++++++++++++
 ...aWebAppWithDslYamlRebindIntegrationTest.java | 125 +++
 .../brooklyn/JavaWebAppsIntegrationTest.java    | 275 ++++++
 .../camp/brooklyn/JavaWebAppsMatchingTest.java  | 146 +++
 .../camp/brooklyn/LocationsYamlTest.java        | 285 ++++++
 .../camp/brooklyn/MapReferenceYamlTest.java     | 130 +++
 .../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 280 ++++++
 .../camp/brooklyn/PoliciesYamlTest.java         | 215 ++++
 .../camp/brooklyn/ReferencedYamlTest.java       | 180 ++++
 .../brooklyn/ReferencingYamlTestEntity.java     |  66 ++
 .../brooklyn/ReferencingYamlTestEntityImpl.java |  25 +
 .../brooklyn/ReloadBrooklynPropertiesTest.java  |  89 ++
 .../camp/brooklyn/TestEntityWithInitConfig.java |  35 +
 .../brooklyn/TestEntityWithInitConfigImpl.java  |  59 ++
 .../camp/brooklyn/TestReferencingEnricher.java  |  34 +
 .../camp/brooklyn/TestReferencingPolicy.java    |  34 +
 .../TestSensorAndEffectorInitializer.java       |  86 ++
 .../brooklyn/VanillaBashNetcatYamlTest.java     | 114 +++
 .../brooklyn/camp/brooklyn/WrapAppTest.java     |  93 ++
 .../catalog/AbstractCatalogXmlTest.java         | 109 ++
 .../CatalogOsgiVersionMoreEntityTest.java       | 262 +++++
 .../brooklyn/catalog/CatalogXmlOsgiTest.java    |  37 +
 .../brooklyn/catalog/CatalogXmlVersionTest.java |  58 ++
 .../brooklyn/catalog/CatalogYamlCombiTest.java  | 143 +++
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 780 +++++++++++++++
 .../catalog/CatalogYamlLocationTest.java        | 247 +++++
 .../brooklyn/catalog/CatalogYamlPolicyTest.java | 195 ++++
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 132 +++
 .../catalog/CatalogYamlTemplateTest.java        |  95 ++
 .../catalog/CatalogYamlVersioningTest.java      | 257 +++++
 .../camp/brooklyn/catalog/TestBasicApp.java     |  27 +
 .../camp/brooklyn/catalog/TestBasicAppImpl.java |  24 +
 .../camp/brooklyn/spi/dsl/DslParseTest.java     |  79 ++
 .../more-entities-osgi-catalog-scan.yaml        |  32 -
 .../more-entity-v1-called-v1-osgi-catalog.yaml  |  27 -
 .../catalog/more-entity-v1-osgi-catalog.yaml    |  27 -
 ...more-entity-v1-with-policy-osgi-catalog.yaml |  29 -
 .../catalog/more-entity-v2-osgi-catalog.yaml    |  28 -
 .../more-policies-osgi-catalog-scan.yaml        |  32 -
 .../catalog/simple-policy-osgi-catalog.yaml     |  27 -
 .../more-entities-osgi-catalog-scan.yaml        |  32 +
 .../more-entity-v1-called-v1-osgi-catalog.yaml  |  27 +
 .../catalog/more-entity-v1-osgi-catalog.yaml    |  27 +
 ...more-entity-v1-with-policy-osgi-catalog.yaml |  29 +
 .../catalog/more-entity-v2-osgi-catalog.yaml    |  28 +
 .../more-policies-osgi-catalog-scan.yaml        |  32 +
 .../catalog/simple-policy-osgi-catalog.yaml     |  27 +
 .../camp/src/test/resources/simple-catalog.xml  |   2 +-
 .../resources/test-entity-with-init-config.yaml |   2 +-
 .../resources/test-referencing-enrichers.yaml   |  26 +-
 .../resources/test-referencing-entities.yaml    |  12 +-
 .../resources/test-referencing-policies.yaml    |  26 +-
 .../main/java/brooklyn/cli/AbstractMain.java    | 253 -----
 .../main/java/brooklyn/cli/CloudExplorer.java   | 381 -------
 .../src/main/java/brooklyn/cli/ItemLister.java  | 272 -----
 usage/cli/src/main/java/brooklyn/cli/Main.java  | 986 ------------------
 .../java/brooklyn/cli/lister/ClassFinder.java   | 153 ---
 .../brooklyn/cli/lister/ItemDescriptors.java    | 173 ----
 .../org/apache/brooklyn/cli/AbstractMain.java   | 254 +++++
 .../org/apache/brooklyn/cli/CloudExplorer.java  | 381 +++++++
 .../org/apache/brooklyn/cli/ItemLister.java     | 273 +++++
 .../main/java/org/apache/brooklyn/cli/Main.java | 987 +++++++++++++++++++
 .../apache/brooklyn/cli/lister/ClassFinder.java | 153 +++
 .../brooklyn/cli/lister/ItemDescriptors.java    | 173 ++++
 .../cli/src/test/java/brooklyn/cli/CliTest.java | 604 ------------
 .../brooklyn/cli/CloudExplorerLiveTest.java     | 209 ----
 .../java/org/apache/brooklyn/cli/CliTest.java   | 605 ++++++++++++
 .../brooklyn/cli/CloudExplorerLiveTest.java     | 209 ++++
 .../resources/example-app-app-location.yaml     |   2 +-
 .../resources/example-app-entity-location.yaml  |   2 +-
 .../test/resources/example-app-no-location.yaml |   2 +-
 .../brooklyn/launcher/BrooklynLauncher.java     |   4 +-
 .../camp/BrooklynCampPlatformLauncher.java      |   5 +-
 .../launcher/camp/SimpleYamlLauncher.java       |   4 +-
 .../blueprints/AbstractBlueprintTest.java       |   2 +-
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |   4 +-
 .../brooklyn/rest/HaMasterCheckFilterTest.java  |   2 +-
 .../rest/testing/BrooklynRestApiTest.java       |   2 +-
 204 files changed, 14641 insertions(+), 14631 deletions(-)
----------------------------------------------------------------------



[16/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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
new file mode 100644
index 0000000..c413e4d
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -0,0 +1,490 @@
+/*
+ * 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 io.brooklyn.camp.spi.AbstractResource;
+import io.brooklyn.camp.spi.ApplicationComponentTemplate;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.BrooklynTags;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.proxying.InternalEntityFactory;
+import brooklyn.location.Location;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ManagementContextInjectable;
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
+import brooklyn.management.internal.ManagementContextInternal;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.flags.FlagUtils;
+import brooklyn.util.flags.FlagUtils.FlagConfigKeyAndValueRecord;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.javalang.Reflections;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+/**
+ * This generates instances of a template resolver that use a {@link ServiceTypeResolver}
+ * to parse the {@code serviceType} line in the template.
+ */
+public class BrooklynComponentTemplateResolver {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynComponentTemplateResolver.class);
+
+    private final BrooklynClassLoadingContext loader;
+    private final ManagementContext mgmt;
+    private final ConfigBag attrs;
+    private final Maybe<AbstractResource> template;
+    private final BrooklynYamlTypeInstantiator.Factory yamlLoader;
+    private final String type;
+    private final ServiceTypeResolver typeResolver;
+    private final AtomicBoolean alreadyBuilt = new AtomicBoolean(false);
+
+    public BrooklynComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate, String type, ServiceTypeResolver typeResolver) {
+        this.loader = loader;
+        this.mgmt = loader.getManagementContext();
+        this.attrs = ConfigBag.newInstanceCopying(attrs);
+        this.template = Maybe.fromNullable(optionalTemplate);
+        this.yamlLoader = new BrooklynYamlTypeInstantiator.Factory(loader, this);
+        this.type = type;
+        this.typeResolver = typeResolver;
+    }
+
+    public BrooklynClassLoadingContext getLoader() { return loader; }
+    public ManagementContext getManagementContext() { return mgmt; }
+    public ConfigBag getAttrs() { return attrs; }
+    public Maybe<AbstractResource> getTemplate() { return template; }
+    public BrooklynYamlTypeInstantiator.Factory getYamlLoader() { return yamlLoader; }
+    public ServiceTypeResolver getServiceTypeResolver() { return typeResolver; }
+    public String getDeclaredType() { return type; }
+    public Boolean isAlreadyBuilt() { return alreadyBuilt.get(); }
+
+    public static class Factory {
+
+        /** returns resolver type based on the service type, inspecting the arguments in order to determine the service type */
+        private static ServiceTypeResolver computeResolverType(BrooklynClassLoadingContext context, String knownServiceType, AbstractResource optionalTemplate, ConfigBag attrs) {
+            String type = getDeclaredType(knownServiceType, optionalTemplate, attrs);
+            return findService(context, type);
+        }
+
+        // TODO This could be extended to support multiple prefixes per resolver and a 'best-match' algorithm
+        protected static ServiceTypeResolver findService(BrooklynClassLoadingContext context, String type) {
+            if (type.indexOf(':') != -1) {
+                String prefix = Splitter.on(":").splitToList(type).get(0);
+                ServiceLoader<ServiceTypeResolver> loader = ServiceLoader.load(ServiceTypeResolver.class,
+                        context.getManagementContext().getCatalogClassLoader());
+                for (ServiceTypeResolver resolver : loader) {
+                   if (prefix.equals(resolver.getTypePrefix())) {
+                       return resolver;
+                   }
+                }
+            }
+            return null;
+        }
+
+        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, Map<String, ?> childAttrs) {
+            return newInstance(context, ConfigBag.newInstance(childAttrs), null);
+        }
+
+        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, AbstractResource template) {
+            return newInstance(context, ConfigBag.newInstance(template.getCustomAttributes()), template);
+        }
+
+        public static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, String serviceType) {
+            return newInstance(context, ConfigBag.newInstance().configureStringKey("serviceType", serviceType), null);
+        }
+
+        private static BrooklynComponentTemplateResolver newInstance(BrooklynClassLoadingContext context, ConfigBag attrs, AbstractResource optionalTemplate) {
+            ServiceTypeResolver typeResolver = computeResolverType(context, null, optionalTemplate, attrs);
+            String type = getDeclaredType(null, optionalTemplate, attrs);
+            if (typeResolver == null) // use default
+                typeResolver = new BrooklynServiceTypeResolver();
+            return new BrooklynComponentTemplateResolver(context, attrs, optionalTemplate, type, typeResolver);
+        }
+
+        public static String getDeclaredType(String knownServiceType, AbstractResource optionalTemplate, @Nullable ConfigBag attrs) {
+            String type = knownServiceType;
+            if (type==null && optionalTemplate!=null) {
+                type = optionalTemplate.getType();
+                if (type.equals(AssemblyTemplate.CAMP_TYPE) || type.equals(PlatformComponentTemplate.CAMP_TYPE) || type.equals(ApplicationComponentTemplate.CAMP_TYPE))
+                    // ignore these values for the type; only subclasses are interesting
+                    type = null;
+            }
+            if (type==null) type = extractServiceTypeAttribute(attrs);
+            return type;
+        }
+
+        private static String extractServiceTypeAttribute(@Nullable ConfigBag attrs) {
+            return BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("service", attrs).orNull();
+        }
+
+        public static boolean supportsType(BrooklynClassLoadingContext context, String serviceType) {
+            ServiceTypeResolver typeResolver = computeResolverType(context, serviceType, null, null);
+            if (typeResolver != null) return true;
+            return newInstance(context, serviceType).canResolve();
+        }
+    }
+
+    protected boolean canResolve() {
+        if (typeResolver.getCatalogItem(this, type)!=null)
+            return true;
+        if (loader.tryLoadClass(getJavaType(), Entity.class).isPresent())
+            return true;
+        return false;
+    }
+
+    /** returns the entity class, if needed in contexts which scan its statics for example */
+    protected Class<? extends Entity> loadEntityClass() {
+        Maybe<Class<? extends Entity>> result = tryLoadEntityClass();
+        if (result.isAbsent())
+            throw new IllegalStateException("Could not find "+typeResolver.getBrooklynType(type), ((Maybe.Absent<?>)result).getException());
+        return result.get();
+    }
+
+    /** tries to load the Java entity class */
+    protected Maybe<Class<? extends Entity>> tryLoadEntityClass() {
+        return loader.tryLoadClass(getJavaType(), Entity.class);
+    }
+
+    // TODO Generalise to have other prefixes (e.g. explicit "catalog:" etc)?
+    protected boolean isJavaTypePrefix() {
+        return type != null && (type.toLowerCase().startsWith("java:") || type.toLowerCase().startsWith("brooklyn:java:"));
+    }
+
+    protected String getJavaType() {
+        CatalogItem<Entity, EntitySpec<?>> item = typeResolver.getCatalogItem(this, type);
+        if (!isJavaTypePrefix() && item != null && item.getJavaType() != null) {
+            return item.getJavaType();
+        } else {
+            return typeResolver.getBrooklynType(type);
+        }
+    }
+
+    /** resolves the spec, updating the loader if a catalog item is loaded */
+    protected <T extends Entity> EntitySpec<T> resolveSpec(Set<String> encounteredCatalogTypes) {
+        if (alreadyBuilt.getAndSet(true))
+            throw new IllegalStateException("Spec can only be used once: "+this);
+
+        EntitySpec<T> spec = createSpec(encounteredCatalogTypes);
+        populateSpec(spec);
+
+        return spec;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    protected <T extends Entity> EntitySpec<T> createSpec(Set<String> encounteredCatalogTypes) {
+        CatalogItem<Entity, EntitySpec<?>> item = getServiceTypeResolver().getCatalogItem(this, getDeclaredType());
+        if (encounteredCatalogTypes==null) encounteredCatalogTypes = MutableSet.of();
+        
+        //Take the symoblicName part of the catalog item only for recursion detection to prevent
+        //cross referencing of different versions. Not interested in non-catalog item types.
+        //Prevent catalog items self-referencing even if explicitly different version.
+        boolean firstOccurrence = (item == null || encounteredCatalogTypes.add(item.getSymbolicName()));
+        boolean recursiveButTryJava = !firstOccurrence;
+
+        // Load a java class from current loader if explicit java prefix, or if no item, or if item is legacy / 
+        // old-style catalog item (item != null && item.getJavaType() != null).
+        // Old-style catalog items (can be defined in catalog.xml only) don't have structure, only a single type, so
+        // they are loaded as a simple java type, only taking the class name from the catalog item instead of the
+        // type value in the YAML. Classpath entries in the item are also used (through the catalog root classloader).
+        if (isJavaTypePrefix() || item == null || item.getJavaType() != null) {
+            return createSpecFromJavaType();
+
+        // Same as above case, but this time force java type loading (either as plain class or through an old-style
+        // catalog item, since we have already loaded a class item with the same name as the type value.
+        } else if (recursiveButTryJava) {
+            if (tryLoadEntityClass().isAbsent()) {
+                throw new IllegalStateException("Recursive reference to " + item + " (and cannot be resolved as a Java type)");
+            }
+            return createSpecFromJavaType();
+
+        // Only case that's left is a catalog item with YAML content - try to parse it recursively
+        // including it's OSGi bundles in the loader classpath.
+        } else {
+            // TODO perhaps migrate to catalog.createSpec ?
+            EntitySpec<?> spec = BrooklynAssemblyTemplateInstantiator.resolveCatalogYamlReferenceSpec(mgmt, item, encounteredCatalogTypes);
+            spec.catalogItemId(item.getId());
+            
+            return (EntitySpec<T>)spec;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected <T extends Entity> EntitySpec<T> createSpecFromJavaType() {
+        Class<T> type = (Class<T>) loadEntityClass();
+        
+        EntitySpec<T> spec;
+        if (type.isInterface()) {
+            spec = EntitySpec.create(type);
+        } else {
+            // If this is a concrete class, particularly for an Application class, we want the proxy
+            // to expose all interfaces it implements.
+            @SuppressWarnings("rawtypes")
+            Class interfaceclazz = (Application.class.isAssignableFrom(type)) ? Application.class : Entity.class;
+            List<Class<?>> additionalInterfaceClazzes = Reflections.getAllInterfaces(type);
+            spec = EntitySpec.create(interfaceclazz).impl(type).additionalInterfaces(additionalInterfaceClazzes);
+        }
+        spec.catalogItemId(CatalogUtils.getCatalogItemIdFromLoader(loader));
+        if (template.isPresent() && template.get().getSourceCode()!=null)
+            spec.tag(BrooklynTags.newYamlSpecTag(template.get().getSourceCode()));
+
+        return spec;
+    }
+
+    //called from BrooklynAssemblyTemplateInstantiator as well
+    @SuppressWarnings("unchecked")
+    protected <T extends Entity> void populateSpec(EntitySpec<T> spec) {
+        String name, templateId=null, planId=null;
+        if (template.isPresent()) {
+            name = template.get().getName();
+            templateId = template.get().getId();
+        } else {
+            name = (String)attrs.getStringKey("name");
+        }
+        planId = (String)attrs.getStringKey("id");
+        if (planId==null)
+            planId = (String) attrs.getStringKey(BrooklynCampConstants.PLAN_ID_FLAG);
+
+        Object childrenObj = attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
+        if (childrenObj != null) {
+            // Creating a new set of encounteredCatalogTypes means that this won't check things recursively;
+            // but we are looking at children so we probably *should* be resetting the recursive list we've looked at;
+            // (but see also, a previous comment here which suggested otherwise? - Apr 2015)
+            Set<String> encounteredCatalogTypes = MutableSet.of();
+
+            Iterable<Map<String,?>> children = (Iterable<Map<String,?>>)childrenObj;
+            for (Map<String,?> childAttrs : children) {
+                BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, childAttrs);
+                EntitySpec<? extends Entity> childSpec = BrooklynAssemblyTemplateInstantiator.resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
+                spec.child(childSpec);
+            }
+        }
+        if (!Strings.isBlank(name))
+            spec.displayName(name);
+        if (templateId != null)
+            spec.configure(BrooklynCampConstants.TEMPLATE_ID, templateId);
+        if (planId != null)
+            spec.configure(BrooklynCampConstants.PLAN_ID, planId);
+
+        List<Location> childLocations = new BrooklynYamlLocationResolver(mgmt).resolveLocations(attrs.getAllConfig(), true);
+        if (childLocations != null)
+            spec.locations(childLocations);
+
+        typeResolver.decorateSpec(this, spec);
+        configureEntityConfig(spec);
+    }
+
+    /** returns new *uninitialised* entity, with just a few of the pieces from the spec;
+     * initialisation occurs soon after, in {@link #initEntity(ManagementContext, Entity, EntitySpec)},
+     * inside an execution context and after entity ID's are recognised
+     */
+    protected <T extends Entity> T newEntity(EntitySpec<T> spec) {
+        Class<? extends T> entityImpl = (spec.getImplementation() != null) ? spec.getImplementation() : mgmt.getEntityManager().getEntityTypeRegistry().getImplementedBy(spec.getType());
+        InternalEntityFactory entityFactory = ((ManagementContextInternal)mgmt).getEntityFactory();
+        T entity = entityFactory.constructEntity(entityImpl, spec);
+
+        String planId = (String)spec.getConfig().get(BrooklynCampConstants.PLAN_ID);
+        if (planId != null) {
+            entity.config().set(BrooklynCampConstants.PLAN_ID, planId);
+        }
+
+        if (spec.getLocations().size() > 0) {
+            ((AbstractEntity)entity).addLocations(spec.getLocations());
+        }
+
+        if (spec.getParent() != null) entity.setParent(spec.getParent());
+
+        return entity;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    protected void configureEntityConfig(EntitySpec<?> spec) {
+        // first take *recognised* flags and config keys from the top-level, and put them in the bag (of brooklyn.config)
+        // attrs will contain only brooklyn.xxx properties when coming from BrooklynEntityMatcher.
+        // Any top-level flags will go into "brooklyn.flags". When resolving a spec from $brooklyn:entitySpec
+        // top level flags remain in place. Have to support both cases.
+
+        ConfigBag bag = ConfigBag.newInstance((Map<Object, Object>) attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CONFIG));
+        ConfigBag bagFlags = ConfigBag.newInstanceCopying(attrs);
+        if (attrs.containsKey(BrooklynCampReservedKeys.BROOKLYN_FLAGS)) {
+            bagFlags.putAll((Map<String, Object>) attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_FLAGS));
+        }
+
+        Collection<FlagConfigKeyAndValueRecord> topLevelApparentConfig = findAllFlagsAndConfigKeys(spec, bagFlags);
+        for (FlagConfigKeyAndValueRecord r: topLevelApparentConfig) {
+            if (r.getConfigKeyMaybeValue().isPresent())
+                bag.putIfAbsent((ConfigKey)r.getConfigKey(), r.getConfigKeyMaybeValue().get());
+            if (r.getFlagMaybeValue().isPresent())
+                bag.putAsStringKeyIfAbsent(r.getFlagName(), r.getFlagMaybeValue().get());
+        }
+
+        // now set configuration for all the items in the bag
+        Collection<FlagConfigKeyAndValueRecord> records = findAllFlagsAndConfigKeys(spec, bag);
+        Set<String> keyNamesUsed = new LinkedHashSet<String>();
+        for (FlagConfigKeyAndValueRecord r: records) {
+            if (r.getFlagMaybeValue().isPresent()) {
+                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(r.getFlagMaybeValue().get());
+                spec.configure(r.getFlagName(), transformed);
+                keyNamesUsed.add(r.getFlagName());
+            }
+            if (r.getConfigKeyMaybeValue().isPresent()) {
+                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(r.getConfigKeyMaybeValue().get());
+                spec.configure((ConfigKey<Object>)r.getConfigKey(), transformed);
+                keyNamesUsed.add(r.getConfigKey().getName());
+            }
+        }
+
+        // set unused keys as anonymous config keys -
+        // they aren't flags or known config keys, so must be passed as config keys in order for
+        // EntitySpec to know what to do with them (as they are passed to the spec as flags)
+        for (String key: MutableSet.copyOf(bag.getUnusedConfig().keySet())) {
+            // we don't let a flag with the same name as a config key override the config key
+            // (that's why we check whether it is used)
+            if (!keyNamesUsed.contains(key)) {
+                Object transformed = new SpecialFlagsTransformer(loader).transformSpecialFlags(bag.getStringKey(key));
+                spec.configure(ConfigKeys.newConfigKey(Object.class, key.toString()), transformed);
+            }
+        }
+    }
+
+    /**
+     * Searches for config keys in the type, additional interfaces and the implementation (if specified)
+     */
+    private Collection<FlagConfigKeyAndValueRecord> findAllFlagsAndConfigKeys(EntitySpec<?> spec, ConfigBag bagFlags) {
+        Set<FlagConfigKeyAndValueRecord> allKeys = MutableSet.of();
+        allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, spec.getType(), bagFlags));
+        if (spec.getImplementation() != null) {
+            allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, spec.getImplementation(), bagFlags));
+        }
+        for (Class<?> iface : spec.getAdditionalInterfaces()) {
+            allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, iface, bagFlags));
+        }
+        return allKeys;
+    }
+
+    protected static class SpecialFlagsTransformer implements Function<Object, Object> {
+        protected final ManagementContext mgmt;
+        /* TODO find a way to make do without loader here?
+         * it is not very nice having to serialize it; but serialization of BLCL is now relatively clean.
+         *
+         * it is only used to instantiate classes, and now most things should be registered with catalog;
+         * the notable exception is when one entity in a bundle is creating another in the same bundle,
+         * it wants to use his bundle CLC to do that.  but we can set up some unique reference to the entity
+         * which can be used to find it from mgmt, rather than pass the loader.
+         */
+        private BrooklynClassLoadingContext loader = null;
+
+        public SpecialFlagsTransformer(BrooklynClassLoadingContext loader) {
+            this.loader = loader;
+            mgmt = loader.getManagementContext();
+        }
+        public Object apply(Object input) {
+            if (input instanceof Map)
+                return transformSpecialFlags((Map<?, ?>)input);
+            else if (input instanceof Set<?>)
+                return MutableSet.of(transformSpecialFlags((Iterable<?>)input));
+            else if (input instanceof List<?>)
+                return MutableList.copyOf(transformSpecialFlags((Iterable<?>)input));
+            else if (input instanceof Iterable<?>)
+                return transformSpecialFlags((Iterable<?>)input);
+            else
+                return transformSpecialFlags((Object)input);
+        }
+
+        protected Map<?, ?> transformSpecialFlags(Map<?, ?> flag) {
+            return Maps.transformValues(flag, this);
+        }
+
+        protected Iterable<?> transformSpecialFlags(Iterable<?> flag) {
+            return Iterables.transform(flag, this);
+        }
+
+        protected BrooklynClassLoadingContext getLoader() {
+            if (loader!=null) return loader;
+            // TODO currently loader will non-null unless someone has messed with the rebind files,
+            // but we'd like to get rid of it; ideally we'd have a reference to the entity.
+            // for now, this is a slightly naff way to do it, if we have to set loader=null as a workaround
+            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (entity!=null) return CatalogUtils.getClassLoadingContext(entity);
+            return JavaBrooklynClassLoadingContext.create(mgmt);
+        }
+
+        /**
+         * Makes additional transformations to the given flag with the extra knowledge of the flag's management context.
+         * @return The modified flag, or the flag unchanged.
+         */
+        protected Object transformSpecialFlags(Object flag) {
+            if (flag instanceof EntitySpecConfiguration) {
+                EntitySpecConfiguration specConfig = (EntitySpecConfiguration) flag;
+                // TODO: This should called from BrooklynAssemblyTemplateInstantiator.configureEntityConfig
+                // And have transformSpecialFlags(Object flag, ManagementContext mgmt) drill into the Object flag if it's a map or iterable?
+                @SuppressWarnings("unchecked")
+                Map<String, Object> resolvedConfig = (Map<String, Object>)transformSpecialFlags(specConfig.getSpecConfiguration());
+                specConfig.setSpecConfiguration(resolvedConfig);
+                return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec(null);
+            }
+            if (flag instanceof ManagementContextInjectable) {
+                log.debug("Injecting Brooklyn management context info object: {}", flag);
+                ((ManagementContextInjectable) flag).injectManagementContext(loader.getManagementContext());
+            }
+
+            return flag;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected List<Map<String, Object>> getChildren(Map<String, Object> attrs) {
+        if (attrs==null) return null;
+        return (List<Map<String, Object>>) attrs.get(BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
new file mode 100644
index 0000000..8af9ba5
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -0,0 +1,180 @@
+/*
+ * 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.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.proxying.EntityInitializer;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.Policy;
+import brooklyn.policy.PolicySpec;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Pattern for resolving "decorations" on service specs / entity specs, such as policies, enrichers, etc.
+ * @since 0.7.0
+ */
+@Beta
+public abstract class BrooklynEntityDecorationResolver<DT> {
+
+    public final BrooklynYamlTypeInstantiator.Factory instantiator;
+    
+    protected BrooklynEntityDecorationResolver(BrooklynYamlTypeInstantiator.Factory instantiator) {
+        this.instantiator = instantiator;
+    }
+    
+    public abstract void decorate(EntitySpec<?> entitySpec, ConfigBag attrs);
+
+    protected Iterable<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) {
+        Object value = getDecorationAttributeJsonValue(attrs); 
+        List<DT> decorations = MutableList.of();
+        if (value==null) return decorations;
+        if (value instanceof Iterable) {
+            for (Object decorationJson: (Iterable<?>)value)
+                addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
+        } else {
+            // in future may support types other than iterables here, 
+            // e.g. a map short form where the key is the type
+            throw new IllegalArgumentException(getDecorationKind()+" body should be iterable, not " + value.getClass());
+        }
+        return decorations;
+    }
+    
+    protected Map<?,?> checkIsMap(Object decorationJson) {
+        if (!(decorationJson instanceof Map))
+            throw new IllegalArgumentException(getDecorationKind()+" value must be a Map, not " + 
+                (decorationJson==null ? null : decorationJson.getClass()) );
+        return (Map<?,?>) decorationJson;
+    }
+
+    protected abstract String getDecorationKind();
+    protected abstract Object getDecorationAttributeJsonValue(ConfigBag attrs);
+    
+    /** creates and adds decorations from the given json to the given collection; 
+     * default impl requires a map and calls {@link #addDecorationFromJsonMap(Map, List)} */
+    protected void addDecorationFromJson(Object decorationJson, List<DT> decorations) {
+        addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
+    }
+    protected abstract void addDecorationFromJsonMap(Map<?,?> decorationJson, List<DT> decorations);
+    
+
+    public static class PolicySpecResolver extends BrooklynEntityDecorationResolver<PolicySpec<?>> {
+        
+        public PolicySpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
+        @Override protected String getDecorationKind() { return "Policy"; }
+
+        @Override
+        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
+            entitySpec.policySpecs(buildListOfTheseDecorationsFromEntityAttributes(attrs));
+        }
+        
+        @Override
+        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
+            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_POLICIES);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<PolicySpec<?>> decorations) {
+            InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("policy");
+
+            String policyType = decoLoader.getTypeName().get();
+            ManagementContext mgmt = instantiator.loader.getManagementContext();
+            BrooklynCatalog catalog = mgmt.getCatalog();
+            CatalogItem<?, ?> item = getPolicyCatalogItem(catalog, policyType);
+            PolicySpec<? extends Policy> spec;
+            if (item != null) {
+                spec = (PolicySpec<? extends Policy>) catalog.createSpec(item);
+                spec.configure(decoLoader.getConfigMap());
+            } else {
+                // this pattern of creating a spec could be simplified with a "Configurable" superinterface on *Spec  
+                spec = PolicySpec.create(decoLoader.getType(Policy.class))
+                    .configure( decoLoader.getConfigMap() );
+            }
+            decorations.add(spec);
+        }
+        private CatalogItem<?, ?> getPolicyCatalogItem(BrooklynCatalog catalog, String policyType) {
+            if (CatalogUtils.looksLikeVersionedId(policyType)) {
+                String id = CatalogUtils.getIdFromVersionedId(policyType);
+                String version = CatalogUtils.getVersionFromVersionedId(policyType);
+                return catalog.getCatalogItem(id, version);
+            } else {
+                return catalog.getCatalogItem(policyType, BrooklynCatalog.DEFAULT_VERSION);
+            }
+        }
+    }
+
+    public static class EnricherSpecResolver extends BrooklynEntityDecorationResolver<EnricherSpec<?>> {
+        
+        public EnricherSpecResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
+        @Override protected String getDecorationKind() { return "Enricher"; }
+
+        @Override
+        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
+            entitySpec.enricherSpecs(buildListOfTheseDecorationsFromEntityAttributes(attrs));
+        }
+        
+        @Override
+        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
+            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_ENRICHERS);
+        }
+
+        @Override
+        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<EnricherSpec<?>> decorations) {
+            InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("enricher");
+            decorations.add(EnricherSpec.create(decoLoader.getType(Enricher.class))
+                .configure( decoLoader.getConfigMap() ));
+        }
+    }
+    
+    public static class InitializerResolver extends BrooklynEntityDecorationResolver<EntityInitializer> {
+        
+        public InitializerResolver(BrooklynYamlTypeInstantiator.Factory loader) { super(loader); }
+        @Override protected String getDecorationKind() { return "Entity initializer"; }
+
+        @Override
+        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
+            entitySpec.addInitializers(buildListOfTheseDecorationsFromEntityAttributes(attrs));
+        }
+        
+        @Override
+        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
+            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS);
+        }
+
+        @Override
+        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<EntityInitializer> decorations) {
+            decorations.add(instantiator.from(decorationJson).prefix("initializer").newInstance(EntityInitializer.class));
+        }
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
new file mode 100644
index 0000000..27ccae7
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
@@ -0,0 +1,193 @@
+/*
+ * 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 io.brooklyn.camp.spi.PlatformComponentTemplate;
+import io.brooklyn.camp.spi.PlatformComponentTemplate.Builder;
+import io.brooklyn.camp.spi.pdp.AssemblyTemplateConstructor;
+import io.brooklyn.camp.spi.pdp.Service;
+import io.brooklyn.camp.spi.resolve.PdpMatcher;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.internal.BasicBrooklynCatalog;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Urls;
+import brooklyn.util.text.Strings;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class BrooklynEntityMatcher implements PdpMatcher {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynEntityMatcher.class);
+    
+    protected final ManagementContext mgmt;
+
+    public BrooklynEntityMatcher(ManagementContext bmc) {
+        this.mgmt = bmc;
+    }
+
+    @Override
+    public boolean accepts(Object deploymentPlanItem) {
+        return lookupType(deploymentPlanItem) != null;
+    }
+
+    /** returns the type of the given plan item, 
+     * typically whether a Service can be matched to a Brooklyn entity,
+     * or null if not supported */
+    protected String lookupType(Object deploymentPlanItem) {
+        if (deploymentPlanItem instanceof Service) {
+            Service service = (Service)deploymentPlanItem;
+
+            String serviceType = service.getServiceType();
+            BrooklynClassLoadingContext loader = BasicBrooklynCatalog.BrooklynLoaderTracker.getLoader();
+            if (loader == null) loader = JavaBrooklynClassLoadingContext.create(mgmt);
+            if (BrooklynComponentTemplateResolver.Factory.supportsType(loader, serviceType))
+                return serviceType;
+
+            String protocol = Urls.getProtocol(serviceType);
+            if (protocol != null) {
+                if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
+                    return serviceType;
+                } else {
+                    log.debug("The reference '" + serviceType + "' looks like a URL (running the CAMP Brooklyn entity-matcher) but the protocol '" + 
+                            protocol + "' isn't white listed " + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + ". " +
+                            "Not recognized as catalog item or java item as well!");
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean apply(Object deploymentPlanItem, AssemblyTemplateConstructor atc) {
+        if (!(deploymentPlanItem instanceof Service)) return false;
+        
+        String type = lookupType(deploymentPlanItem);
+        if (type==null) return false;
+
+        log.debug("Item "+deploymentPlanItem+" being instantiated with "+type);
+
+        Object old = atc.getInstantiator();
+        if (old!=null && !old.equals(BrooklynAssemblyTemplateInstantiator.class)) {
+            log.warn("Can't mix Brooklyn entities with non-Brooklyn entities (at present): "+old);
+            return false;
+        }
+
+        // TODO should we build up a new type, BrooklynEntityComponentTemplate here
+        // complete w EntitySpec -- ie merge w BrooklynComponentTemplateResolver ?
+        
+        Builder<? extends PlatformComponentTemplate> builder = PlatformComponentTemplate.builder();
+        builder.type( type.indexOf(':')==-1 ? "brooklyn:"+type : type );
+        
+        // currently instantiator must be brooklyn at the ATC level
+        // optionally would be nice to support multiple/mixed instantiators, 
+        // ie at the component level, perhaps with the first one responsible for building the app
+        atc.instantiator(BrooklynAssemblyTemplateInstantiator.class);
+
+        String name = ((Service)deploymentPlanItem).getName();
+        if (!Strings.isBlank(name)) builder.name(name);
+        
+        // configuration
+        Map<String, Object> attrs = MutableMap.copyOf( ((Service)deploymentPlanItem).getCustomAttributes() );
+
+        if (attrs.containsKey("id"))
+            builder.customAttribute("planId", attrs.remove("id"));
+
+        Object location = attrs.remove("location");
+        if (location!=null)
+            builder.customAttribute("location", location);
+        Object locations = attrs.remove("locations");
+        if (locations!=null)
+            builder.customAttribute("locations", locations);
+
+        MutableMap<Object, Object> brooklynFlags = MutableMap.of();
+        Object origBrooklynFlags = attrs.remove(BrooklynCampReservedKeys.BROOKLYN_FLAGS);
+        if (origBrooklynFlags!=null) {
+            if (!(origBrooklynFlags instanceof Map))
+                throw new IllegalArgumentException("brooklyn.flags must be a map of brooklyn flags");
+            brooklynFlags.putAll((Map<?,?>)origBrooklynFlags);
+        }
+
+        addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CONFIG);
+        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_POLICIES);
+        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_ENRICHERS);
+        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS);
+        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
+        addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CATALOG);
+
+        brooklynFlags.putAll(attrs);
+        if (!brooklynFlags.isEmpty()) {
+            builder.customAttribute(BrooklynCampReservedKeys.BROOKLYN_FLAGS, brooklynFlags);
+        }
+
+        atc.add(builder.build());
+
+        return true;
+    }
+
+    /**
+     * Looks for the given key in the map of attributes and adds it to the given builder
+     * as a custom attribute with type List.
+     * @throws java.lang.IllegalArgumentException if map[key] is not an instance of List
+     */
+    private void addCustomListAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) {
+        Object items = attrs.remove(key);
+        if (items != null) {
+            if (items instanceof List) {
+                List<?> itemList = (List<?>) items;
+                if (!itemList.isEmpty()) {
+                    builder.customAttribute(key, Lists.newArrayList(itemList));
+                }
+            } else {
+                throw new IllegalArgumentException(key + " must be a list, is: " + items.getClass().getName());
+            }
+        }
+    }
+
+    /**
+     * Looks for the given key in the map of attributes and adds it to the given builder
+     * as a custom attribute with type Map.
+     * @throws java.lang.IllegalArgumentException if map[key] is not an instance of Map
+     */
+    private void addCustomMapAttributeIfNonNull(Builder<? extends PlatformComponentTemplate> builder, Map<?,?> attrs, String key) {
+        Object items = attrs.remove(key);
+        if (items != null) {
+            if (items instanceof Map) {
+                Map<?, ?> itemMap = (Map<?, ?>) items;
+                if (!itemMap.isEmpty()) {
+                    builder.customAttribute(key, Maps.newHashMap(itemMap));
+                }
+            } else {
+                throw new IllegalArgumentException(key + " must be a map, is: " + items.getClass().getName());
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
new file mode 100644
index 0000000..7c4f734
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
@@ -0,0 +1,142 @@
+/*
+ * 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.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import brooklyn.location.Location;
+import brooklyn.location.LocationDefinition;
+import brooklyn.management.ManagementContext;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.guava.Maybe.Absent;
+import brooklyn.util.text.Strings;
+
+import com.google.common.collect.Iterables;
+
+public class BrooklynYamlLocationResolver {
+
+    protected final ManagementContext mgmt;
+
+    public BrooklynYamlLocationResolver(ManagementContext bmc) {
+        this.mgmt = bmc;
+    }
+
+    /** returns list of locations, if any were supplied, or null if none indicated */
+    @SuppressWarnings("unchecked")
+    public List<Location> resolveLocations(Map<? super String,?> attrs, boolean removeUsedAttributes) {
+        Object location = attrs.get("location");
+        Object locations = attrs.get("locations");
+
+        if (location==null && locations==null)
+            return null;
+        
+        Location locationFromString = null;
+        List<Location> locationsFromList = null;
+        
+        if (location!=null) {
+            if (location instanceof String) {
+                locationFromString = resolveLocationFromString((String)location);
+            } else if (location instanceof Map) {
+                locationFromString = resolveLocationFromMap((Map<?,?>)location);
+            } else {
+                throw new IllegalStateException("Illegal parameter for 'location'; must be a string or map (but got "+location+")");
+            }
+        }
+        
+        if (locations!=null) {
+            if (!(locations instanceof Iterable))
+                throw new IllegalStateException("Illegal parameter for 'locations'; must be an iterable (but got "+locations+")");
+            locationsFromList = resolveLocations( (Iterable<Object>)locations );
+        }
+        
+        if (locationFromString!=null && locationsFromList!=null) {
+            if (locationsFromList.size() != 1)
+                throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); "
+                    + "if both are supplied the list must have exactly one element being the same");
+            if (!locationFromString.equals( Iterables.getOnlyElement(locationsFromList) ))
+                throw new IllegalStateException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); "
+                    + "different location specified in each");
+        } else if (locationFromString!=null) {
+            locationsFromList = Arrays.asList(locationFromString);
+        }
+        
+        return locationsFromList;
+    }
+
+    public List<Location> resolveLocations(Iterable<Object> locations) {
+        List<Location> result = MutableList.of();
+        for (Object l: locations) {
+            Location ll = resolveLocation(l);
+            if (ll!=null) result.add(ll);
+        }
+        return result;
+    }
+
+    public Location resolveLocation(Object location) {
+        if (location instanceof String) {
+            return resolveLocationFromString((String)location);
+        } else if (location instanceof Map) {
+            return resolveLocationFromMap((Map<?,?>)location);
+        }
+        // could support e.g. location definition
+        throw new IllegalStateException("Illegal parameter for 'location' ("+location+"); must be a string or map");
+    }
+    
+    /** resolves the location from the given spec string, either "Named Location", or "named:Named Location" format;
+     * returns null if input is blank (or null); otherwise guaranteed to resolve or throw error */
+    public Location resolveLocationFromString(String location) {
+        if (Strings.isBlank(location)) return null;
+        return resolveLocation(location, MutableMap.of());
+    }
+
+    public Location resolveLocationFromMap(Map<?,?> location) {
+        if (location.size() > 1) {
+            throw new IllegalStateException("Illegal parameter for 'location'; expected a single entry in map ("+location+")");
+        }
+        Object key = Iterables.getOnlyElement(location.keySet());
+        Object value = location.get(key);
+        
+        if (!(key instanceof String)) {
+            throw new IllegalStateException("Illegal parameter for 'location'; expected String key ("+location+")");
+        }
+        if (!(value instanceof Map)) {
+            throw new IllegalStateException("Illegal parameter for 'location'; expected config map ("+location+")");
+        }
+        return resolveLocation((String)key, (Map<?,?>)value);
+    }
+    
+    protected Location resolveLocation(String spec, Map<?,?> flags) {
+        LocationDefinition ldef = mgmt.getLocationRegistry().getDefinedLocationByName((String)spec);
+        if (ldef!=null)
+            // found it as a named location
+            return mgmt.getLocationRegistry().resolve(ldef, null, flags).get();
+        
+        Maybe<Location> l = mgmt.getLocationRegistry().resolve(spec, null, flags);
+        if (l.isPresent()) return l.get();
+        
+        RuntimeException exception = ((Absent<?>)l).getException();
+        throw new IllegalStateException("Illegal parameter for 'location' ("+spec+"); not resolvable: "+
+            Exceptions.collapseText( exception ), exception);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
new file mode 100644
index 0000000..8c2cb72
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
@@ -0,0 +1,208 @@
+/*
+ * 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.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.javalang.Reflections;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/** Assists in loading types referenced from YAML;
+ * mainly as a way to share logic used in very different contexts. */
+public abstract class BrooklynYamlTypeInstantiator {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynYamlTypeInstantiator.class);
+    
+    protected final Factory factory;
+
+    @Beta
+    public static class Factory {
+        final BrooklynClassLoadingContext loader;
+        final Object contextForLogging;
+        
+        public Factory(BrooklynClassLoadingContext loader, Object contextForLogging) {
+            this.loader = loader;
+            this.contextForLogging = contextForLogging;
+        }
+        
+        public InstantiatorFromKey from(Map<?,?> data) {
+            return new InstantiatorFromKey(this, ConfigBag.newInstance(data));
+        }
+        
+        public InstantiatorFromKey from(ConfigBag data) {
+            return new InstantiatorFromKey(this, data);
+        }
+        
+        public InstantiatorFromName type(String typeName) {
+            return new InstantiatorFromName(this, typeName);
+        }
+
+    }
+        
+    public static class InstantiatorFromKey extends BrooklynYamlTypeInstantiator {
+        protected final ConfigBag data;
+        protected String typeKeyPrefix = null;
+        
+        /** Nullable only permitted for instances which do not do loading, e.g. LoaderFromKey#lookup */
+        protected InstantiatorFromKey(@Nullable Factory factory, ConfigBag data) {
+            super(factory);
+            this.data = data;
+        }
+        
+        public static Maybe<String> extractTypeName(String prefix, ConfigBag data) {
+            if (data==null) return Maybe.absent();
+            return new InstantiatorFromKey(null, data).prefix(prefix).getTypeName();
+        }
+        
+        public InstantiatorFromKey prefix(String prefix) {
+            typeKeyPrefix = prefix;
+            return this;
+        }
+
+        public Maybe<String> getTypeName() {
+            Maybe<Object> result = data.getStringKeyMaybe(getPreferredKeyName());
+            if (result.isAbsent() && typeKeyPrefix!=null) {
+                // try alternatives if a prefix was specified
+                result = data.getStringKeyMaybe(typeKeyPrefix+"Type");
+                if (result.isAbsent()) result = data.getStringKeyMaybe("type");
+            }
+            
+            if (result.isAbsent() || result.get()==null) 
+                return Maybe.absent("Missing key '"+getPreferredKeyName()+"'");
+            
+            if (result.get() instanceof String) return Maybe.of((String)result.get());
+            
+            throw new IllegalArgumentException("Invalid value "+result.get().getClass()+" for "+getPreferredKeyName()+"; "
+                + "expected String, got "+result.get());
+        }
+        
+        protected String getPreferredKeyName() {
+            if (typeKeyPrefix!=null) return typeKeyPrefix+"_type";
+            return "type";
+        }
+        
+        /** as {@link #newInstance(Class)} but inferring the type */
+        public Object newInstance() {
+            return newInstance(null);
+        }
+        
+        /** creates a new instance of the type referred to by this description,
+         * as a subtype of the type supplied here, 
+         * inferring a Map from <code>brooklyn.config</code> key.
+         * TODO in future also picking up recognized flags and config keys (those declared on the type).  
+         * <p>
+         * constructs the object using:
+         * <li> a constructor on the class taking a Map
+         * <li> a no-arg constructor, only if the inferred map is empty  
+         **/
+        public <T> T newInstance(@Nullable Class<T> supertype) {
+            Class<? extends T> type = getType(supertype);
+            Map<String, ?> cfg = getConfigMap();
+            Optional<? extends T> result = Reflections.invokeConstructorWithArgs(type, cfg);
+            if (result.isPresent()) 
+                return result.get();
+            
+            ConfigBag cfgBag = ConfigBag.newInstance(cfg);
+            result = Reflections.invokeConstructorWithArgs(type, cfgBag);
+            if (result.isPresent()) 
+                return result.get();
+            
+            if (cfg.isEmpty()) {
+                result = Reflections.invokeConstructorWithArgs(type);
+                if (result.isPresent()) 
+                    return result.get();
+            }
+            
+            throw new IllegalStateException("No known mechanism for constructing type "+type+" in "+factory.contextForLogging);
+        }
+
+        /** finds the map of config for the type specified;
+         * currently only gets <code>brooklyn.config</code>, returning empty map if none,
+         * but TODO in future should support recognized flags and config keys (those declared on the type),
+         * incorporating code in {@link BrooklynEntityMatcher}.
+         */
+        @SuppressWarnings("unchecked")
+        @Nonnull
+        public Map<String,?> getConfigMap() {
+            MutableMap<String,Object> result = MutableMap.of();
+            Object bc = data.getStringKey(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
+            if (bc!=null) {
+                if (bc instanceof Map)
+                    result.putAll((Map<? extends String, ?>) bc);
+                else
+                    throw new IllegalArgumentException("brooklyn.config key in "+factory.contextForLogging+" should be a map, not "+bc.getClass()+" ("+bc+")");
+            }
+            return result; 
+        }
+
+    }
+    
+    public static class InstantiatorFromName extends BrooklynYamlTypeInstantiator {
+        protected final String typeName;
+        protected InstantiatorFromName(Factory factory, String typeName) {
+            super(factory);
+            this.typeName = typeName;
+        }
+        
+        public Maybe<String> getTypeName() {
+            return Maybe.fromNullable(typeName);
+        }
+    }
+    
+    protected BrooklynYamlTypeInstantiator(Factory factory) {
+        this.factory = factory;
+    }
+        
+    public abstract Maybe<String> getTypeName();
+    
+    public BrooklynClassLoadingContext getClassLoadingContext() {
+        Preconditions.checkNotNull(factory, "No factory set; cannot use this instance for type loading");
+        return factory.loader;
+    }
+    
+    public Class<?> getType() {
+        return getType(Object.class);
+    }
+    
+    public <T> Class<? extends T> getType(@Nonnull Class<T> type) {
+        try {
+            return getClassLoadingContext().loadClass(getTypeName().get(), type);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            log.debug("Unable to resolve " + type + " " + getTypeName().get() + " (rethrowing) in spec " + factory.contextForLogging);
+            throw Exceptions.propagate(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
new file mode 100644
index 0000000..626529f
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/EntitySpecConfiguration.java
@@ -0,0 +1,58 @@
+/*
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.proxying.EntitySpec;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Captures the {@link EntitySpec} configuration defined in YAML. 
+ * 
+ * This class does not parse that output; it just stores it.
+ */
+public class EntitySpecConfiguration {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(EntitySpecConfiguration.class);
+
+    private Map<String, Object> specConfiguration;
+
+    public EntitySpecConfiguration(Map<String, ?> specConfiguration) {
+        this.specConfiguration = Maps.newHashMap(checkNotNull(specConfiguration, "specConfiguration"));
+    }
+
+    public Map<String, Object> getSpecConfiguration() {
+        return specConfiguration;
+    }
+    
+    /**
+     * Allows BrooklynComponentTemplateResolver to traverse the configuration and resolve any entity specs
+     */
+    public void setSpecConfiguration(Map<String, Object> specConfiguration) {
+       this.specConfiguration =  specConfiguration;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
new file mode 100644
index 0000000..de9f36f
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
@@ -0,0 +1,71 @@
+/*
+ * 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.service;
+
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityDecorationResolver;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.util.text.Strings;
+
+/**
+ * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code brooklyn:}
+ * to Brooklyn {@link EntitySpec} instances.
+ */
+public class BrooklynServiceTypeResolver implements ServiceTypeResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
+
+    @Override
+    public String getTypePrefix() { return DEFAULT_TYPE_PREFIX; }
+
+    @Override
+    public String getBrooklynType(String serviceType) {
+        String type = Strings.removeFromStart(serviceType, getTypePrefix() + ":").trim();
+        if (type == null) return null;
+        return type;
+    }
+
+    @Nullable
+    @Override
+    public CatalogItem<Entity,EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) {
+        String type = getBrooklynType(serviceType);
+        if (type != null) {
+            return CatalogUtils.getCatalogItemOptionalVersion(resolver.getManagementContext(), Entity.class,  type);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) {
+        new BrooklynEntityDecorationResolver.PolicySpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
+        new BrooklynEntityDecorationResolver.EnricherSpecResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
+        new BrooklynEntityDecorationResolver.InitializerResolver(resolver.getYamlLoader()).decorate(spec, resolver.getAttrs());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
new file mode 100644
index 0000000..e569183
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CatalogServiceTypeResolver.java
@@ -0,0 +1,78 @@
+/*
+ * 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.service;
+
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.VanillaSoftwareProcess;
+import brooklyn.entity.brooklynnode.BrooklynNode;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.group.DynamicRegionsFabric;
+import brooklyn.entity.java.VanillaJavaApp;
+import brooklyn.entity.proxying.EntitySpec;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Converter;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code catalog:}
+ * to Brooklyn {@link EntitySpec} instances.
+ */
+public class CatalogServiceTypeResolver extends BrooklynServiceTypeResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
+
+    // TODO currently a hardcoded list of aliases; would like that to come from mgmt somehow
+    private static final Map<String, String> CATALOG_TYPES = ImmutableMap.<String, String>builder()
+            .put("cluster", DynamicCluster.class.getName())
+            .put("fabric", DynamicRegionsFabric.class.getName())
+            .put("vanilla", VanillaSoftwareProcess.class.getName())
+            .put("software-process", VanillaSoftwareProcess.class.getName())
+            .put("java-app", VanillaJavaApp.class.getName())
+            .put("brooklyn-node", BrooklynNode.class.getName())
+            .put("web-app-cluster","brooklyn.entity.webapp.ControlledDynamicWebAppCluster")
+            .build();
+
+    // Allow catalog-type or CatalogType as service type string
+    private static final Converter<String, String> FMT = CaseFormat.LOWER_HYPHEN.converterTo(CaseFormat.UPPER_CAMEL);
+
+    @Override
+    public String getTypePrefix() { return "catalog"; }
+
+    @Override
+    public String getBrooklynType(String serviceType) {
+        String type = super.getBrooklynType(serviceType);
+        if (type == null) return null;
+
+        for (String check : CATALOG_TYPES.keySet()) {
+            if (type.equals(check) || type.equals(FMT.convert(check))) {
+                return CATALOG_TYPES.get(check);
+            }
+        }
+
+        return type;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
new file mode 100644
index 0000000..f5d135f
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ChefServiceTypeResolver.java
@@ -0,0 +1,61 @@
+/*
+ * 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.service;
+
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.entity.Entity;
+import brooklyn.entity.chef.ChefConfig;
+import brooklyn.entity.chef.ChefEntity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.util.text.Strings;
+
+/**
+ * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code chef:}
+ * to Brooklyn {@link EntitySpec} instances.
+ */
+public class ChefServiceTypeResolver extends BrooklynServiceTypeResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
+
+    @Override
+    public String getTypePrefix() { return "chef"; }
+
+    @Override
+    public String getBrooklynType(String serviceType) {
+        return ChefEntity.class.getName();
+    }
+
+    /** Chef items are not in the catalog. */
+    @Override
+    public CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType) {
+        return null;
+    }
+
+    @Override
+    public <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec) {
+        spec.configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, Strings.removeFromStart(resolver.getDeclaredType(), "chef:"));
+        super.decorateSpec(resolver, spec);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
new file mode 100644
index 0000000..8670723
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/JavaServiceTypeResolver.java
@@ -0,0 +1,39 @@
+/*
+ * 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.service;
+
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.proxying.EntitySpec;
+
+/**
+ * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code java:}
+ * to Brooklyn {@link EntitySpec} instances.
+ */
+public class JavaServiceTypeResolver extends BrooklynServiceTypeResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ServiceTypeResolver.class);
+
+    @Override
+    public String getTypePrefix() { return "java"; }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
new file mode 100644
index 0000000..734352b
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
@@ -0,0 +1,73 @@
+/*
+ * 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.service;
+
+import java.util.ServiceLoader;
+
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+
+/**
+ * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template.
+ * <p>
+ * The {@link #getTypePrefix()} method returns a string that should match the beginning of the
+ * service type. The resolver implementation will use the rest of the service type information
+ * to create and decorate an approprate {@link EntitySpec entity}.
+ * <p>
+ * The resolvers are loaded using the {@link ServiceLoader} mechanism, allowing external libraries
+ * to add extra service type implementations that will be picked up at runtime.
+ *
+ * @see BrooklynServiceTypeResolver
+ * @see ChefServiceTypeResolver
+ */
+public interface ServiceTypeResolver {
+
+    String DEFAULT_TYPE_PREFIX = "brooklyn";
+
+    /**
+     * The service type prefix the resolver is responsible for.
+     */
+    String getTypePrefix();
+
+    /**
+     * The name of the Java type that Brooklyn will instantiate to create the
+     * service. This can be generated from parts of the service type information
+     * or may be a fixed value.
+     */
+    String getBrooklynType(String serviceType);
+
+    /**
+     * Returns the {@link CatalogItem} if there is one for the given type.
+     * <p>
+     * If no type, callers should fall back to default classloading.
+     */
+    CatalogItem<Entity, EntitySpec<?>> getCatalogItem(BrooklynComponentTemplateResolver resolver, String serviceType);
+
+    /**
+     * Takes the provided {@link EntitySpec} and decorates it appropriately for the service type.
+     * <p>
+     * This includes setting configuration and adding policies, enrichers and initializers.
+     *
+     * @see BrooklynServiceTypeResolver#decorateSpec(BrooklynComponentTemplateResolver, EntitySpec)
+     */
+    <T extends Entity> void decorateSpec(BrooklynComponentTemplateResolver resolver, EntitySpec<T> spec);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
new file mode 100644
index 0000000..9b27607
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
@@ -0,0 +1,99 @@
+/*
+ * 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.dsl;
+
+import java.io.Serializable;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.effector.EffectorTasks;
+import brooklyn.management.Task;
+import brooklyn.management.TaskFactory;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.task.DeferredSupplier;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/** provide an object suitable to resolve chained invocations in a parsed YAML / Deployment Plan DSL,
+ * which also implements {@link DeferredSupplier} so that they can be resolved when needed
+ * (e.g. when entity-lookup and execution contexts are available).
+ * <p>
+ * implementations of this abstract class are expected to be immutable,
+ * as instances must support usage in multiple {@link Assembly} instances 
+ * created from a single {@link AssemblyTemplate}  
+ * <p>
+ * subclasses which return a deferred value are typically only
+ * resolvable in the context of a {@link Task} on an {@link Entity}; 
+ * these should be only used as the value of a {@link ConfigKey} set in the YAML,
+ * and should not accessed until after the components / entities are created 
+ * and are being started.
+ * (TODO the precise semantics of this are under development.)
+ * <p>
+ **/
+public abstract class BrooklynDslDeferredSupplier<T> implements DeferredSupplier<T>, TaskFactory<Task<T>>, Serializable {
+
+    private static final long serialVersionUID = -8789624905412198233L;
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynDslDeferredSupplier.class);
+    
+    // TODO json of this object should *be* this, not wrapped this ($brooklyn:literal is a bit of a hack, though it might work!)
+    @JsonInclude
+    @JsonProperty(value="$brooklyn:literal")
+    // currently marked transient because it's only needed for logging
+    private transient Object dsl = "(gone)";
+    
+    public BrooklynDslDeferredSupplier() {
+        PlanInterpretationNode sourceNode = BrooklynDslInterpreter.currentNode();
+        dsl = sourceNode!=null ? sourceNode.getOriginalValue() : null;
+    }
+    
+    /** returns the current entity; for use in implementations of {@link #get()} */
+    protected final static EntityInternal entity() {
+        // rely on implicit ThreadLocal for now
+        return (EntityInternal) EffectorTasks.findEntity();
+    }
+
+    @Override
+    public final synchronized T get() {
+        try {
+            if (log.isDebugEnabled())
+                log.debug("Queuing task to resolve "+dsl);
+            T result = Entities.submit(entity(), newTask()).get();
+            if (log.isDebugEnabled())
+                log.debug("Resolved "+result+" from "+dsl);
+            return result;
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+    
+    @Override
+    public abstract Task<T> newTask();
+
+}


[17/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
deleted file mode 100644
index 43a4d04..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
+++ /dev/null
@@ -1,144 +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 io.brooklyn.camp.brooklyn.spi.dsl.parse;
-
-import java.util.Collection;
-import java.util.List;
-
-import brooklyn.util.collections.MutableList;
-
-public class DslParser {
-    private final String expression;
-    int index = -1;
-    
-    public DslParser(String expression) {
-        this.expression = expression;
-    }
-    
-    public synchronized Object parse() {
-        if (index>=0)
-            throw new IllegalStateException("Parser can only be used once");
-        
-        index++;
-        Object result = next();
-        
-        if (index < expression.length())
-            throw new IllegalStateException("Unexpected character at position "+index+" in "+expression);
-        
-        return result;
-    }
-    
-    @SuppressWarnings("unchecked")
-    public Object next() {
-        int start = index;
-        
-        skipWhitespace();
-        if (index >= expression.length())
-            throw new IllegalStateException("Unexpected end of expression to parse, looking for content since position "+start);
-        
-        if (expression.charAt(index)=='"') {
-            // assume a string
-            int stringStart = index;
-            index++;
-            do {
-                if (index >= expression.length())
-                    throw new IllegalStateException("Unexpected end of expression to parse, looking for close quote since position "+stringStart);
-                char c = expression.charAt(index);
-                if (c=='"') break;
-                if (c=='\\') index++;
-                index++;
-            } while (true);
-            index++;
-            return new QuotedString(expression.substring(stringStart, index));
-        }
-
-        // not a string, must be a function (or chain thereof)
-        List<FunctionWithArgs> result = new MutableList<FunctionWithArgs>();
-
-        int fnStart = index;
-        do {
-            if (index >= expression.length())
-                break;
-            char c = expression.charAt(index);
-            if (Character.isJavaIdentifierPart(c)) ;
-            // these chars also permitted
-            else if (".:".indexOf(c)>=0) ;
-            // other things e.g. whitespace, parentheses, etc, skip
-            else break;
-            index++;
-        } while (true);
-        String fn = expression.substring(fnStart, index);
-        if (fn.length()==0)
-            throw new IllegalStateException("Expected a function name at position "+start);
-        skipWhitespace();
-        
-        if (index < expression.length() && expression.charAt(index)=='(') {
-            // collect arguments
-            int parenStart = index;
-            List<Object> args = new MutableList<Object>();
-            index ++;
-            do {
-                skipWhitespace();
-                if (index >= expression.length())
-                    throw new IllegalStateException("Unexpected end of arguments to function '"+fn+"', no close parenthesis matching character at position "+parenStart);
-                char c = expression.charAt(index);
-                if (c==')') break;
-                if (c==',') {
-                    if (args.isEmpty())
-                        throw new IllegalStateException("Invalid character at position"+index);
-                    index++;
-                } else {
-                    if (!args.isEmpty())
-                        throw new IllegalStateException("Expected , before position"+index);
-                }
-                args.add(next());
-            } while (true);
-            result.add(new FunctionWithArgs(fn, args));
-            index++;
-            skipWhitespace();
-            if (index >= expression.length())
-                return result;
-            char c = expression.charAt(index);
-            if (c=='.') {
-                // chained expression
-                int chainStart = index;
-                index++;
-                Object next = next();
-                if (next instanceof List) {
-                    result.addAll((Collection<? extends FunctionWithArgs>) next);
-                    return result;
-                } else {
-                    throw new IllegalStateException("Expected functions following position"+chainStart);
-                }
-            } else {
-                // following word not something handled at this level; assume parent will handle (or throw) - e.g. a , or extra )
-                return result;
-            }
-        } else {
-            // it is just a word; return it with args as null
-            return new FunctionWithArgs(fn, null);
-        }
-    }
-
-    private void skipWhitespace() {
-        while (index<expression.length() && Character.isWhitespace(expression.charAt(index)))
-            index++;
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
deleted file mode 100644
index 973b7ba..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
+++ /dev/null
@@ -1,57 +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 io.brooklyn.camp.brooklyn.spi.dsl.parse;
-
-import java.util.List;
-
-import com.google.common.collect.ImmutableList;
-
-public class FunctionWithArgs {
-    private final String function;
-    private final List<Object> args;
-    
-    public FunctionWithArgs(String function, List<Object> args) {
-        this.function = function;
-        this.args = args==null ? null : ImmutableList.copyOf(args);
-    }
-    
-    public String getFunction() {
-        return function;
-    }
-    
-    /**
-     * arguments (typically {@link QuotedString} or more {@link FunctionWithArgs}).
-     * 
-     * null means it is a function in a map key which expects map value to be the arguments -- specified without parentheses;
-     * empty means parentheses already applied, with 0 args.
-     */
-    public List<Object> getArgs() {
-        return args;
-    }
-    
-    @Override
-    public String toString() {
-        return function+(args==null ? "" : args);
-    }
-
-    public Object arg(int i) {
-        return args.get(i);
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
deleted file mode 100644
index 485d00a..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
+++ /dev/null
@@ -1,49 +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 io.brooklyn.camp.brooklyn.spi.dsl.parse;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.base.Objects;
-
-public class QuotedString {
-    private final String s;
-    
-    public QuotedString(String s) {
-        this.s = checkNotNull(s, "string");
-    }
-    @Override
-    public String toString() {
-        return s;
-    }
-    public String unwrapped() {
-        return JavaStringEscapes.unwrapJavaString(s);
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        return (obj instanceof QuotedString) && ((QuotedString)obj).toString().equals(toString());
-    }
-    
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(s);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java
deleted file mode 100644
index 5e0e3f0..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.spi.AbstractResource;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.AbstractResourceLookup;
-import brooklyn.management.ManagementContext;
-
-public abstract class AbstractBrooklynResourceLookup<T extends AbstractResource>  extends AbstractResourceLookup<T> {
-
-    protected final PlatformRootSummary root;
-    protected final ManagementContext bmc;
-
-    public AbstractBrooklynResourceLookup(PlatformRootSummary root, ManagementContext bmc) {
-        this.root = root;
-        this.bmc = bmc;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
deleted file mode 100644
index a15b178..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
+++ /dev/null
@@ -1,62 +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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.spi.AbstractResource;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.management.ManagementContext;
-
-public abstract class AbstractTemplateBrooklynLookup<T extends AbstractResource>  extends AbstractBrooklynResourceLookup<T> {
-
-    private static final Logger log = LoggerFactory.getLogger(AbstractTemplateBrooklynLookup.class);
-    
-    public AbstractTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
-        super(root, bmc);
-    }
-
-    @Override
-    public T get(String id) {
-        CatalogItem<?,?> item = getCatalogItem(id);
-        if (item==null) {
-            log.warn("Could not find item '"+id+"' in Brooklyn catalog; returning null");
-            return null;
-        }
-        return adapt(item);
-    }
-
-    private CatalogItem<?, ?> getCatalogItem(String versionedId) {
-        return CatalogUtils.getCatalogItemOptionalVersion(bmc, versionedId);
-    }
-
-    public abstract T adapt(CatalogItem<?,?> item);
-
-    protected ResolvableLink<T> newLink(CatalogItem<? extends Entity,EntitySpec<?>> li) {
-        return newLink(li.getId(), li.getDisplayName());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
deleted file mode 100644
index 2f0380f..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
+++ /dev/null
@@ -1,69 +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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.management.ManagementContext;
-
-
-public class AssemblyBrooklynLookup extends AbstractBrooklynResourceLookup<Assembly> {
-
-    private PlatformComponentBrooklynLookup pcs;
-
-    public AssemblyBrooklynLookup(PlatformRootSummary root, ManagementContext bmc, PlatformComponentBrooklynLookup pcs) {
-        super(root, bmc);
-        this.pcs = pcs;
-    }
-
-    @Override
-    public Assembly get(String id) {
-        Entity entity = bmc.getEntityManager().getEntity(id);
-        if (!(entity instanceof Application))
-            throw new IllegalArgumentException("Element for "+id+" is not an Application ("+entity+")");
-        Assembly.Builder<? extends Assembly> builder = Assembly.builder()
-                .created(new Date(entity.getCreationTime()))
-                .id(entity.getId())
-                .name(entity.getDisplayName());
-        
-        builder.customAttribute("externalManagementUri", BrooklynUrlLookup.getUrl(bmc, entity));
-        
-        for (Entity child: entity.getChildren())
-            // FIXME this walks the whole damn tree!
-            builder.add( pcs.get(child.getId() ));
-        return builder.build();
-    }
-
-    @Override
-    public List<ResolvableLink<Assembly>> links() {
-        List<ResolvableLink<Assembly>> result = new ArrayList<ResolvableLink<Assembly>>();
-        for (Application app: bmc.getApplications())
-            result.add(newLink(app.getId(), app.getDisplayName()));
-        return result;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
deleted file mode 100644
index 24c40bc..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
+++ /dev/null
@@ -1,70 +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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.management.ManagementContext;
-
-public class AssemblyTemplateBrooklynLookup extends AbstractTemplateBrooklynLookup<AssemblyTemplate> {
-
-    public AssemblyTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
-        super(root, bmc);
-    }
-
-    @Override
-    public AssemblyTemplate adapt(CatalogItem<?,?> item) {
-        return AssemblyTemplate.builder().
-                name(item.getDisplayName()).
-                id(item.getId()).
-                description(item.getDescription()).
-                created(root.getCreated()).
-                instantiator(BrooklynAssemblyTemplateInstantiator.class).
-                build();
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    // why can I not pass an EntitySpec<? extends Application> to    newLink(EntitySpec<?> spec)  ?
-    // feels to me (alexheneveld) that `? extends Application` should be both covariant and contravariant to `?` ..
-    // but it's not, so we introduce this conversion method
-    protected ResolvableLink<AssemblyTemplate> newApplicationLink(CatalogItem<? extends Entity, EntitySpec<? extends Application>> li) {
-        return super.newLink((CatalogItem)li);
-    }
-    
-    @Override
-    public List<ResolvableLink<AssemblyTemplate>> links() {
-        Iterable<CatalogItem<Application,EntitySpec<? extends Application>>> l = bmc.getCatalog().getCatalogItems(CatalogPredicates.IS_TEMPLATE);
-        List<ResolvableLink<AssemblyTemplate>> result = new ArrayList<ResolvableLink<AssemblyTemplate>>();
-        for (CatalogItem<Application,EntitySpec<? extends Application>> li: l)
-            result.add(newApplicationLink(li));
-        return result;
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
deleted file mode 100644
index a27be03..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
+++ /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.
- */
-package io.brooklyn.camp.brooklyn.spi.lookup;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.management.ManagementContext;
-import brooklyn.util.net.Urls;
-
-public class BrooklynUrlLookup {
-
-    public static ConfigKey<String> BROOKLYN_ROOT_URL = ConfigKeys.newStringConfigKey("brooklyn.root.url");
-    
-    public static String getUrl(ManagementContext bmc, Entity entity) {
-        String root = bmc.getConfig().getConfig(BROOKLYN_ROOT_URL);
-        if (root==null) return null;
-        return Urls.mergePaths(root, "#/", 
-                "/v1/applications/"+entity.getApplicationId()+"/entities/"+entity.getId());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
deleted file mode 100644
index 90e5113..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
+++ /dev/null
@@ -1,61 +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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.spi.PlatformComponent;
-import io.brooklyn.camp.spi.PlatformComponent.Builder;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
-import brooklyn.entity.Entity;
-import brooklyn.management.ManagementContext;
-
-
-public class PlatformComponentBrooklynLookup extends AbstractBrooklynResourceLookup<PlatformComponent> {
-
-    public PlatformComponentBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
-        super(root, bmc);
-    }
-
-    @Override
-    public PlatformComponent get(String id) {
-        Entity entity = bmc.getEntityManager().getEntity(id);
-        Builder<? extends PlatformComponent> builder = PlatformComponent.builder()
-            .created(new Date(entity.getCreationTime()))
-            .id(entity.getId())
-            .name(entity.getDisplayName())
-            .externalManagementUri(BrooklynUrlLookup.getUrl(bmc, entity));
-        
-        for (Entity child: entity.getChildren())
-            // FIXME this walks the whole damn tree!
-            builder.add( get(child.getId() ));
-        return builder.build();
-    }
-
-    // platform components are not listed at the top level -- you have to walk the assemblies
-    @Override
-    public List<ResolvableLink<PlatformComponent>> links() {
-        return Collections.emptyList();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
deleted file mode 100644
index 7abb8ad..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
+++ /dev/null
@@ -1,59 +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 io.brooklyn.camp.brooklyn.spi.lookup;
-
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.collection.ResolvableLink;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.management.ManagementContext;
-
-public class PlatformComponentTemplateBrooklynLookup extends AbstractTemplateBrooklynLookup<PlatformComponentTemplate> {
-
-    public PlatformComponentTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
-        super(root, bmc);
-    }
-
-    @Override
-    public PlatformComponentTemplate adapt(CatalogItem<?,?> item) {
-        return PlatformComponentTemplate.builder().
-                name(item.getDisplayName()).
-                id(item.getId()).
-                description(item.getDescription()).
-                created(root.getCreated()).
-                build();
-    }
-
-    @Override
-    public List<ResolvableLink<PlatformComponentTemplate>> links() {
-        Iterable<CatalogItem<Entity,EntitySpec<?>>> l = bmc.getCatalog().getCatalogItems(CatalogPredicates.IS_ENTITY);
-        List<ResolvableLink<PlatformComponentTemplate>> result = new ArrayList<ResolvableLink<PlatformComponentTemplate>>();
-        for (CatalogItem<Entity,EntitySpec<?>> li: l)
-            result.add(newLink(li));
-        return result;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
deleted file mode 100644
index e5369cd..0000000
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
+++ /dev/null
@@ -1,107 +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 io.brooklyn.camp.brooklyn.spi.platform;
-
-import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.brooklyn.spi.lookup.AssemblyBrooklynLookup;
-import io.brooklyn.camp.brooklyn.spi.lookup.AssemblyTemplateBrooklynLookup;
-import io.brooklyn.camp.brooklyn.spi.lookup.PlatformComponentBrooklynLookup;
-import io.brooklyn.camp.brooklyn.spi.lookup.PlatformComponentTemplateBrooklynLookup;
-import io.brooklyn.camp.spi.ApplicationComponent;
-import io.brooklyn.camp.spi.ApplicationComponentTemplate;
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.PlatformComponent;
-import io.brooklyn.camp.spi.PlatformComponentTemplate;
-import io.brooklyn.camp.spi.PlatformRootSummary;
-import io.brooklyn.camp.spi.PlatformTransaction;
-import io.brooklyn.camp.spi.collection.BasicResourceLookup;
-import io.brooklyn.camp.spi.collection.ResourceLookup;
-import io.brooklyn.camp.spi.collection.ResourceLookup.EmptyResourceLookup;
-import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
-import brooklyn.management.ManagementContext;
-
-/** Immutable CAMP platform which reflects things in the underlying Brooklyn system */
-public class BrooklynImmutableCampPlatform extends CampPlatform implements HasBrooklynManagementContext {
-
-    private final ManagementContext bmc;
-    private final AssemblyTemplateBrooklynLookup ats;
-    private final PlatformComponentTemplateBrooklynLookup pcts;
-    private final BasicResourceLookup<ApplicationComponentTemplate> acts;
-    private final PlatformComponentBrooklynLookup pcs;
-    private final AssemblyBrooklynLookup assemblies;
-
-    public BrooklynImmutableCampPlatform(PlatformRootSummary root, ManagementContext managementContext) {
-        super(root);
-        this.bmc = managementContext;
-        
-        // these come from brooklyn
-        pcts = new PlatformComponentTemplateBrooklynLookup(root(), getBrooklynManagementContext());
-        ats = new AssemblyTemplateBrooklynLookup(root(), getBrooklynManagementContext());
-        pcs = new PlatformComponentBrooklynLookup(root(), getBrooklynManagementContext());
-        assemblies = new AssemblyBrooklynLookup(root(), getBrooklynManagementContext(), pcs);
-        
-        // ACT's are not known in brooklyn (everything comes in as config) -- to be extended to support!
-        acts = new BasicResourceLookup<ApplicationComponentTemplate>();
-    }
-
-    // --- brooklyn setup
-    
-    public ManagementContext getBrooklynManagementContext() {
-        return bmc;
-    }
-    
-    // --- camp comatibility setup
-    
-    @Override
-    public ResourceLookup<PlatformComponentTemplate> platformComponentTemplates() {
-        return pcts;
-    }
-
-    @Override
-    public ResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates() {
-        return acts;
-    }
-
-    @Override
-    public ResourceLookup<AssemblyTemplate> assemblyTemplates() {
-        return ats;
-    }
-    
-    @Override
-    public ResourceLookup<PlatformComponent> platformComponents() {
-        return pcs;
-    }
-
-    @Override
-    public ResourceLookup<ApplicationComponent> applicationComponents() {
-        return new EmptyResourceLookup<ApplicationComponent>();
-    }
-
-    @Override
-    public ResourceLookup<Assembly> assemblies() {
-        return assemblies;
-    }
-    
-    @Override
-    public PlatformTransaction transaction() {
-        throw new IllegalStateException(this+" does not support adding new items");
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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
new file mode 100644
index 0000000..4a2078b
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampConstants.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.CampPlatform;
+
+import java.util.Set;
+
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.config.ConfigInheritance;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+
+import com.google.common.collect.ImmutableSet;
+
+public class BrooklynCampConstants {
+
+    public static final String PLAN_ID_FLAG = "planId";
+
+    public static final ConfigKey<String> PLAN_ID = ConfigKeys.builder(String.class, "camp.plan.id")
+            .description("Identifier supplied in the deployment plan for component to which this entity corresponds "
+                        + "(human-readable, for correlating across plan, template, and instance)")
+            .inheritance(ConfigInheritance.NONE)
+            .build();
+
+    public static final ConfigKey<String> TEMPLATE_ID = ConfigKeys.builder(String.class, "camp.template.id")
+            .description("UID of the component in the CAMP template from which this entity was created")
+            .inheritance(ConfigInheritance.NONE)
+            .build();
+
+    public static final ConfigKey<CampPlatform> CAMP_PLATFORM = BrooklynServerConfig.CAMP_PLATFORM;
+
+    public static final Set<String> YAML_URL_PROTOCOL_WHITELIST = ImmutableSet.of("classpath", "http");
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
new file mode 100644
index 0000000..6f941aa
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatform.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.AggregatingCampPlatform;
+import io.brooklyn.camp.CampPlatform;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslInterpreter;
+import org.apache.brooklyn.camp.brooklyn.spi.platform.BrooklynImmutableCampPlatform;
+
+import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+import brooklyn.config.BrooklynProperties;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ManagementContext.PropertiesReloadListener;
+
+/** {@link CampPlatform} implementation which includes Brooklyn entities 
+ * (via {@link BrooklynImmutableCampPlatform})
+ * and allows customisation / additions */
+public class BrooklynCampPlatform extends AggregatingCampPlatform implements HasBrooklynManagementContext {
+
+    private final ManagementContext bmc;
+
+    public BrooklynCampPlatform(PlatformRootSummary root, ManagementContext managementContext) {
+        super(root);
+        addPlatform(new BrooklynImmutableCampPlatform(root, managementContext));
+        
+        this.bmc = managementContext;
+        
+        addMatchers();
+        addInterpreters();
+        
+        managementContext.addPropertiesReloadListener(new PropertiesReloadListener() {
+            private static final long serialVersionUID = -3739276553334749184L;
+            @Override public void reloaded() {
+                setConfigKeyAtManagmentContext();
+            }
+        });
+    }
+
+    // --- brooklyn setup
+    
+    public ManagementContext getBrooklynManagementContext() {
+        return bmc;
+    }
+    
+    protected void addMatchers() {
+        // TODO artifacts
+        pdp().addMatcher(new BrooklynEntityMatcher(bmc));
+    }
+    
+    protected void addInterpreters() {
+        pdp().addInterpreter(new BrooklynDslInterpreter());
+    }
+
+    public BrooklynCampPlatform setConfigKeyAtManagmentContext() {
+        ((BrooklynProperties)bmc.getConfig()).put(BrooklynCampConstants.CAMP_PLATFORM, this);
+        return this;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
new file mode 100644
index 0000000..d1c3cf2
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherAbstract.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.annotations.Beta;
+
+/** launcher for {@link BrooklynCampPlatform}, which may or may not start a (web) server depending on children */
+@Beta
+public abstract class BrooklynCampPlatformLauncherAbstract {
+
+    protected BrooklynCampPlatform platform;
+    protected ManagementContext mgmt;
+    
+    public BrooklynCampPlatformLauncherAbstract useManagementContext(ManagementContext mgmt) {
+        if (this.mgmt!=null && mgmt!=this.mgmt)
+            throw new IllegalStateException("Attempt to change mgmt context; not supported.");
+        
+        this.mgmt = mgmt;
+        
+        return this;
+    }
+    
+    public BrooklynCampPlatformLauncherAbstract launch() {
+        if (platform!=null)
+            throw new IllegalStateException("platform already created");
+
+        if (getBrooklynMgmt()==null)
+            useManagementContext(newMgmtContext());
+        
+        platform = new BrooklynCampPlatform(
+                PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
+                getBrooklynMgmt())
+            .setConfigKeyAtManagmentContext();
+        
+        return this;
+    }
+
+    protected LocalManagementContext newMgmtContext() {
+        return new LocalManagementContext();
+    }
+
+    public ManagementContext getBrooklynMgmt() {
+        return mgmt;
+    }
+    
+    public BrooklynCampPlatform getCampPlatform() {
+        return platform;
+    }
+
+    /** stops any servers (camp and brooklyn) launched by this launcher */
+    public abstract void stopServers() throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.java
new file mode 100644
index 0000000..bbfe2ab
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampPlatformLauncherNoServer.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;
+
+import com.google.common.annotations.Beta;
+
+
+/** launcher for {@link BrooklynCampPlatform}, which does not start a server (and can live in this project) */
+@Beta
+public class BrooklynCampPlatformLauncherNoServer extends BrooklynCampPlatformLauncherAbstract {
+
+    public void stopServers() {
+        // nothing to do
+    }
+    
+    public static void main(String[] args) {
+        new BrooklynCampPlatformLauncherNoServer().launch();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
new file mode 100644
index 0000000..7fe6030
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/BrooklynCampReservedKeys.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public interface BrooklynCampReservedKeys {
+    public static final String BROOKLYN_CONFIG = "brooklyn.config";
+    public static final String BROOKLYN_FLAGS = "brooklyn.flags";
+    public static final String BROOKLYN_POLICIES = "brooklyn.policies";
+    public static final String BROOKLYN_ENRICHERS = "brooklyn.enrichers";
+    public static final String BROOKLYN_CHILDREN = "brooklyn.children";
+    public static final String BROOKLYN_INITIALIZERS = "brooklyn.initializers";
+    public static final String BROOKLYN_CATALOG = "brooklyn.catalog";
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherAbstract.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
new file mode 100644
index 0000000..9e54c49
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherAbstract.java
@@ -0,0 +1,133 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+
+import java.io.Reader;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynShutdownHooks;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.annotations.Beta;
+
+/** convenience for launching YAML files directly */
+@Beta
+public abstract class YamlLauncherAbstract {
+
+    private static final Logger log = LoggerFactory.getLogger(YamlLauncherAbstract.class);
+       
+    protected final BrooklynCampPlatformLauncherAbstract platformLauncher;
+
+    protected final BrooklynCampPlatform platform;
+    protected final ManagementContext brooklynMgmt;
+    protected boolean shutdownAppsOnExit = false;
+
+    public YamlLauncherAbstract() {
+        this.platformLauncher = newPlatformLauncher();
+        platformLauncher.launch();
+        this.platform = platformLauncher.getCampPlatform();
+        this.brooklynMgmt = platformLauncher.getBrooklynMgmt();
+    }
+
+    public ManagementContext getManagementContext() {
+        return brooklynMgmt;
+    }
+
+    public boolean getShutdownAppsOnExit() {
+        return shutdownAppsOnExit;
+    }
+    
+    public void setShutdownAppsOnExit(boolean shutdownAppsOnExit) {
+        this.shutdownAppsOnExit = shutdownAppsOnExit;
+    }
+    
+    protected abstract BrooklynCampPlatformLauncherAbstract newPlatformLauncher();
+
+    public Application launchAppYaml(String url) {
+        return launchAppYaml(url, true);
+    }
+
+    public Application launchAppYaml(String url, boolean waitForTasksToComplete) {
+        try {
+            Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl(url));
+            Application app = launchAppYaml(input, waitForTasksToComplete);
+            log.info("Application started from YAML file "+url+": "+app);
+            return app;
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    public Application launchAppYaml(Reader input) {
+        return launchAppYaml(input, true);
+    }
+
+    public Application launchAppYaml(Reader input, boolean waitForTasksToComplete) {
+        try {
+            AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+            Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+            log.info("Launching "+app);
+
+            if (getShutdownAppsOnExit()) BrooklynShutdownHooks.invokeStopOnShutdown(app);
+
+            if (waitForTasksToComplete) {
+                Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
+                log.info("Waiting on "+tasks.size()+" task(s)");
+                for (Task<?> t: tasks) {
+                    t.blockUntilEnded();
+                }
+            }
+
+            log.info("Application started from YAML: "+app);
+            Entities.dumpInfo(app);
+            return (Application)app;
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    /** kills all apps, web servers, and mgmt context
+     * <p>
+     * this launcher does not support being used again subsequently */
+    public void destroyAll() {
+        Entities.destroyAll(getManagementContext());
+        try {
+            platformLauncher.stopServers();
+        } catch (Exception e) {
+            log.warn("Unable to stop servers (ignoring): "+e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherNoServer.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
new file mode 100644
index 0000000..1ec3c8d
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/YamlLauncherNoServer.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import com.google.common.annotations.Beta;
+
+/** convenience for launching YAML files directly */
+@Beta
+public class YamlLauncherNoServer extends YamlLauncherAbstract {
+
+    @Override
+    protected BrooklynCampPlatformLauncherAbstract newPlatformLauncher() {
+        return new BrooklynCampPlatformLauncherNoServer();
+    }
+
+    public static void main(String[] args) {
+        YamlLauncherNoServer l = new YamlLauncherNoServer();
+        l.setShutdownAppsOnExit(true);
+        
+        l.launchAppYaml("java-web-app-and-db-with-function.yaml");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/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
new file mode 100644
index 0000000..3254e20
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -0,0 +1,283 @@
+/*
+ * 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 io.brooklyn.camp.CampPlatform;
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.AssemblyTemplate.Builder;
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
+import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicApplicationImpl;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.classloading.BrooklynClassLoadingContext;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagementUtils.CreationResult;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.net.Urls;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpecInstantiator {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynAssemblyTemplateInstantiator.class);
+
+    public static final String NEVER_UNWRAP_APPS_PROPERTY = "wrappedApp";
+
+    @Override
+    public Assembly instantiate(AssemblyTemplate template, CampPlatform platform) {
+        Application app = create(template, platform);
+        CreationResult<Application, Void> start = EntityManagementUtils.start(app);
+        log.debug("CAMP created "+app+"; starting in "+start.task());
+        return platform.assemblies().get(app.getApplicationId());
+    }
+
+    public Application create(AssemblyTemplate template, CampPlatform platform) {
+        Application instance = EntityManagementUtils.createUnstarted(getBrooklynManagementContext(platform), template);
+        log.debug("CAMP created {}", instance);
+        return instance;
+    }
+
+    private ManagementContext getBrooklynManagementContext(CampPlatform platform) {
+        return ((HasBrooklynManagementContext)platform).getBrooklynManagementContext();
+    }
+
+    @SuppressWarnings("unchecked")
+    public EntitySpec<? extends Application> createSpec(AssemblyTemplate template, CampPlatform platform, BrooklynClassLoadingContext loader, boolean autoUnwrapIfPossible) {
+        log.debug("CAMP creating application instance for {} ({})", template.getId(), template);
+
+        // AssemblyTemplates created via PDP, _specifying_ then entities to put in
+
+        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
+            loader, buildWrapperAppTemplate(template));
+        EntitySpec<? extends Application> app = resolver.resolveSpec(null);
+
+        // first build the children into an empty shell app
+        List<EntitySpec<?>> childSpecs = buildTemplateServicesAsSpecs(loader, template, platform);
+        for (EntitySpec<?> childSpec : childSpecs) {
+            app.child(childSpec);
+        }
+
+        if (autoUnwrapIfPossible && shouldUnwrap(template, app)) {
+            EntitySpec<? extends Application> oldApp = app;
+            app = (EntitySpec<? extends Application>) Iterables.getOnlyElement( app.getChildren() );
+
+            // 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;
+    }
+
+    private AssemblyTemplate buildWrapperAppTemplate(AssemblyTemplate template) {
+        Builder<? extends AssemblyTemplate> builder = AssemblyTemplate.builder();
+        builder.type("brooklyn:" + BasicApplicationImpl.class.getName());
+        builder.id(template.getId());
+        builder.name(template.getName());
+        builder.sourceCode(template.getSourceCode());
+        for (Entry<String, Object> entry : template.getCustomAttributes().entrySet()) {
+            builder.customAttribute(entry.getKey(), entry.getValue());
+        }
+        builder.instantiator(template.getInstantiator());
+        AssemblyTemplate wrapTemplate = builder.build();
+        return wrapTemplate;
+    }
+
+    protected boolean shouldUnwrap(AssemblyTemplate template, EntitySpec<? extends Application> app) {
+        Object leaveWrapped = template.getCustomAttributes().get(NEVER_UNWRAP_APPS_PROPERTY);
+        if (leaveWrapped!=null) {
+            if (TypeCoercions.coerce(leaveWrapped, Boolean.class))
+                return false;
+        }
+
+        if (app.getChildren().size()!=1)
+            return false;
+
+        EntitySpec<?> childSpec = Iterables.getOnlyElement(app.getChildren());
+        if (childSpec.getType()==null || !Application.class.isAssignableFrom(childSpec.getType()))
+            return false;
+
+        return EntityManagementUtils.hasNoNameOrCustomKeysOrRoot(template, app);
+    }
+
+    private List<EntitySpec<?>> buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform) {
+        return buildTemplateServicesAsSpecsImpl(loader, template, platform, Sets.<String>newLinkedHashSet());
+    }
+
+    private List<EntitySpec<?>> buildTemplateServicesAsSpecsImpl(BrooklynClassLoadingContext loader, AssemblyTemplate template, CampPlatform platform, Set<String> encounteredCatalogTypes) {
+        List<EntitySpec<?>> result = Lists.newArrayList();
+
+        for (ResolvableLink<PlatformComponentTemplate> ctl: template.getPlatformComponentTemplates().links()) {
+            PlatformComponentTemplate appChildComponentTemplate = ctl.resolve();
+            BrooklynComponentTemplateResolver entityResolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, appChildComponentTemplate);
+            EntitySpec<?> spec = resolveSpec(ResourceUtils.create(this), entityResolver, encounteredCatalogTypes);
+
+            result.add(spec);
+        }
+        return result;
+    }
+
+    static EntitySpec<?> resolveSpec(ResourceUtils ru,
+            BrooklynComponentTemplateResolver entityResolver,
+            Set<String> encounteredCatalogTypes) {
+        String brooklynType = entityResolver.getServiceTypeResolver().getBrooklynType(entityResolver.getDeclaredType());
+        CatalogItem<Entity, EntitySpec<?>> item = entityResolver.getServiceTypeResolver().getCatalogItem(entityResolver, entityResolver.getDeclaredType());
+
+        if (log.isTraceEnabled()) log.trace("Building CAMP template services: type="+brooklynType+"; item="+item+"; loader="+entityResolver.getLoader()+"; encounteredCatalogTypes="+encounteredCatalogTypes);
+
+        EntitySpec<?> spec = null;
+        String protocol = Urls.getProtocol(brooklynType);
+        if (protocol != null) {
+            if (BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST.contains(protocol)) {
+                spec = tryResolveYamlUrlReferenceSpec(ru, brooklynType, entityResolver.getLoader(), encounteredCatalogTypes);
+                if (spec != null) {
+                    entityResolver.populateSpec(spec);
+                }
+            } else {
+                // TODO support https above
+                // TODO this will probably be logged if we refer to  chef:cookbook  or other service types which BCTR accepts;
+                // better would be to have BCTR supporting the calls above
+                log.debug("The reference " + brooklynType + " looks like a URL (running the CAMP Brooklyn assembly-template instantiator) but the protocol " +
+                        protocol + " isn't white listed (" + BrooklynCampConstants.YAML_URL_PROTOCOL_WHITELIST + "). " +
+                        "Will try to load it as catalog item or java type.");
+            }
+        }
+
+        if (spec == null) {
+            // load from java or yaml
+            spec = entityResolver.resolveSpec(encounteredCatalogTypes);
+        }
+
+        return spec;
+    }
+
+    private static EntitySpec<?> tryResolveYamlUrlReferenceSpec(
+            ResourceUtils ru,
+            String brooklynType, BrooklynClassLoadingContext itemLoader,
+            Set<String> encounteredCatalogTypes) {
+        ManagementContext mgmt = itemLoader.getManagementContext();
+        Reader yaml;
+        try {
+            yaml = new InputStreamReader(ru.getResourceFromUrl(brooklynType), "UTF-8");
+        } catch (Exception e) {
+            log.warn("AssemblyTemplate type " + brooklynType + " which looks like a URL can't be fetched.", e);
+            return null;
+        }
+        try {
+            return createNestedSpec(mgmt, encounteredCatalogTypes, yaml, itemLoader);
+        } finally {
+            try {
+                yaml.close();
+            } catch (IOException e) {
+                throw Exceptions.propagate(e);
+            }
+        }
+    }
+
+    static EntitySpec<?> resolveCatalogYamlReferenceSpec(
+            ManagementContext mgmt,
+            CatalogItem<Entity, EntitySpec<?>> item,
+            Set<String> encounteredCatalogTypes) {
+
+        String yaml = item.getPlanYaml();
+        Reader input = new StringReader(yaml);
+        BrooklynClassLoadingContext itemLoader = CatalogUtils.newClassLoadingContext(mgmt, item);
+
+        return createNestedSpec(mgmt, encounteredCatalogTypes, input, itemLoader);
+    }
+
+    private static EntitySpec<?> createNestedSpec(ManagementContext mgmt,
+            Set<String> encounteredCatalogTypes, Reader input,
+            BrooklynClassLoadingContext itemLoader) {
+        CampPlatform platform = BrooklynServerConfig.getCampPlatform(mgmt).get();
+
+        AssemblyTemplate at;
+        BrooklynLoaderTracker.setLoader(itemLoader);
+        try {
+            at = platform.pdp().registerDeploymentPlan(input);
+        } finally {
+            BrooklynLoaderTracker.unsetLoader(itemLoader);
+        }
+        return createNestedSpecStatic(at, platform, itemLoader, encounteredCatalogTypes);
+    }
+
+    @Override
+    public EntitySpec<?> createNestedSpec(
+            AssemblyTemplate template,
+            CampPlatform platform,
+            BrooklynClassLoadingContext itemLoader,
+            Set<String> encounteredCatalogTypes) {
+        return createNestedSpecStatic(template, platform, itemLoader, encounteredCatalogTypes);
+    }
+    
+    private static EntitySpec<?> createNestedSpecStatic(
+        AssemblyTemplate template,
+        CampPlatform platform,
+        BrooklynClassLoadingContext itemLoader,
+        Set<String> encounteredCatalogTypes) {
+        // In case we want to allow multiple top-level entities in a catalog we need to think
+        // about what it would mean to subsequently call buildChildrenEntitySpecs on the list of top-level entities!
+        try {
+            AssemblyTemplateInstantiator ati = template.getInstantiator().newInstance();
+            if (ati instanceof BrooklynAssemblyTemplateInstantiator) {
+                List<EntitySpec<?>> specs = ((BrooklynAssemblyTemplateInstantiator)ati).buildTemplateServicesAsSpecsImpl(itemLoader, template, platform, encounteredCatalogTypes);
+                if (specs.size() > 1) {
+                    throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+specs);
+                }
+                return specs.get(0);
+            } else {
+                throw new IllegalStateException("Cannot create application with instantiator: " + ati);
+            }
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+}


[05/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage-cli

Posted by ha...@apache.org.
Package rename to org.apache.brooklyn: usage-cli


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

Branch: refs/heads/master
Commit: 74ee6aaca4cf468ffb820350cb48d3d7f5434035
Parents: 4b80b27
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 5 14:52:37 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 5 16:51:01 2015 +0100

----------------------------------------------------------------------
 .../com/acme/sample/brooklyn/SampleMain.java    |   2 +-
 .../main/java/brooklyn/cli/AbstractMain.java    | 253 -----
 .../main/java/brooklyn/cli/CloudExplorer.java   | 381 -------
 .../src/main/java/brooklyn/cli/ItemLister.java  | 272 -----
 usage/cli/src/main/java/brooklyn/cli/Main.java  | 986 ------------------
 .../java/brooklyn/cli/lister/ClassFinder.java   | 153 ---
 .../brooklyn/cli/lister/ItemDescriptors.java    | 173 ----
 .../org/apache/brooklyn/cli/AbstractMain.java   | 254 +++++
 .../org/apache/brooklyn/cli/CloudExplorer.java  | 381 +++++++
 .../org/apache/brooklyn/cli/ItemLister.java     | 273 +++++
 .../main/java/org/apache/brooklyn/cli/Main.java | 987 +++++++++++++++++++
 .../apache/brooklyn/cli/lister/ClassFinder.java | 153 +++
 .../brooklyn/cli/lister/ItemDescriptors.java    | 173 ++++
 .../cli/src/test/java/brooklyn/cli/CliTest.java | 604 ------------
 .../brooklyn/cli/CloudExplorerLiveTest.java     | 209 ----
 .../java/org/apache/brooklyn/cli/CliTest.java   | 605 ++++++++++++
 .../brooklyn/cli/CloudExplorerLiveTest.java     | 209 ++++
 .../resources/example-app-app-location.yaml     |   2 +-
 .../resources/example-app-entity-location.yaml  |   2 +-
 .../test/resources/example-app-no-location.yaml |   2 +-
 20 files changed, 3039 insertions(+), 3035 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java
----------------------------------------------------------------------
diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java
index e029ede..0fa2e1a 100644
--- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java
+++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/SampleMain.java
@@ -9,7 +9,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.brooklyn.catalog.BrooklynCatalog;
-import brooklyn.cli.Main;
+import org.apache.brooklyn.cli.Main;
 
 import com.google.common.base.Objects.ToStringHelper;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java b/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java
deleted file mode 100644
index c05e0b1..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/AbstractMain.java
+++ /dev/null
@@ -1,253 +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 brooklyn.cli;
-
-import io.airlift.command.Arguments;
-import io.airlift.command.Cli;
-import io.airlift.command.Cli.CliBuilder;
-import io.airlift.command.Command;
-import io.airlift.command.Help;
-import io.airlift.command.Option;
-import io.airlift.command.OptionType;
-import io.airlift.command.ParseException;
-
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import javax.inject.Inject;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.BrooklynVersion;
-import org.apache.brooklyn.catalog.BrooklynCatalog;
-import brooklyn.cli.Main.LaunchCommand;
-import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
-import brooklyn.util.exceptions.FatalRuntimeException;
-import brooklyn.util.exceptions.UserFacingException;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
-
-/**
- * This class is the primary CLI for brooklyn.
- * Run with the `help` argument for help.
- * <p>
- * This class is designed for subclassing, with subclasses typically:
- * <li> providing their own static {@link #main(String...)} (of course) which need simply invoke 
- *      {@link #execCli(String[])} with the arguments 
- * <li> returning their CLI name (e.g. "start.sh") in an overridden {@link #cliScriptName()}
- * <li> providing an overridden {@link LaunchCommand} via {@link #cliLaunchCommand()} if desired
- * <li> providing any other CLI customisations by overriding {@link #cliBuilder()}
- *      (typically calling the parent and then customizing the builder)
- * <li> populating a custom catalog using {@link LaunchCommand#populateCatalog(BrooklynCatalog)}
- */
-public abstract class AbstractMain {
-
-    private static final Logger log = LoggerFactory.getLogger(AbstractMain.class);
-
-    // Launch banner
-    public static final String DEFAULT_BANNER =
-        " _                     _    _             \n" +
-        "| |__  _ __ ___   ___ | | _| |_   _ _ __ (R)\n" +
-        "| '_ \\| '__/ _ \\ / _ \\| |/ / | | | | '_ \\ \n" +
-        "| |_) | | | (_) | (_) |   <| | |_| | | | |\n" +
-        "|_.__/|_|  \\___/ \\___/|_|\\_\\_|\\__, |_| |_|\n" +
-        "                              |___/             "+BrooklynVersion.get()+"\n";
-
-    // Error codes
-    public static final int SUCCESS = 0;
-    public static final int PARSE_ERROR = 1;
-    public static final int EXECUTION_ERROR = 2;
-    public static final int CONFIGURATION_ERROR = 3;
-
-    /**
-     * Field intended for sub-classes (with their own {@code main()}) to customize the banner.
-     * All accesses to the banner are done through this field, to ensure consistent customization.
-     * 
-     * Note that a {@code getBanner()} method is not an option for supporting this, because
-     * it is accessed from static inner-classes (such as {@link InfoCommand}, so non-static
-     * methods are not an option (and one can't override static methods).
-     */
-    protected static volatile String banner = DEFAULT_BANNER;
-    
-    /** abstract superclass for commands defining global options, but not arguments,
-     * as that prevents Help from being injectable in the {@link HelpCommand} subclass */
-    public static abstract class BrooklynCommand implements Callable<Void> {
-
-        @Option(type = OptionType.GLOBAL, name = { "-v", "--verbose" }, description = "Verbose mode")
-        public boolean verbose = false;
-
-        @Option(type = OptionType.GLOBAL, name = { "-q", "--quiet" }, description = "Quiet mode")
-        public boolean quiet = false;
-
-        @VisibleForTesting
-        protected PrintStream stdout = System.out;
-        
-        @VisibleForTesting
-        protected PrintStream stderr = System.err;
-
-        @VisibleForTesting
-        protected InputStream stdin = System.in;
-
-        public ToStringHelper string() {
-            return Objects.toStringHelper(getClass())
-                    .add("verbose", verbose)
-                    .add("quiet", quiet);
-        }
-
-        @Override
-        public String toString() {
-            return string().toString();
-        }
-    }
-    
-    /** common superclass for commands, defining global options (in our super) and extracting the arguments */
-    public static abstract class BrooklynCommandCollectingArgs extends BrooklynCommand {
-
-        /** extra arguments */
-        @Arguments
-        public List<String> arguments = new ArrayList<String>();
-        
-        /** @return true iff there are arguments; it also sys.errs a warning in that case  */
-        protected boolean warnIfArguments() {
-            if (arguments.isEmpty()) return false;
-            stderr.println("Invalid subcommand arguments: "+Strings.join(arguments, " "));
-            return true;
-        }
-        
-        /** throw {@link ParseException} iff there are arguments */
-        protected void failIfArguments() {
-            if (arguments.isEmpty()) return ;
-            throw new ParseException("Invalid subcommand arguments '"+Strings.join(arguments, " ")+"'");
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("arguments", arguments);
-        }
-    }
-
-    @Command(name = "help", description = "Display help for available commands")
-    public static class HelpCommand extends BrooklynCommand {
-
-        @Inject
-        public Help help;
-
-        @Override
-        public Void call() throws Exception {
-            if (log.isDebugEnabled()) log.debug("Invoked help command: {}", this);
-            return help.call();
-        }
-    }
-
-    @Command(name = "info", description = "Display information about brooklyn")
-    public static class InfoCommand extends BrooklynCommandCollectingArgs {
-        
-        @Override
-        public Void call() throws Exception {
-            if (log.isDebugEnabled()) log.debug("Invoked info command: {}", this);
-            warnIfArguments();
-
-            System.out.println(banner);
-            System.out.println("Version:  " + BrooklynVersion.get());
-            if (BrooklynVersion.INSTANCE.isSnapshot()) {
-                System.out.println("Git SHA1: " + BrooklynVersion.INSTANCE.getSha1FromOsgiManifest());
-            }
-            System.out.println("Website:  http://brooklyn.incubator.apache.org");
-            System.out.println("Source:   https://github.com/apache/incubator-brooklyn");
-            System.out.println();
-            System.out.println("Copyright 2011-2015 The Apache Software Foundation.");
-            System.out.println("Licensed under the Apache 2.0 License");
-            System.out.println();
-
-            return null;
-        }
-    }
-
-    public static class DefaultInfoCommand extends InfoCommand {
-        @Override
-        public Void call() throws Exception {
-            super.call();
-            System.out.println("ERROR: No command specified.");
-            System.out.println();
-            throw new ParseException("No command specified.");
-        }
-    }
-
-    /** method intended for overriding when the script filename is different 
-     * @return the name of the script the user has invoked */
-    protected String cliScriptName() {
-        return "brooklyn";
-    }
-
-    /** 
-     * Build the commands.
-     */
-    protected abstract CliBuilder<BrooklynCommand> cliBuilder();
-    
-    protected void execCli(String ...args) {
-        execCli(cliBuilder().build(), args);
-    }
-    
-    protected void execCli(Cli<BrooklynCommand> parser, String ...args) {
-        try {
-            log.debug("Parsing command line arguments: {}", Arrays.asList(args));
-            BrooklynCommand command = parser.parse(args);
-            log.debug("Executing command: {}", command);
-            command.call();
-            System.exit(SUCCESS);
-        } catch (ParseException pe) { // looks like the user typed it wrong
-            System.err.println("Parse error: " + pe.getMessage()); // display
-                                                                   // error
-            System.err.println(getUsageInfo(parser)); // display cli help
-            System.exit(PARSE_ERROR);
-        } catch (FatalConfigurationRuntimeException e) {
-            log.error("Configuration error: "+e.getMessage(), e.getCause());
-            System.err.println("Configuration error: " + e.getMessage());
-            System.exit(CONFIGURATION_ERROR);
-        } catch (FatalRuntimeException e) { // anticipated non-configuration error
-            log.error("Startup error: "+e.getMessage(), e.getCause());
-            System.err.println("Startup error: "+e.getMessage());
-            System.exit(EXECUTION_ERROR);
-        } catch (Exception e) { // unexpected error during command execution
-            log.error("Execution error: " + e.getMessage(), e);
-            System.err.println("Execution error: " + e.getMessage());
-            if (!(e instanceof UserFacingException))
-                e.printStackTrace();
-            System.exit(EXECUTION_ERROR);
-        }
-    }
-
-    protected String getUsageInfo(Cli<BrooklynCommand> parser) {
-        StringBuilder help = new StringBuilder();
-        help.append("\n");
-        Help.help(parser.getMetadata(), Collections.<String>emptyList(), help);
-        return help.toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java
deleted file mode 100644
index 17db6de..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/CloudExplorer.java
+++ /dev/null
@@ -1,381 +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 brooklyn.cli;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import io.airlift.command.Command;
-import io.airlift.command.Option;
-import io.airlift.command.ParseException;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.jclouds.blobstore.BlobStore;
-import org.jclouds.blobstore.BlobStoreContext;
-import org.jclouds.blobstore.domain.Blob;
-import org.jclouds.blobstore.domain.StorageMetadata;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.ComputeMetadata;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.options.TemplateOptions;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.collect.Lists;
-
-/**
- * Convenience for listing Cloud Compute and BlobStore details.
- * <p>
- * For fuller functionality, consider instead the jclouds CLI or Ruby Fog CLI.
- * <p>
- * The advantage of this utility is that it piggie-backs off the {@code brooklyn.property} credentials,
- * so requires less additional credential configuration. It also gives brooklyn-specific information,
- * such as which image will be used by default in a given cloud.
- */
-public class CloudExplorer {
-
-    public static abstract class JcloudsCommand extends AbstractMain.BrooklynCommandCollectingArgs {
-        @Option(name = { "--all-locations" }, title = "all locations",
-                description = "All locations (i.e. all locations in brooklyn.properties for which there are credentials)")
-        public boolean allLocations;
-        
-        @Option(name = { "-l", "--location" }, title = "location spec",
-                description = "A location spec (e.g. referring to a named location in brooklyn.properties file)")
-        public String location;
-
-        @Option(name = { "-y", "--yes" }, title = "auto-confirm",
-                description = "Automatically answer yes to any questions")
-        public boolean autoconfirm = false;
-
-        protected abstract void doCall(JcloudsLocation loc, String indent) throws Exception;
-        
-        @Override
-        public Void call() throws Exception {
-            LocalManagementContext mgmt = new LocalManagementContext();
-            List<JcloudsLocation> locs = Lists.newArrayList();
-            try {
-                if (location != null && allLocations) {
-                    throw new FatalConfigurationRuntimeException("Must not specify --location and --all-locations");
-                } else if (location != null) {
-                    JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(location);
-                    locs.add(loc);
-                } else if (allLocations) {
-                    // Find all named locations that point at different target clouds
-                    Map<String, LocationDefinition> definedLocations = mgmt.getLocationRegistry().getDefinedLocations();
-                    for (LocationDefinition locationDef : definedLocations.values()) {
-                        Location loc = mgmt.getLocationRegistry().resolve(locationDef);
-                        if (loc instanceof JcloudsLocation) {
-                            boolean found = false;
-                            for (JcloudsLocation existing : locs) {
-                                if (equalTargets(existing, (JcloudsLocation) loc)) {
-                                    found = true;
-                                    break;
-                                }
-                            }
-                            if (!found) {
-                                locs.add((JcloudsLocation) loc);
-                            }
-                        }
-                    }
-                } else {
-                    throw new FatalConfigurationRuntimeException("Must specify one of --location or --all-locations");
-                }
-                
-                for (JcloudsLocation loc : locs) {
-                    stdout.println("Location {");
-                    stdout.println("\tprovider: "+loc.getProvider());
-                    stdout.println("\tdisplayName: "+loc.getDisplayName());
-                    stdout.println("\tidentity: "+loc.getIdentity());
-                    if (loc.getEndpoint() != null) stdout.println("\tendpoint: "+loc.getEndpoint());
-                    if (loc.getRegion() != null) stdout.println("\tregion: "+loc.getRegion());
-
-                    try {
-                        doCall(loc, "\t");
-                    } finally {
-                        stdout.println("}");
-                    }
-                }
-            } finally {
-                mgmt.terminate();
-            }
-            return null;
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("location", location);
-        }
-        
-        protected boolean equalTargets(JcloudsLocation loc1, JcloudsLocation loc2) {
-            return Objects.equal(loc1.getProvider(), loc2.getProvider())
-                    && Objects.equal(loc1.getIdentity(), loc2.getIdentity())
-                    && Objects.equal(loc1.getEndpoint(), loc2.getEndpoint())
-                    && Objects.equal(loc1.getRegion(), loc2.getRegion());
-        }
-        
-        
-        protected boolean confirm(String msg, String indent) throws Exception {
-            if (autoconfirm) {
-                stdout.println(indent+"Auto-confirmed: "+msg);
-                return true;
-            } else {
-                stdout.println(indent+"Enter y/n. Are you sure you want to "+msg);
-                int in = stdin.read();
-                boolean confirmed = (Character.toLowerCase(in) == 'y');
-                if (confirmed) {
-                    stdout.println(indent+"Confirmed; will "+msg);
-                } else {
-                    stdout.println(indent+"Declined; will not "+msg);
-                }
-                return confirmed;
-            }
-        }
-    }
-    
-    public static abstract class ComputeCommand extends JcloudsCommand {
-        protected abstract void doCall(ComputeService computeService, String indent) throws Exception;
-            
-        @Override
-        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
-            ComputeService computeService = loc.getComputeService();
-            doCall(computeService, indent);
-        }
-    }
-
-    @Command(name = "list-instances", description = "")
-    public static class ComputeListInstancesCommand extends ComputeCommand {
-        @Override
-        protected void doCall(ComputeService computeService, String indent) throws Exception {
-            failIfArguments();
-            Set<? extends ComputeMetadata> instances = computeService.listNodes();
-            stdout.println(indent+"Instances {");
-            for (ComputeMetadata instance : instances) {
-                stdout.println(indent+"\t"+instance);
-            }
-            stdout.println(indent+"}");
-        }
-    }
-
-    @Command(name = "list-images", description = "")
-    public static class ComputeListImagesCommand extends ComputeCommand {
-        @Override
-        protected void doCall(ComputeService computeService, String indent) throws Exception {
-            failIfArguments();
-            Set<? extends Image> images = computeService.listImages();
-            stdout.println(indent+"Images {");
-            for (Image image : images) {
-                stdout.println(indent+"\t"+image);
-            }
-            stdout.println(indent+"}");
-        }
-    }
-    
-    @Command(name = "list-hardware-profiles", description = "")
-    public static class ComputeListHardwareProfilesCommand extends ComputeCommand {
-        @Override
-        protected void doCall(ComputeService computeService, String indent) throws Exception {
-            failIfArguments();
-            Set<? extends Hardware> hardware = computeService.listHardwareProfiles();
-            stdout.println(indent+"Hardware Profiles {");
-            for (Hardware image : hardware) {
-                stdout.println(indent+"\t"+image);
-            }
-            stdout.println(indent+"}");
-        }
-    }
-    
-    @Command(name = "get-image", description = "")
-    public static class ComputeGetImageCommand extends ComputeCommand {
-        @Override
-        protected void doCall(ComputeService computeService, String indent) throws Exception {
-            if (arguments.isEmpty()) {
-                throw new ParseException("Requires at least one image-id arguments");
-            }
-            
-            for (String imageId : arguments) {
-                Image image = computeService.getImage(imageId);
-                stdout.println(indent+"Image "+imageId+" {");
-                stdout.println(indent+"\t"+image);
-                stdout.println(indent+"}");
-            }
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("imageIds", arguments);
-        }
-    }
-
-    @Command(name = "default-template", description = "")
-    public static class ComputeDefaultTemplateCommand extends JcloudsCommand {
-        @Override
-        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
-            failIfArguments();
-            ComputeService computeService = loc.getComputeService();
-            
-            Template template = loc.buildTemplate(computeService, loc.config().getBag());
-            Image image = template.getImage();
-            Hardware hardware = template.getHardware();
-            org.jclouds.domain.Location location = template.getLocation();
-            TemplateOptions options = template.getOptions();
-            stdout.println(indent+"Default template {");
-            stdout.println(indent+"\tImage: "+image);
-            stdout.println(indent+"\tHardware: "+hardware);
-            stdout.println(indent+"\tLocation: "+location);
-            stdout.println(indent+"\tOptions: "+options);
-            stdout.println(indent+"}");
-        }
-    }
-    
-    @Command(name = "terminate-instances", description = "")
-    public static class ComputeTerminateInstancesCommand extends ComputeCommand {
-        @Override
-        protected void doCall(ComputeService computeService, String indent) throws Exception {
-            if (arguments.isEmpty()) {
-                throw new ParseException("Requires at least one instance-id arguments");
-            }
-            
-            for (String instanceId : arguments) {
-                NodeMetadata instance = computeService.getNodeMetadata(instanceId);
-                if (instance == null) {
-                    stderr.println(indent+"Cannot terminate instance; could not find "+instanceId);
-                } else {
-                    boolean confirmed = confirm(indent, "terminate "+instanceId+" ("+instance+")");
-                    if (confirmed) {
-                        computeService.destroyNode(instanceId);
-                    }
-                }
-            }
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("instanceIds", arguments);
-        }
-    }
-
-    public static abstract class BlobstoreCommand extends JcloudsCommand {
-        protected abstract void doCall(BlobStore blobstore, String indent) throws Exception;
-
-        @Override
-        protected void doCall(JcloudsLocation loc, String indent) throws Exception {
-            String identity = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_IDENTITY), "identity must not be null");
-            String credential = checkNotNull(loc.getConfig(LocationConfigKeys.ACCESS_CREDENTIAL), "credential must not be null");
-            String provider = checkNotNull(loc.getConfig(LocationConfigKeys.CLOUD_PROVIDER), "provider must not be null");
-            String endpoint = loc.getConfig(CloudLocationConfig.CLOUD_ENDPOINT);
-            
-            BlobStoreContext context = JcloudsUtil.newBlobstoreContext(provider, endpoint, identity, credential);
-            try {
-                BlobStore blobStore = context.getBlobStore();
-                doCall(blobStore, indent);
-            } finally {
-                context.close();
-            }
-        }
-    }
-    
-    @Command(name = "list-containers", description = "")
-    public static class BlobstoreListContainersCommand extends BlobstoreCommand {
-        @Override
-        protected void doCall(BlobStore blobstore, String indent) throws Exception {
-            failIfArguments();
-            Set<? extends StorageMetadata> containers = blobstore.list();
-            stdout.println(indent+"Containers {");
-            for (StorageMetadata container : containers) {
-                stdout.println(indent+"\t"+container);
-            }
-            stdout.println(indent+"}");
-        }
-    }
-
-    @Command(name = "list-container", description = "")
-    public static class BlobstoreListContainerCommand extends BlobstoreCommand {
-        @Override
-        protected void doCall(BlobStore blobStore, String indent) throws Exception {
-            if (arguments.isEmpty()) {
-                throw new ParseException("Requires at least one container-name arguments");
-            }
-            
-            for (String containerName : arguments) {
-                Set<? extends StorageMetadata> contents = blobStore.list(containerName);
-                stdout.println(indent+"Container "+containerName+" {");
-                for (StorageMetadata content : contents) {
-                    stdout.println(indent+"\t"+content);
-                }
-                stdout.println(indent+"}");
-            }
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("containers", arguments);
-        }
-    }
-    
-    @Command(name = "blob", description = "")
-    public static class BlobstoreGetBlobCommand extends BlobstoreCommand {
-        @Option(name = { "--container" }, title = "list contents of a given container",
-                description = "")
-        public String container;
-
-        @Option(name = { "--blob" }, title = "retrieves the blog in the given container",
-                description = "")
-        public String blob;
-
-        @Override
-        protected void doCall(BlobStore blobStore, String indent) throws Exception {
-            failIfArguments();
-            Blob content = blobStore.getBlob(container, blob);
-            stdout.println(indent+"Blob "+container+" : " +blob +" {");
-            stdout.println(indent+"\tHeaders {");
-            for (Map.Entry<String, String> entry : content.getAllHeaders().entries()) {
-                stdout.println(indent+"\t\t"+entry.getKey() + " = " + entry.getValue());
-            }
-            stdout.println(indent+"\t}");
-            stdout.println(indent+"\tmetadata : "+content.getMetadata());
-            stdout.println(indent+"\tpayload : "+Streams.readFullyString(content.getPayload().openStream()));
-            stdout.println(indent+"}");
-        }
-        
-        @Override
-        public ToStringHelper string() {
-            return super.string()
-                    .add("container", container)
-                    .add("blob", blob);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/brooklyn/cli/ItemLister.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/ItemLister.java b/usage/cli/src/main/java/brooklyn/cli/ItemLister.java
deleted file mode 100644
index 6ed751c..0000000
--- a/usage/cli/src/main/java/brooklyn/cli/ItemLister.java
+++ /dev/null
@@ -1,272 +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 brooklyn.cli;
-
-import io.airlift.command.Command;
-import io.airlift.command.Option;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.basic.BrooklynObject;
-import org.apache.brooklyn.catalog.Catalog;
-import brooklyn.cli.lister.ClassFinder;
-import brooklyn.cli.lister.ItemDescriptors;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.location.Location;
-import brooklyn.location.LocationResolver;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.net.Urls;
-import brooklyn.util.os.Os;
-import brooklyn.util.text.Strings;
-import brooklyn.util.text.TemplateProcessor;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.google.common.base.Charsets;
-import com.google.common.base.Splitter;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-
-public class ItemLister {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(ItemLister.class);
-    private static final String BASE = "brooklyn/item-lister";
-    private static final String BASE_TEMPLATES = BASE+"/"+"templates";
-    private static final String BASE_STATICS = BASE+"/"+"statics";
-
-    @Command(name = "list-objects", description = "List Brooklyn objects (Entities, Policies, Enrichers and Locations)")
-    public static class ListAllCommand extends AbstractMain.BrooklynCommandCollectingArgs {
-
-        @Option(name = { "--jars" }, title = "Jars", description = "Jars to scan. If a file (not a url) pointing at a directory, will include all files in that directory")
-        public List<String> jars = Lists.newLinkedList();
-
-        @Option(name = { "--type-regex" }, title = "Regex for types to list")
-        public String typeRegex;
-
-        @Option(name = { "--catalog-only" }, title = "Whether to only list items annotated with @Catalog")
-        public boolean catalogOnly = true;
-
-        @Option(name = { "--ignore-impls" }, title = "Ignore Entity implementations, where there is an Entity interface with @ImplementedBy")
-        public boolean ignoreImpls = false;
-
-        @Option(name = { "--headings-only" }, title = "Whether to only show name/type, and not config keys etc")
-        public boolean headingsOnly = false;
-        
-        @Option(name = { "--output-folder" }, title = "Folder to save output")
-        public String outputFolder;
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public Void call() throws Exception {
-            List<URL> urls = getUrls();
-            LOG.info("Retrieving objects from "+urls);
-
-            // TODO Remove duplication from separate ListPolicyCommand etc
-            List<Class<? extends Entity>> entityTypes = getTypes(urls, Entity.class);
-            List<Class<? extends Policy>> policyTypes = getTypes(urls, Policy.class);
-            List<Class<? extends Enricher>> enricherTypes = getTypes(urls, Enricher.class);
-            List<Class<? extends Location>> locationTypes = getTypes(urls, Location.class, Boolean.FALSE);
-
-            Map<String, Object> result = ImmutableMap.<String, Object>builder()
-                    .put("entities", ItemDescriptors.toItemDescriptors(entityTypes, headingsOnly, "name"))
-                    .put("policies", ItemDescriptors.toItemDescriptors(policyTypes, headingsOnly, "name"))
-                    .put("enrichers", ItemDescriptors.toItemDescriptors(enricherTypes, headingsOnly, "name"))
-                    .put("locations", ItemDescriptors.toItemDescriptors(locationTypes, headingsOnly, "type"))
-                    .put("locationResolvers", ItemDescriptors.toItemDescriptors(ImmutableList.copyOf(ServiceLoader.load(LocationResolver.class)), true))
-                    .build();
-
-            String json = toJson(result);
-
-            if (outputFolder == null) {
-                System.out.println(json);
-            } else {
-                LOG.info("Outputting item list (size "+itemCount+") to " + outputFolder);
-                String outputPath = Os.mergePaths(outputFolder, "index.html");
-                String parentDir = (new File(outputPath).getParentFile()).getAbsolutePath();
-                mkdir(parentDir, "entities");
-                mkdir(parentDir, "policies");
-                mkdir(parentDir, "enrichers");
-                mkdir(parentDir, "locations");
-                mkdir(parentDir, "locationResolvers"); //TODO nothing written here yet...
-                
-                mkdir(parentDir, "style");
-                mkdir(Os.mergePaths(parentDir, "style"), "js");
-                mkdir(Os.mergePaths(parentDir, "style", "js"), "catalog");
-                
-                Files.write("var items = " + json, new File(Os.mergePaths(outputFolder, "items.js")), Charsets.UTF_8);
-                ResourceUtils resourceUtils = ResourceUtils.create(this);
-                
-                // root - just loads the above JSON
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "brooklyn-object-list.html", "index.html");
-                
-                // statics - structure mirrors docs (not for any real reason however... the json is usually enough for our docs)
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "common.js");
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "items.css");
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.js");
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/underscore-min.map");
-                copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, "style/js/catalog/bloodhound.js");
-
-                // now make pages for each item
-                
-                List<Map<String, Object>> entities = (List<Map<String, Object>>) result.get("entities");
-                String entityTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "entity.html"));
-                for (Map<String, Object> entity : entities) {
-                    String type = (String) entity.get("type");
-                    String name = (String) entity.get("name");
-                    String entityHtml = TemplateProcessor.processTemplateContents(entityTemplateHtml, ImmutableMap.of("type", type, "name", name));
-                    Files.write(entityHtml, new File(Os.mergePaths(outputFolder, "entities", type + ".html")), Charsets.UTF_8);
-                }
-                
-                List<Map<String, Object>> policies = (List<Map<String, Object>>) result.get("policies");
-                String policyTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "policy.html"));
-                for (Map<String, Object> policy : policies) {
-                    String type = (String) policy.get("type");
-                    String name = (String) policy.get("name");
-                    String policyHtml = TemplateProcessor.processTemplateContents(policyTemplateHtml, ImmutableMap.of("type", type, "name", name));
-                    Files.write(policyHtml, new File(Os.mergePaths(outputFolder, "policies", type + ".html")), Charsets.UTF_8);
-                }
-                
-                List<Map<String, Object>> enrichers = (List<Map<String, Object>>) result.get("enrichers");
-                String enricherTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "enricher.html"));
-                for (Map<String, Object> enricher : enrichers) {
-                    String type = (String) enricher.get("type");
-                    String name = (String) enricher.get("name");
-                    String enricherHtml = TemplateProcessor.processTemplateContents(enricherTemplateHtml, ImmutableMap.of("type", type, "name", name));
-                    Files.write(enricherHtml, new File(Os.mergePaths(outputFolder, "enrichers", type + ".html")), Charsets.UTF_8);
-                }
-                
-                List<Map<String, Object>> locations = (List<Map<String, Object>>) result.get("locations");
-                String locationTemplateHtml = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_TEMPLATES, "location.html"));
-                for (Map<String, Object> location : locations) {
-                    String type = (String) location.get("type");
-                    String locationHtml = TemplateProcessor.processTemplateContents(locationTemplateHtml, ImmutableMap.of("type", type));
-                    Files.write(locationHtml, new File(Os.mergePaths(outputFolder, "locations", type + ".html")), Charsets.UTF_8);
-                }
-                LOG.info("Finished outputting item list to " + outputFolder);
-            }
-            return null;
-        }
-
-        private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item) throws IOException {
-            copyFromItemListerClasspathBaseStaticsToOutputDir(resourceUtils, item, item);
-        }
-        private void copyFromItemListerClasspathBaseStaticsToOutputDir(ResourceUtils resourceUtils, String item, String dest) throws IOException {
-            String js = resourceUtils.getResourceAsString(Urls.mergePaths(BASE_STATICS, item));
-            Files.write(js, new File(Os.mergePaths(outputFolder, dest)), Charsets.UTF_8);
-        }
-
-        private void mkdir(String rootDir, String dirName) {
-            (new File(Os.mergePaths(rootDir, dirName))).mkdirs();
-        }
-
-        protected List<URL> getUrls() throws MalformedURLException {
-            List<URL> urls = Lists.newArrayList();
-            if (jars.isEmpty()) {
-                String classpath = System.getenv("INITIAL_CLASSPATH");
-                if (Strings.isNonBlank(classpath)) {
-                    List<String> entries = Splitter.on(":").omitEmptyStrings().trimResults().splitToList(classpath);
-                    for (String entry : entries) {
-                        if (entry.endsWith(".jar") || entry.endsWith("/*")) {
-                            urls.addAll(ClassFinder.toJarUrls(entry.replace("/*", "")));
-                        }
-                    }
-                } else {
-                    throw new IllegalArgumentException("No Jars to process");
-                }
-            } else {
-                for (String jar : jars) {
-                    List<URL> expanded = ClassFinder.toJarUrls(jar);
-                    if (expanded.isEmpty())
-                        LOG.warn("No jars found at: "+jar);
-                    urls.addAll(expanded);
-                }
-            }
-            return urls;
-        }
-
-        private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type) {
-            return getTypes(urls, type, null);
-        }
-
-        int itemCount = 0;
-        
-        private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type, Boolean catalogOnlyOverride) {
-            FluentIterable<Class<? extends T>> fluent = FluentIterable.from(ClassFinder.findClasses(urls, type));
-            if (typeRegex != null) {
-                fluent = fluent.filter(ClassFinder.withClassNameMatching(typeRegex));
-            }
-            if (catalogOnlyOverride == null ? catalogOnly : catalogOnlyOverride) {
-                fluent = fluent.filter(ClassFinder.withAnnotation(Catalog.class));
-            }
-            List<Class<? extends T>> filtered = fluent.toList();
-            Collection<Class<? extends T>> result;
-            if (ignoreImpls) {
-                result = MutableSet.copyOf(filtered);
-                for (Class<? extends T> clazz : filtered) {
-                    ImplementedBy implementedBy = clazz.getAnnotation(ImplementedBy.class);
-                    if (implementedBy != null) {
-                        result.remove(implementedBy.value());
-                    }
-                }
-            } else {
-                result = filtered;
-            }
-            itemCount += result.size();
-            return ImmutableList.copyOf(result);
-        }
-        
-        private String toJson(Object obj) throws JsonProcessingException {
-            ObjectMapper objectMapper = new ObjectMapper()
-                    .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
-                    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
-                    .enable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)
-                    .enable(SerializationFeature.INDENT_OUTPUT)
-                    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
-                    .setSerializationInclusion(JsonInclude.Include.ALWAYS)
-            
-                    // Only serialise annotated fields
-                    .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
-                    .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
-            
-            return objectMapper.writeValueAsString(obj);
-        }
-    }
-}



[06/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
new file mode 100644
index 0000000..18ce3b3
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlTemplateTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.Assert;
+import org.testng.TestListenerAdapter;
+import org.testng.TestNG;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.CatalogItem;
+import org.apache.brooklyn.catalog.CatalogItem.CatalogItemType;
+import brooklyn.management.osgi.OsgiStandaloneTest;
+import brooklyn.management.osgi.OsgiTestResources;
+import org.apache.brooklyn.test.TestResourceUnavailableException;
+
+
+public class CatalogYamlTemplateTest extends AbstractYamlTest {
+    
+    private static final String SIMPLE_ENTITY_TYPE = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY;
+
+    @Test
+    public void testAddCatalogItem() throws Exception {
+        CatalogItem<?, ?> item = makeItem();
+        assertEquals(item.getCatalogItemType(), CatalogItemType.TEMPLATE);
+        Assert.assertTrue(item.getPlanYaml().indexOf("sample comment")>=0,
+            "YAML did not include original comments; it was:\n"+item.getPlanYaml());
+        Assert.assertFalse(item.getPlanYaml().indexOf("description")>=0,
+            "YAML included metadata which should have been excluded; it was:\n"+item.getPlanYaml());
+
+        deleteCatalogEntity("t1");
+    }
+
+    @Test
+    public void testAddCatalogItemAndCheckSource() throws Exception {
+        // this will fail with the Eclipse TestNG plugin -- use the static main instead to run in eclipse!
+        // see Yamls.KnownClassVersionException for details
+        
+        CatalogItem<?, ?> item = makeItem();
+        Assert.assertTrue(item.getPlanYaml().indexOf("sample comment")>=0,
+            "YAML did not include original comments; it was:\n"+item.getPlanYaml());
+        Assert.assertFalse(item.getPlanYaml().indexOf("description")>=0,
+            "YAML included metadata which should have been excluded; it was:\n"+item.getPlanYaml());
+
+        deleteCatalogEntity("t1");
+    }
+
+    private CatalogItem<?, ?> makeItem() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: t1",
+            "  item_type: template",
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item:",
+            "    services:",
+            "    # this sample comment should be included",
+            "    - type: " + SIMPLE_ENTITY_TYPE);
+
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem("t1", TEST_VERSION);
+        return item;
+    }
+
+    // convenience for running in eclipse when the TestNG plugin drags in old version of snake yaml
+    public static void main(String[] args) {
+        TestListenerAdapter tla = new TestListenerAdapter();
+        TestNG testng = new TestNG();
+        testng.setTestClasses(new Class[] { CatalogYamlTemplateTest.class });
+        testng.addListener(tla);
+        testng.run();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
new file mode 100644
index 0000000..6d5e0b7
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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.catalog;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.catalog.BrooklynCatalog;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.catalog.internal.BasicBrooklynCatalog;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.ConfigKeys;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class CatalogYamlVersioningTest extends AbstractYamlTest {
+    
+    private BrooklynCatalog catalog;
+    
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() {
+        super.setUp();
+        catalog = mgmt().getCatalog();
+    }
+
+    @Test
+    public void testAddItem() {
+        String symbolicName = "sampleId";
+        String version = "0.1.0";
+        addCatalogEntity(symbolicName, version);
+        assertSingleCatalogItem(symbolicName, version);
+    }
+
+    @Test
+    public void testAddUnversionedItem() {
+        String symbolicName = "sampleId";
+        addCatalogEntity(symbolicName, null);
+        assertSingleCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
+    }
+
+    @Test
+    public void testAddSameVersionFailsWhenIconIsDifferent() {
+        String symbolicName = "sampleId";
+        String version = "0.1.0";
+        addCatalogEntity(symbolicName, version);
+        addCatalogEntity(symbolicName, version);
+        try {
+            addCatalogEntity(symbolicName, version, BasicEntity.class.getName(), "classpath:/another/icon.png");
+            fail("Expected to fail");
+        } catch (IllegalStateException e) {
+            assertEquals(e.getMessage(), "Updating existing catalog entries is forbidden: " + symbolicName + ":" + version + ". Use forceUpdate argument to override.");
+        }
+    }
+    
+    @Test
+    public void testAddSameVersionForce() {
+        String symbolicName = "sampleId";
+        String version = "0.1.0";
+        addCatalogEntity(symbolicName, version);
+        forceCatalogUpdate();
+        String expectedType = "brooklyn.entity.basic.BasicApplication";
+        addCatalogEntity(symbolicName, version, expectedType);
+        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, version);
+        assertTrue(item.getPlanYaml().contains(expectedType), "Version not updated");
+    }
+    
+    @Test
+    public void testGetLatest() {
+        String symbolicName = "sampleId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0";
+        addCatalogEntity(symbolicName, v1);
+        addCatalogEntity(symbolicName, v2);
+        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+        assertEquals(item.getVersion(), v2);
+    }
+    
+    @Test
+    public void testGetLatestStable() {
+        String symbolicName = "sampleId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0-SNAPSHOT";
+        addCatalogEntity(symbolicName, v1);
+        addCatalogEntity(symbolicName, v2);
+        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+        assertEquals(item.getVersion(), v1);
+    }
+
+    @Test
+    public void testDelete() {
+        String symbolicName = "sampleId";
+        String version = "0.1.0";
+        addCatalogEntity(symbolicName, version);
+        assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+        catalog.deleteCatalogItem(symbolicName, version);
+        assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+    }
+    
+    @Test
+    public void testDeleteDefault() {
+        String symbolicName = "sampleId";
+        addCatalogEntity(symbolicName, null);
+        assertTrue(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+        catalog.deleteCatalogItem(symbolicName, BasicBrooklynCatalog.NO_VERSION);
+        assertFalse(catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))).iterator().hasNext());
+    }
+    
+    @Test
+    public void testList() {
+        String symbolicName = "sampleId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0-SNAPSHOT";
+        addCatalogEntity(symbolicName, v1);
+        addCatalogEntity(symbolicName, v2);
+        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        assertEquals(Iterables.size(items), 2);
+    }
+    
+    @Test
+    public void testVersionedReference() throws Exception {
+        String symbolicName = "sampleId";
+        String parentName = "parentId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0";
+        String expectedType = BasicApplication.class.getName();
+
+        addCatalogEntity(symbolicName, v1, expectedType);
+        addCatalogEntity(symbolicName, v2);
+        addCatalogEntity(parentName, v1, symbolicName + ":" + v1);
+
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + parentName + ":" + v1);
+
+        assertEquals(app.getEntityType().getName(), expectedType);
+    }
+
+    @Test
+    public void testUnversionedReference() throws Exception {
+        String symbolicName = "sampleId";
+        String parentName = "parentId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0";
+        String expectedType = BasicApplication.class.getName();
+
+        addCatalogEntity(symbolicName, v1);
+        addCatalogEntity(symbolicName, v2, expectedType);
+        addCatalogEntity(parentName, v1, symbolicName);
+
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + parentName + ":" + v1);
+
+        assertEquals(app.getEntityType().getName(), expectedType);
+    }
+
+    private void doTestVersionedReferenceJustAdded(boolean isVersionImplicitSyntax) throws Exception {
+        addCatalogItems(            "brooklyn.catalog:",
+            "  version: 0.9",
+            "  items:",
+            "  - id: referrent",
+            "    item:",
+            "      type: "+BasicEntity.class.getName(),
+            "  - id: referrent",
+            "    version: 1.1",
+            "    item:",
+            "      type: "+BasicEntity.class.getName(),
+            "      brooklyn.config: { foo: bar }",
+            "  - id: referrer",
+            "    version: 1.0",
+            "    item:",
+            (isVersionImplicitSyntax ? 
+                "      type: referrent:1.1" :
+                "      type: referrent\n" +
+                "      version: 1.1"));
+        
+        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo("referrer")));
+        Assert.assertEquals(Iterables.size(items), 1, "Wrong number of: "+items);
+        CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
+        Assert.assertEquals(item.getVersion(), "1.0");
+        
+        Entity app = createAndStartApplication(
+            "services:",
+            (isVersionImplicitSyntax ? 
+                "- type: referrer:1.0" :
+                "- type: referrer\n" +
+                "  version: 1.0") );
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertTrue(child instanceof BasicEntity, "Wrong child: "+child);
+        Assert.assertEquals(child.getConfig(ConfigKeys.newStringConfigKey("foo")), "bar");
+    }
+
+    @Test
+    public void testVersionedReferenceJustAddedExplicitVersion() throws Exception {
+        doTestVersionedReferenceJustAdded(false);
+    }
+    
+    @Test
+    public void testVersionedReferenceJustAddedImplicitVersionSyntax() throws Exception {
+        doTestVersionedReferenceJustAdded(true);
+    }
+    
+    private void assertSingleCatalogItem(String symbolicName, String version) {
+        Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);
+        assertEquals(item.getSymbolicName(), symbolicName);
+        assertEquals(item.getVersion(), version);
+    }
+    
+    private void addCatalogEntity(String symbolicName, String version) {
+        addCatalogEntity(symbolicName, version, BasicEntity.class.getName());
+    }
+
+    private void addCatalogEntity(String symbolicName, String version, String type) {
+        addCatalogEntity(symbolicName, version, type, "classpath://path/to/myicon.jpg");
+    }
+    
+    private void addCatalogEntity(String symbolicName, String version, String type, String iconUrl) {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: "+iconUrl,
+            (version != null ? "  version: " + version : ""),
+            "",
+            "services:",
+            "- type: " + type);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicApp.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
new file mode 100644
index 0000000..6f6fab5
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicApp.java
@@ -0,0 +1,27 @@
+/*
+ * 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.catalog;
+
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.proxying.ImplementedBy;
+
+@ImplementedBy(TestBasicAppImpl.class)
+public interface TestBasicApp extends BasicApplication {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
new file mode 100644
index 0000000..bedbd3b
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/TestBasicAppImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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.catalog;
+
+import brooklyn.entity.basic.BasicApplicationImpl;
+
+public class TestBasicAppImpl extends BasicApplicationImpl implements TestBasicApp {
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
new file mode 100644
index 0000000..4457cb3
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslParseTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.dsl;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.FunctionWithArgs;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.QuotedString;
+import org.testng.annotations.Test;
+
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+@Test
+public class DslParseTest {
+
+    public void testParseString() {
+        assertEquals(new DslParser("\"hello world\"").parse(), new QuotedString(JavaStringEscapes.wrapJavaString("hello world")));
+    }
+
+    public void testParseNoArgFunction() {
+        Object fx = new DslParser("f()").parse();
+        fx = Iterables.getOnlyElement( (List<?>)fx );
+        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
+        assertEquals( ((FunctionWithArgs)fx).getArgs(), ImmutableList.of());
+    }
+    
+    public void testParseOneArgFunction() {
+        Object fx = new DslParser("f(\"x\")").parse();
+        fx = Iterables.getOnlyElement( (List<?>)fx );
+        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
+        assertEquals( ((FunctionWithArgs)fx).getArgs(), Arrays.asList(new QuotedString("\"x\"")) );
+    }
+    
+    public void testParseMultiArgMultiTypeFunction() {
+        // TODO Parsing "f(\"x\", 1)" fails, because it interprets 1 as a function rather than a number. Is that expected?
+        Object fx = new DslParser("f(\"x\", \"y\")").parse();
+        fx = Iterables.getOnlyElement( (List<?>)fx );
+        assertEquals( ((FunctionWithArgs)fx).getFunction(), "f" );
+        assertEquals( ((FunctionWithArgs)fx).getArgs(), ImmutableList.of(new QuotedString("\"x\""), new QuotedString("\"y\"")));
+    }
+
+    
+    public void testParseFunctionChain() {
+        Object fx = new DslParser("f(\"x\").g()").parse();
+        assertTrue(((List<?>)fx).size() == 2, ""+fx);
+        Object fx1 = ((List<?>)fx).get(0);
+        Object fx2 = ((List<?>)fx).get(1);
+        assertEquals( ((FunctionWithArgs)fx1).getFunction(), "f" );
+        assertEquals( ((FunctionWithArgs)fx1).getArgs(), ImmutableList.of(new QuotedString("\"x\"")) );
+        assertEquals( ((FunctionWithArgs)fx2).getFunction(), "g" );
+        assertTrue( ((FunctionWithArgs)fx2).getArgs().isEmpty() );
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
deleted file mode 100644
index 852d9e1..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
+++ /dev/null
@@ -1,32 +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.
-#
-
-# test case which demonstrates osgi bundles can be scanned, *if* expand classpath is true
-
-brooklyn.catalog:
-  items:
-  - scanJavaAnnotations: true
-    version: 2.0.test_java
-    libraries:
-    - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
-    - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
-  - item:
-      id: more-entity
-      type: brooklyn.osgi.tests.more.MoreEntity
-      version: 2.0.test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
deleted file mode 100644
index 0bc4997..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
+++ /dev/null
@@ -1,27 +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.
-#
-services:
-- type: brooklyn.osgi.tests.more.MoreEntity
-
-brooklyn.catalog:
-  id: more-entity-v1
-  version: 1.0
-  # see OsgiTestResources
-  libraries:
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
deleted file mode 100644
index 940053d..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
+++ /dev/null
@@ -1,27 +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.
-#
-services:
-- type: brooklyn.osgi.tests.more.MoreEntity
-
-brooklyn.catalog:
-  id: more-entity
-  version: 1.0
-  # see OsgiTestResources
-  libraries:
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
deleted file mode 100644
index 3c03bd0..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
+++ /dev/null
@@ -1,29 +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.
-#
-services:
-- type: brooklyn.osgi.tests.more.MoreEntity
-  brooklyn.policies:
-  - type: simple-policy:1.0
-
-brooklyn.catalog:
-  id: more-entity
-  version: 1.0
-  # see OsgiTestResources
-  libraries:
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
deleted file mode 100644
index 74323fa..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
+++ /dev/null
@@ -1,28 +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.
-#
-services:
-- type: brooklyn.osgi.tests.more.MoreEntity
-
-brooklyn.catalog:
-  id: more-entity
-  version: 1.0
-  # see OsgiTestResources
-  libraries:
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
deleted file mode 100644
index 47f344d..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
+++ /dev/null
@@ -1,32 +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.
-#
-
-# test case which demonstrates osgi bundles can be scanned, *if* expand classpath is true
-
-brooklyn.catalog:
-  items:
-  - scanJavaAnnotations: true
-    version: 2.0.test_java
-    libraries:
-    - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
-    - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
-  - item:
-      id: more-policy
-      type: brooklyn.osgi.tests.more.MorePolicy
-      version: 2.0.test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml b/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
deleted file mode 100644
index 0004513..0000000
--- a/usage/camp/src/test/resources/io/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
+++ /dev/null
@@ -1,27 +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.
-#
-brooklyn.policies:
-- type: brooklyn.osgi.tests.SimplePolicy
-
-brooklyn.catalog:
-  id: simple-policy
-  version: 1.0
-  # see OsgiTestResources
-  libraries:
-  - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
new file mode 100644
index 0000000..852d9e1
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entities-osgi-catalog-scan.yaml
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+# test case which demonstrates osgi bundles can be scanned, *if* expand classpath is true
+
+brooklyn.catalog:
+  items:
+  - scanJavaAnnotations: true
+    version: 2.0.test_java
+    libraries:
+    - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
+    - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
+  - item:
+      id: more-entity
+      type: brooklyn.osgi.tests.more.MoreEntity
+      version: 2.0.test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
new file mode 100644
index 0000000..0bc4997
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-called-v1-osgi-catalog.yaml
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+services:
+- type: brooklyn.osgi.tests.more.MoreEntity
+
+brooklyn.catalog:
+  id: more-entity-v1
+  version: 1.0
+  # see OsgiTestResources
+  libraries:
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
new file mode 100644
index 0000000..940053d
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-osgi-catalog.yaml
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+services:
+- type: brooklyn.osgi.tests.more.MoreEntity
+
+brooklyn.catalog:
+  id: more-entity
+  version: 1.0
+  # see OsgiTestResources
+  libraries:
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
new file mode 100644
index 0000000..3c03bd0
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v1-with-policy-osgi-catalog.yaml
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+services:
+- type: brooklyn.osgi.tests.more.MoreEntity
+  brooklyn.policies:
+  - type: simple-policy:1.0
+
+brooklyn.catalog:
+  id: more-entity
+  version: 1.0
+  # see OsgiTestResources
+  libraries:
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
new file mode 100644
index 0000000..74323fa
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-entity-v2-osgi-catalog.yaml
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+services:
+- type: brooklyn.osgi.tests.more.MoreEntity
+
+brooklyn.catalog:
+  id: more-entity
+  version: 1.0
+  # see OsgiTestResources
+  libraries:
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
new file mode 100644
index 0000000..47f344d
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/more-policies-osgi-catalog-scan.yaml
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+# test case which demonstrates osgi bundles can be scanned, *if* expand classpath is true
+
+brooklyn.catalog:
+  items:
+  - scanJavaAnnotations: true
+    version: 2.0.test_java
+    libraries:
+    - classpath:/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
+    - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar
+  - item:
+      id: more-policy
+      type: brooklyn.osgi.tests.more.MorePolicy
+      version: 2.0.test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
new file mode 100644
index 0000000..0004513
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/catalog/simple-policy-osgi-catalog.yaml
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+brooklyn.policies:
+- type: brooklyn.osgi.tests.SimplePolicy
+
+brooklyn.catalog:
+  id: simple-policy
+  version: 1.0
+  # see OsgiTestResources
+  libraries:
+  - classpath:/brooklyn/osgi/brooklyn-test-osgi-entities.jar

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/simple-catalog.xml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/simple-catalog.xml b/usage/camp/src/test/resources/simple-catalog.xml
index 242478c..6536bdb 100644
--- a/usage/camp/src/test/resources/simple-catalog.xml
+++ b/usage/camp/src/test/resources/simple-catalog.xml
@@ -29,7 +29,7 @@
         <symbolicName>BasicApp</symbolicName>
     </template>
     <template name="Custom App" type="brooklyn.entity.basic.BasicApplication">
-        <symbolicName>io.brooklyn.camp.brooklyn.catalog.TestBasicApp</symbolicName>
+        <symbolicName>org.apache.brooklyn.camp.brooklyn.catalog.TestBasicApp</symbolicName>
         <!-- Tests that "java:" prefix won't load an old-style catalog item with the same id -->
     </template>
     <template name="Osgi App" type="brooklyn.osgi.tests.SimpleApplication">

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/test-entity-with-init-config.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-entity-with-init-config.yaml b/usage/camp/src/test/resources/test-entity-with-init-config.yaml
index 91167b0..f288363 100644
--- a/usage/camp/src/test/resources/test-entity-with-init-config.yaml
+++ b/usage/camp/src/test/resources/test-entity-with-init-config.yaml
@@ -25,7 +25,7 @@ services:
   name: testentity
   brooklyn.config:
     test.name: Name of the test entity
-- serviceType: io.brooklyn.camp.brooklyn.TestEntityWithInitConfig 
+- serviceType: org.apache.brooklyn.camp.brooklyn.TestEntityWithInitConfig 
   name: testentity with init config
   brooklyn.config:
     test.entity: $brooklyn:component("te1") # This entity will be accessed in TestEntityWithInitConfig.init()

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/test-referencing-enrichers.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-referencing-enrichers.yaml b/usage/camp/src/test/resources/test-referencing-enrichers.yaml
index 4bfc2da..f1d6a24 100644
--- a/usage/camp/src/test/resources/test-referencing-enrichers.yaml
+++ b/usage/camp/src/test/resources/test-referencing-enrichers.yaml
@@ -41,7 +41,7 @@ description: Test multi-layer application with each entity having an enricher re
 origin: https://github.com/apache/incubator-brooklyn
 id: app1
 brooklyn.enrichers:
-  - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+  - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")
@@ -51,11 +51,11 @@ brooklyn.enrichers:
       test.reference.grandchild1: $brooklyn:component("gc1")
       test.reference.grandchild2: $brooklyn:component("gc2")
 services:
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e1
   name: entity 1
   brooklyn.enrichers:
-  - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+  - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")
@@ -65,11 +65,11 @@ services:
       test.reference.grandchild1: $brooklyn:component("gc1")
       test.reference.grandchild2: $brooklyn:component("gc2")
   brooklyn.children:
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c1
       name: child 1
       brooklyn.enrichers:
-      - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+      - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
         brooklyn.config:
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
@@ -79,11 +79,11 @@ services:
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2")
       brooklyn.children:
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc1
         name: grandchild 1
         brooklyn.enrichers:
-        - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+        - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
           brooklyn.config:
             test.reference.app: $brooklyn:component("app1")
             test.reference.entity1: $brooklyn:component("e1")
@@ -92,11 +92,11 @@ services:
             test.reference.child2: $brooklyn:component("c2")
             test.reference.grandchild1: $brooklyn:component("gc1")
             test.reference.grandchild2: $brooklyn:component("gc2")
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc2
         name: grandchild 2
         brooklyn.enrichers:
-        - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+        - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
           brooklyn.config:
             test.reference.app: $brooklyn:component("app1")
             test.reference.entity1: $brooklyn:component("e1")
@@ -105,11 +105,11 @@ services:
             test.reference.child2: $brooklyn:component("c2")
             test.reference.grandchild1: $brooklyn:component("gc1")
             test.reference.grandchild2: $brooklyn:component("gc2") 
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c2
       name: child 2
       brooklyn.enrichers:
-      - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+      - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
         brooklyn.config:
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
@@ -118,11 +118,11 @@ services:
           test.reference.child2: $brooklyn:component("c2")
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2")
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e2
   name: entity 2
   brooklyn.enrichers:
-  - enricherType: io.brooklyn.camp.brooklyn.TestReferencingEnricher
+  - enricherType: org.apache.brooklyn.camp.brooklyn.TestReferencingEnricher
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/test-referencing-entities.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-referencing-entities.yaml b/usage/camp/src/test/resources/test-referencing-entities.yaml
index e37d851..19944c3 100644
--- a/usage/camp/src/test/resources/test-referencing-entities.yaml
+++ b/usage/camp/src/test/resources/test-referencing-entities.yaml
@@ -47,7 +47,7 @@ brooklyn.config:
   test.reference.grandchild2: $brooklyn:component("gc2")
   test.reference.bogus: $brooklyn:child("c1")
 services:
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e1
   name: entity 1
   brooklyn.config:
@@ -61,7 +61,7 @@ services:
     test.reference.grandchild2: $brooklyn:component("gc2")
     test.reference.bogus: $brooklyn:descendant("app1")
   brooklyn.children:
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c1
       name: child 1
       brooklyn.config:
@@ -76,7 +76,7 @@ services:
         test.reference.grandchild2: $brooklyn:component("gc2")
         test.reference.bogus: $brooklyn:component("bogus")
       brooklyn.children:
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc1
         name: grandchild 1
         brooklyn.config:
@@ -87,7 +87,7 @@ services:
           test.reference.child2: $brooklyn:component("c2")
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2")
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc2
         name: grandchild 2
         brooklyn.config:
@@ -98,7 +98,7 @@ services:
           test.reference.child2: $brooklyn:component("c2")
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2") 
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c2
       name: child 2
       brooklyn.config:
@@ -109,7 +109,7 @@ services:
         test.reference.child2: $brooklyn:component("c2")
         test.reference.grandchild1: $brooklyn:component("gc1")
         test.reference.grandchild2: $brooklyn:component("gc2")
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e2
   name: entity 2
   brooklyn.config:

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/resources/test-referencing-policies.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-referencing-policies.yaml b/usage/camp/src/test/resources/test-referencing-policies.yaml
index 35f0233..ff06f5b 100644
--- a/usage/camp/src/test/resources/test-referencing-policies.yaml
+++ b/usage/camp/src/test/resources/test-referencing-policies.yaml
@@ -41,7 +41,7 @@ description: Test multi-layer application with each entity having a policy refer
 origin: https://github.com/apache/incubator-brooklyn
 id: app1
 brooklyn.policies:
-  - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+  - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")
@@ -51,11 +51,11 @@ brooklyn.policies:
       test.reference.grandchild1: $brooklyn:component("gc1")
       test.reference.grandchild2: $brooklyn:component("gc2")
 services:
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e1
   name: entity 1
   brooklyn.policies:
-  - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+  - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")
@@ -65,11 +65,11 @@ services:
       test.reference.grandchild1: $brooklyn:component("gc1")
       test.reference.grandchild2: $brooklyn:component("gc2")
   brooklyn.children:
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c1
       name: child 1
       brooklyn.policies:
-      - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+      - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
         brooklyn.config:
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
@@ -79,11 +79,11 @@ services:
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2")
       brooklyn.children:
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc1
         name: grandchild 1
         brooklyn.policies:
-        - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+        - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
           brooklyn.config:
             test.reference.app: $brooklyn:component("app1")
             test.reference.entity1: $brooklyn:component("e1")
@@ -92,11 +92,11 @@ services:
             test.reference.child2: $brooklyn:component("c2")
             test.reference.grandchild1: $brooklyn:component("gc1")
             test.reference.grandchild2: $brooklyn:component("gc2")
-      - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+      - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
         id: gc2
         name: grandchild 2
         brooklyn.policies:
-        - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+        - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
           brooklyn.config:
             test.reference.app: $brooklyn:component("app1")
             test.reference.entity1: $brooklyn:component("e1")
@@ -105,11 +105,11 @@ services:
             test.reference.child2: $brooklyn:component("c2")
             test.reference.grandchild1: $brooklyn:component("gc1")
             test.reference.grandchild2: $brooklyn:component("gc2") 
-    - serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+    - serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
       id: c2
       name: child 2
       brooklyn.policies:
-      - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+      - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
         brooklyn.config:
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
@@ -118,11 +118,11 @@ services:
           test.reference.child2: $brooklyn:component("c2")
           test.reference.grandchild1: $brooklyn:component("gc1")
           test.reference.grandchild2: $brooklyn:component("gc2")
-- serviceType: io.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
+- serviceType: org.apache.brooklyn.camp.brooklyn.ReferencingYamlTestEntity
   id: e2
   name: entity 2
   brooklyn.policies:
-  - policyType: io.brooklyn.camp.brooklyn.TestReferencingPolicy
+  - policyType: org.apache.brooklyn.camp.brooklyn.TestReferencingPolicy
     brooklyn.config:
       test.reference.app: $brooklyn:component("app1")
       test.reference.entity1: $brooklyn:component("e1")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/launcher/src/main/java/brooklyn/launcher/BrooklynLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynLauncher.java b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynLauncher.java
index 76ded17..eb4fb82 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynLauncher.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynLauncher.java
@@ -33,6 +33,8 @@ import java.util.concurrent.TimeoutException;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -103,8 +105,6 @@ import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;
 import io.brooklyn.camp.CampPlatform;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
 import io.brooklyn.camp.spi.AssemblyTemplate;
 import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java b/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
index c8e7df4..3bd4823 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
@@ -19,14 +19,15 @@
 package brooklyn.launcher.camp;
 
 import io.brooklyn.camp.CampServer;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatform;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
 import io.brooklyn.camp.spi.PlatformRootSummary;
 import brooklyn.entity.basic.BrooklynShutdownHooks;
 import brooklyn.launcher.BrooklynLauncher;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.internal.LocalManagementContext;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
+
 import com.google.common.annotations.Beta;
 
 /** variant of super who also starts a CampServer for convenience */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/launcher/src/main/java/brooklyn/launcher/camp/SimpleYamlLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/camp/SimpleYamlLauncher.java b/usage/launcher/src/main/java/brooklyn/launcher/camp/SimpleYamlLauncher.java
index ad3e281..0603ded 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/camp/SimpleYamlLauncher.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/camp/SimpleYamlLauncher.java
@@ -18,8 +18,8 @@
  */
 package brooklyn.launcher.camp;
 
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
-import io.brooklyn.camp.brooklyn.YamlLauncherAbstract;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
+import org.apache.brooklyn.camp.brooklyn.YamlLauncherAbstract;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/launcher/src/test/java/brooklyn/launcher/blueprints/AbstractBlueprintTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/launcher/blueprints/AbstractBlueprintTest.java b/usage/launcher/src/test/java/brooklyn/launcher/blueprints/AbstractBlueprintTest.java
index ec084e9..63a8bfb 100644
--- a/usage/launcher/src/test/java/brooklyn/launcher/blueprints/AbstractBlueprintTest.java
+++ b/usage/launcher/src/test/java/brooklyn/launcher/blueprints/AbstractBlueprintTest.java
@@ -19,13 +19,13 @@
 package brooklyn.launcher.blueprints;
 
 import static org.testng.Assert.assertNotEquals;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
 
 import java.io.File;
 import java.io.Reader;
 import java.io.StringReader;
 import java.util.Collection;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index 138a4ca..08511b7 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -19,8 +19,6 @@
 package brooklyn.rest;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 
 import java.io.File;
 import java.io.FilenameFilter;
@@ -32,6 +30,8 @@ import java.util.List;
 import javax.servlet.DispatcherType;
 import javax.servlet.Filter;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.servlet.FilterHolder;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
index eabeef1..ff16c29 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
@@ -19,13 +19,13 @@
 package brooklyn.rest;
 
 import static org.testng.Assert.assertEquals;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 
 import java.io.File;
 import java.net.URI;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 import org.apache.http.HttpStatus;
 import org.apache.http.client.HttpClient;
 import org.eclipse.jetty.server.Server;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
index af8909a..36a7cd4 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/BrooklynRestApiTest.java
@@ -18,6 +18,7 @@
  */
 package brooklyn.rest.testing;
 
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeMethod;
@@ -45,7 +46,6 @@ import brooklyn.rest.util.TestShutdownHandler;
 import brooklyn.rest.util.json.BrooklynJacksonJsonProvider;
 import brooklyn.test.entity.LocalManagementContextForTests;
 import brooklyn.util.exceptions.Exceptions;
-import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 
 public abstract class BrooklynRestApiTest {
 


[09/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
new file mode 100644
index 0000000..16bd3e5
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.basic.Propagator;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityAdjuncts;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.policy.Enricher;
+import brooklyn.test.Asserts;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.test.policy.TestEnricher;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+@Test
+public class EnrichersYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(EnrichersYamlTest.class);
+
+    @Test
+    public void testWithAppEnricher() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-app-with-enricher.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-app-with-enricher");
+        
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(app).size(), 1);
+        final Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(app).iterator().next();
+        Assert.assertTrue(enricher instanceof TestEnricher, "enricher="+enricher);
+        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_NAME), "Name from YAML");
+        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
+        
+        Entity target = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
+            public Entity call() {
+                return enricher.getConfig(TestEnricher.TARGET_ENTITY);
+            }}).get();
+        Assert.assertNotNull(target);
+        Assert.assertEquals(target.getDisplayName(), "testentity");
+        Assert.assertEquals(target, app.getChildren().iterator().next());
+        Entity targetFromFlag = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
+            public Entity call() {
+                return enricher.getConfig(TestEnricher.TARGET_ENTITY_FROM_FLAG);
+            }}).get();
+        Assert.assertEquals(targetFromFlag, target);
+        Map<?, ?> leftoverProperties = ((TestEnricher) enricher).getLeftoverProperties();
+        Assert.assertEquals(leftoverProperties.get("enricherLiteralValue1"), "Hello");
+        Assert.assertEquals(leftoverProperties.get("enricherLiteralValue2"), "World");
+        Assert.assertEquals(leftoverProperties.size(), 2);
+    }
+    
+    @Test
+    public void testWithEntityEnricher() throws Exception {
+        final Entity app = createAndStartApplication(loadYaml("test-entity-with-enricher.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-entity-with-enricher");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(app).size(), 0);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        final Entity child = app.getChildren().iterator().next();
+        Asserts.eventually(new Supplier<Integer>() {
+            @Override
+            public Integer get() {
+                return EntityAdjuncts.getNonSystemEnrichers(child).size();
+            }
+        }, Predicates.<Integer> equalTo(1));        
+        final Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(child).iterator().next();
+        Assert.assertNotNull(enricher);
+        Assert.assertTrue(enricher instanceof TestEnricher, "enricher=" + enricher + "; type=" + enricher.getClass());
+        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_NAME), "Name from YAML");
+        Assert.assertEquals(enricher.getConfig(TestEnricher.CONF_FROM_FUNCTION), "$brooklyn: is a fun place");
+        
+        Assert.assertEquals(((TestEnricher) enricher).getLeftoverProperties(),
+                ImmutableMap.of("enricherLiteralValue1", "Hello", "enricherLiteralValue2", "World"));
+    }
+    
+    @Test
+    public void testPropagatingEnricher() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-propagating-enricher.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-propagating-enricher");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        TestEntity entity = (TestEntity)app.getChildren().iterator().next();
+        entity.setAttribute(TestEntity.NAME, "New Name");
+        Asserts.eventually(Entities.attributeSupplier(app, TestEntity.NAME), Predicates.<String>equalTo("New Name"));
+    }
+    
+    @Test
+    public void testPropogateChildSensor() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
+                    "  brooklyn.config:",
+                    "    test.confName: parent entity",
+                    "  id: parentId",
+                    "  brooklyn.enrichers:",
+                    "  - enricherType: brooklyn.enricher.basic.Propagator",
+                    "    brooklyn.config:",
+                    "      enricher.producer: $brooklyn:component(\"childId\")",
+                    "      enricher.propagating.propagatingAll: true",
+                    "  brooklyn.children:",
+                    "  - serviceType: brooklyn.test.entity.TestEntity",
+                    "    id: childId",
+                    "    brooklyn.config:",
+                    "      test.confName: Child Name"));
+        waitForApplicationTasks(app);
+        
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        final Entity parentEntity = app.getChildren().iterator().next();
+        Assert.assertTrue(parentEntity instanceof TestEntity, "Expected parent entity to be TestEntity, found:" + parentEntity);
+        Assert.assertEquals(parentEntity.getChildren().size(), 1);
+        Entity childEntity = parentEntity.getChildren().iterator().next();
+        Assert.assertTrue(childEntity instanceof TestEntity, "Expected child entity to be TestEntity, found:" + childEntity);
+        Asserts.eventually(new Supplier<Integer>() {
+            @Override
+            public Integer get() {
+                return EntityAdjuncts.getNonSystemEnrichers(parentEntity).size();
+            }
+        }, Predicates.<Integer>equalTo(1));
+        Enricher enricher = EntityAdjuncts.getNonSystemEnrichers(parentEntity).iterator().next();
+        Asserts.assertTrue(enricher instanceof Propagator, "Expected enricher to be Propagator, found:" + enricher);
+        final Propagator propagator = (Propagator)enricher;
+        Entity producer = ((EntityInternal)parentEntity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
+            public Entity call() {
+                return propagator.getConfig(Propagator.PRODUCER);
+            }}).get();
+        Assert.assertEquals(producer, childEntity);
+        Asserts.assertTrue(Boolean.valueOf(propagator.getConfig(Propagator.PROPAGATING_ALL)), "Expected Propagator.PROPAGATING_ALL to be true");
+        ((TestEntity)childEntity).setAttribute(TestEntity.NAME, "New Name");
+        Asserts.eventually(Entities.attributeSupplier(parentEntity, TestEntity.NAME), Predicates.<String>equalTo("New Name"));
+    }
+    
+    @Test
+    public void testMultipleEnricherReferences() throws Exception {
+        final Entity app = createAndStartApplication(loadYaml("test-referencing-enrichers.yaml"));
+        waitForApplicationTasks(app);
+        
+        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
+        
+        Assert.assertEquals(app.getChildren().size(), 2);
+        for (Entity child : app.getChildren()) {
+            if (child.getDisplayName().equals("entity 1"))
+                entity1 = child;
+            if (child.getDisplayName().equals("entity 2"))
+                entity2 = child;
+        }
+        Assert.assertNotNull(entity1);
+        Assert.assertNotNull(entity2);
+        
+        Assert.assertEquals(entity1.getChildren().size(), 2);
+        for (Entity child : entity1.getChildren()) {
+            if (child.getDisplayName().equals("child 1"))
+                child1 = child;
+            if (child.getDisplayName().equals("child 2"))
+                child2 = child;
+        }
+        Assert.assertNotNull(child1);
+        Assert.assertNotNull(child2);
+        
+        Assert.assertEquals(child1.getChildren().size(), 2);
+        for (Entity child : child1.getChildren()) {
+            if (child.getDisplayName().equals("grandchild 1"))
+               grandchild1 = child;
+            if (child.getDisplayName().equals("grandchild 2"))
+                grandchild2 = child;
+        }
+        Assert.assertNotNull(grandchild1);
+        Assert.assertNotNull(grandchild2);
+        
+        ImmutableSet<Enricher> enrichers = new ImmutableSet.Builder<Enricher>()
+                .add(getEnricher(app))
+                .add(getEnricher(entity1))
+                .add(getEnricher(entity2))
+                .add(getEnricher(child1))
+                .add(getEnricher(child2))
+                .add(getEnricher(grandchild1))
+                .add(getEnricher(grandchild2))
+                .build();
+        
+        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
+                .put(TestReferencingEnricher.TEST_APPLICATION, app)
+                .put(TestReferencingEnricher.TEST_ENTITY_1, entity1)
+                .put(TestReferencingEnricher.TEST_ENTITY_2, entity2)
+                .put(TestReferencingEnricher.TEST_CHILD_1, child1)
+                .put(TestReferencingEnricher.TEST_CHILD_2, child2)
+                .put(TestReferencingEnricher.TEST_GRANDCHILD_1, grandchild1)
+                .put(TestReferencingEnricher.TEST_GRANDCHILD_2, grandchild2)
+                .build();
+        
+        for (Enricher enricher : enrichers)
+            checkReferences(enricher, keyToEntity);
+    }
+    
+    private void checkReferences(final Enricher enricher, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
+        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
+            final Entity entity = keyToEntity.get(key); // Grab an entity whose execution context we can use
+            Entity fromConfig = ((EntityInternal)entity).getExecutionContext().submit(MutableMap.of(), new Callable<Entity>() {
+                @Override
+                public Entity call() throws Exception {
+                    return (Entity) enricher.getConfig(key);
+                }
+            }).get();
+            Assert.assertEquals(fromConfig, keyToEntity.get(key));
+        }
+    }
+    
+    private Enricher getEnricher(Entity entity) {
+        List<Enricher> enrichers = EntityAdjuncts.getNonSystemEnrichers(entity);
+        Assert.assertEquals(enrichers.size(), 1, "Wrong number of enrichers: "+enrichers);
+        Enricher enricher = enrichers.iterator().next();
+        Assert.assertTrue(enricher instanceof TestReferencingEnricher, "Wrong enricher: "+enricher);
+        return enricher;
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
new file mode 100644
index 0000000..4933e5d
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlIntegrationTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import static org.testng.Assert.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Iterables;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.proxy.nginx.NginxController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.tomcat.TomcatServer;
+
+public class EntitiesYamlIntegrationTest extends AbstractYamlTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EntitiesYamlIntegrationTest.class);
+
+    @Test(groups = "Integration")
+    public void testStartTomcatCluster() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-tomcat-cluster.yaml"));
+        waitForApplicationTasks(app);
+
+        assertNotNull(app);
+        assertEquals(app.getChildren().size(), 1);
+        final Entity entity = Iterables.getOnlyElement(app.getChildren());
+        assertTrue(entity instanceof ControlledDynamicWebAppCluster, "entity="+entity);
+        ControlledDynamicWebAppCluster cluster = (ControlledDynamicWebAppCluster) entity;
+
+        assertTrue(cluster.getController() instanceof NginxController, "controller="+cluster.getController());
+        Iterable<TomcatServer> tomcats = FluentIterable.from(cluster.getCluster().getMembers()).filter(TomcatServer.class);
+        assertEquals(Iterables.size(tomcats), 2);
+        for (TomcatServer tomcat : tomcats) {
+            assertTrue(tomcat.getAttribute(TomcatServer.SERVICE_UP), "serviceup");
+        }
+
+        EntitySpec<?> spec = entity.getConfig(DynamicCluster.MEMBER_SPEC);
+        assertNotNull(spec);
+        assertEquals(spec.getType(), TomcatServer.class);
+        assertEquals(spec.getConfig().get(DynamicCluster.QUARANTINE_FAILED_ENTITIES), Boolean.FALSE);
+        assertEquals(spec.getConfig().get(DynamicCluster.INITIAL_QUORUM_SIZE), 2);
+    }
+
+
+    @Override
+    protected Logger getLogger() {
+        return LOG;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
new file mode 100644
index 0000000..e873ffa
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -0,0 +1,919 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Application;
+import brooklyn.entity.Effector;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityFunctions;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityPredicates;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.SameServerEntity;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.location.Location;
+import brooklyn.management.Task;
+import brooklyn.management.internal.EntityManagementUtils;
+import brooklyn.management.internal.EntityManagerInternal;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.test.entity.TestEntityImpl;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Functionals;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+@Test
+public class EntitiesYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(EntitiesYamlTest.class);
+
+    protected Entity setupAndCheckTestEntityInBasicYamlWith(String ...extras) throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", extras));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+        
+        Assert.assertTrue(app.getChildren().iterator().hasNext(), "Expected app to have child entity");
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+        
+        return (TestEntity)entity;
+    }
+    
+    @Test
+    public void testSingleEntity() throws Exception {
+        setupAndCheckTestEntityInBasicYamlWith();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testBrooklynConfig() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  brooklyn.config:",
+            "    test.confName: Test Entity Name",
+            "    test.confMapPlain:",
+            "      foo: bar",
+            "      baz: qux",
+            "    test.confListPlain:",
+            "      - dogs",
+            "      - cats",
+            "      - badgers",
+            "    test.confSetThing: !!set",
+            "      ? square",
+            "      ? circle",
+            "      ? triangle",
+            "    test.confObject: 5");
+        
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Test Entity Name");
+        List<String> list = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
+        Assert.assertEquals(list, ImmutableList.of("dogs", "cats", "badgers"));
+        Map<String, String> map = testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
+        Assert.assertEquals(map, ImmutableMap.of("foo", "bar", "baz", "qux"));
+        Set<String> set = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_THING);
+        Assert.assertEquals(set, ImmutableSet.of("square", "circle", "triangle"));
+        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
+        Assert.assertEquals(object, 5);
+    }
+
+    @Test
+    public void testFlagInBrooklynConfig() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  brooklyn.config:",
+            "    confName: Foo Bar");
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testUndeclaredItemInBrooklynConfig() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  brooklyn.config:",
+            "    test.dynamic.confName: Foo Bar");
+        Assert.assertEquals(testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName")), "Foo Bar");
+    }
+
+    @Test
+    public void testFlagAtRoot() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  confName: Foo Bar");
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testFlagAtRootEntityImpl() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- serviceType: " + TestEntityImpl.class.getName(),
+                "  confName: Foo Bar");
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testConfigKeyAtRoot() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  test.confName: Foo Bar");
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testUndeclaredItemAtRootIgnored() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  test.dynamic.confName: Foo Bar");
+        // should NOT be set (and there should be a warning in the log)
+        String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
+        Assert.assertNull(dynamicConfNameValue);
+    }
+
+    @Test
+    public void testExplicitFlags() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  brooklyn.flags:",
+            "    confName: Foo Bar");
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testExplicitFlagsEntityImpl() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- serviceType: " + TestEntityImpl.class.getName(),
+                "  brooklyn.flags:",
+                "    confName: Foo Bar");
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "Foo Bar");
+    }
+
+    @Test
+    public void testUndeclaredExplicitFlagsIgnored() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith( 
+            "  brooklyn.flags:",
+            "    test.dynamic.confName: Foo Bar");
+        String dynamicConfNameValue = testEntity.getConfig(ConfigKeys.newStringConfigKey("test.dynamic.confName"));
+        Assert.assertNull(dynamicConfNameValue);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testEmptyConfig() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
+            "  brooklyn.config:",
+            "    test.confName: \"\"",
+            "    test.confListPlain: !!seq []",
+            "    test.confMapPlain: !!map {}",
+            "    test.confSetPlain: !!set {}",
+            "    test.confObject: \"\""));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertNotNull(entity, "Expected app to have child entity");
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+        TestEntity testEntity = (TestEntity) entity;
+        Assert.assertEquals(testEntity.getConfig(TestEntity.CONF_NAME), "");
+        List<String> list = testEntity.getConfig(TestEntity.CONF_LIST_PLAIN);
+        Assert.assertEquals(list, ImmutableList.of());
+        Map<String, String> map = testEntity.getConfig(TestEntity.CONF_MAP_PLAIN);
+        Assert.assertEquals(map, ImmutableMap.of());
+        // TODO: CONF_SET_PLAIN is being set to an empty ArrayList - may be a snakeyaml issue?
+        //        Set<String> plainSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_PLAIN);
+        //        Assert.assertEquals(plainSet, ImmutableSet.of());
+        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
+        Assert.assertEquals(object, "");
+    }
+    
+    @SuppressWarnings("unchecked")
+    public void testEmptyStructuredConfig() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
+            "  brooklyn.config:",
+            "    test.confName: \"\"",
+            "    test.confListThing: !!seq []",
+            "    test.confSetThing: !!set {}",
+            "    test.confMapThing: !!map {}"));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertNotNull(entity, "Expected app to have child entity");
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+        TestEntity testEntity = (TestEntity) entity;
+        List<String> thingList = (List<String>)testEntity.getConfig(TestEntity.CONF_LIST_THING);
+        Set<String> thingSet = (Set<String>)testEntity.getConfig(TestEntity.CONF_SET_THING);
+        Map<String, String> thingMap = (Map<String, String>)testEntity.getConfig(TestEntity.CONF_MAP_THING);
+        Assert.assertEquals(thingList, Lists.newArrayList());
+        Assert.assertEquals(thingSet, ImmutableSet.of());
+        Assert.assertEquals(thingMap, ImmutableMap.of());
+    }
+
+    @Test
+    public void testSensor() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
+            "  brooklyn.config:",
+            "    test.confObject: $brooklyn:sensor(\"brooklyn.test.entity.TestEntity\", \"test.sequence\")"));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getDisplayName(), "test-entity-basic-template");
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertNotNull(entity, "Expected app to have child entity");
+        Assert.assertTrue(entity instanceof TestEntity, "Expected TestEntity, found " + entity.getClass());
+        TestEntity testEntity = (TestEntity) entity;
+        Object object = testEntity.getConfig(TestEntity.CONF_OBJECT);
+        Assert.assertNotNull(object);
+        Assert.assertTrue(object instanceof AttributeSensor, "attributeSensor="+object);
+        Assert.assertEquals(object, TestEntity.SEQUENCE);
+    }
+
+    @Test
+    public void testSensorOnArbitraryClass() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
+            "  brooklyn.config:",
+            "    test.confObject: $brooklyn:sensor(\""+EntitiesYamlTest.class.getName()+"$ArbitraryClassWithSensor\", \"mysensor\")"));
+        waitForApplicationTasks(app);
+
+        log.info("App started:");
+        Entities.dumpInfo(app);
+
+        TestEntity entity = (TestEntity) app.getChildren().iterator().next();
+        Object object = entity.getConfig(TestEntity.CONF_OBJECT);
+        Assert.assertEquals(object, ArbitraryClassWithSensor.MY_SENSOR);
+    }
+    public static class ArbitraryClassWithSensor {
+        public static final AttributeSensor<String> MY_SENSOR = Sensors.newStringSensor("mysensor");
+    }
+    
+    @Test
+    public void testComponent() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",
+            "  brooklyn.config:",
+            "    test.confName: first entity",
+            "  id: te1",
+            "- serviceType: brooklyn.test.entity.TestEntity",
+            "  name: second entity",
+            "  brooklyn.config:",
+            "    test.confObject: $brooklyn:component(\"te1\")"));
+        waitForApplicationTasks(app);
+        Entity firstEntity = null;
+        Entity secondEntity = null;
+        Assert.assertEquals(app.getChildren().size(), 2);
+        for (Entity entity : app.getChildren()) {
+            if (entity.getDisplayName().equals("testentity"))
+                firstEntity = entity;
+            else if (entity.getDisplayName().equals("second entity"))
+                secondEntity = entity;
+        }
+        final Entity[] entities = {firstEntity, secondEntity};
+        Assert.assertNotNull(entities[0], "Expected app to contain child named 'testentity'");
+        Assert.assertNotNull(entities[1], "Expected app to contain child named 'second entity'");
+        Object object = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Object>() {
+            public Object call() {
+                return entities[1].getConfig(TestEntity.CONF_OBJECT);
+            }}).get();
+        Assert.assertNotNull(object);
+        Assert.assertEquals(object, firstEntity, "Expected second entity's test.confObject to contain first entity");
+    }
+
+    @Test
+    public void testGrandchildEntities() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml", 
+            "  brooklyn.config:",
+            "    test.confName: first entity",
+            "  brooklyn.children:",
+            "  - serviceType: brooklyn.test.entity.TestEntity",
+            "    name: Child Entity",
+            "    brooklyn.config:",
+            "      test.confName: Name of the first Child",
+            "    brooklyn.children:",
+            "    - serviceType: brooklyn.test.entity.TestEntity",
+            "      name: Grandchild Entity",
+            "      brooklyn.config:",
+            "        test.confName: Name of the Grandchild",
+            "  - serviceType: brooklyn.test.entity.TestEntity",
+            "    name: Second Child",
+            "    brooklyn.config:",
+            "      test.confName: Name of the second Child"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity firstEntity = app.getChildren().iterator().next();
+        Assert.assertEquals(firstEntity.getConfig(TestEntity.CONF_NAME), "first entity");
+        Assert.assertEquals(firstEntity.getChildren().size(), 2);
+        Entity firstChild = null;
+        Entity secondChild = null;
+        for (Entity entity : firstEntity.getChildren()) {
+            if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the first Child"))
+                firstChild = entity;
+            if (entity.getConfig(TestEntity.CONF_NAME).equals("Name of the second Child"))
+                secondChild = entity;
+        }
+        Assert.assertNotNull(firstChild, "Expected a child of 'first entity' with the name 'Name of the first Child'");
+        Assert.assertNotNull(secondChild, "Expected a child of 'first entity' with the name 'Name of the second Child'");
+        Assert.assertEquals(firstChild.getChildren().size(), 1);
+        Entity grandchild = firstChild.getChildren().iterator().next();
+        Assert.assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "Name of the Grandchild");
+        Assert.assertEquals(secondChild.getChildren().size(), 0);
+    }
+
+    @Test
+    public void testWithInitConfig() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-with-init-config.yaml"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getDisplayName(), "test-entity-with-init-config");
+        TestEntityWithInitConfig testWithConfigInit = null;
+        TestEntity testEntity = null;
+        Assert.assertEquals(app.getChildren().size(), 2);
+        for (Entity entity : app.getChildren()) {
+            if (entity instanceof TestEntity)
+                testEntity = (TestEntity) entity;
+            if (entity instanceof TestEntityWithInitConfig)
+                testWithConfigInit = (TestEntityWithInitConfig) entity;
+        }
+        Assert.assertNotNull(testEntity, "Expected app to contain TestEntity child");
+        Assert.assertNotNull(testWithConfigInit, "Expected app to contain TestEntityWithInitConfig child");
+        Assert.assertEquals(testWithConfigInit.getEntityCachedOnInit(), testEntity);
+        log.info("App started:");
+        Entities.dumpInfo(app);
+    }
+
+    @Test
+    public void testMultipleReferencesJava() throws Exception {
+        final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
+        waitForApplicationTasks(app);
+        
+        Entity c1 = Tasks.resolving(new DslComponent("c1").newTask(), Entity.class).context( ((EntityInternal)app).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(c1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("child 1")).iterator().next());
+        
+        Entity e1 = Tasks.resolving(new DslComponent(Scope.PARENT, "xxx").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(e1, Entities.descendants(app, EntityPredicates.displayNameEqualTo("entity 1")).iterator().next());
+        
+        Entity c1a = Tasks.resolving(BrooklynDslCommon.descendant("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(c1a, c1);
+        Entity e1a = Tasks.resolving(BrooklynDslCommon.ancestor("e1").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(e1a, e1);
+        try {
+            Tasks.resolving(BrooklynDslCommon.ancestor("c1").newTask(), Entity.class).context( ((EntityInternal)e1).getExecutionContext() ).embedResolutionInTask(true).get();
+            Assert.fail("Should not have found c1 as ancestor of e1");
+        } catch (Exception e) { /* expected */ }
+    }
+    
+    @Test
+    public void testMultipleReferences() throws Exception {
+        final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
+        waitForApplicationTasks(app);
+        
+        Entities.dumpInfo(app);
+        
+        Assert.assertEquals(app.getDisplayName(), "test-referencing-entities");
+
+        Entity entity1 = null, entity2 = null, child1 = null, child2 = null, grandchild1 = null, grandchild2 = null;
+
+        Assert.assertEquals(app.getChildren().size(), 2);
+        for (Entity child : app.getChildren()) {
+            if (child.getDisplayName().equals("entity 1"))
+                entity1 = child;
+            if (child.getDisplayName().equals("entity 2"))
+                entity2 = child;
+        }
+        Assert.assertNotNull(entity1);
+        Assert.assertNotNull(entity2);
+
+        Assert.assertEquals(entity1.getChildren().size(), 2);
+        for (Entity child : entity1.getChildren()) {
+            if (child.getDisplayName().equals("child 1"))
+                child1 = child;
+            if (child.getDisplayName().equals("child 2"))
+                child2 = child;
+        }
+        Assert.assertNotNull(child1);
+        Assert.assertNotNull(child2);
+
+        Assert.assertEquals(child1.getChildren().size(), 2);
+        for (Entity child : child1.getChildren()) {
+            if (child.getDisplayName().equals("grandchild 1"))
+                grandchild1 = child;
+            if (child.getDisplayName().equals("grandchild 2"))
+                grandchild2 = child;
+        }
+        Assert.assertNotNull(grandchild1);
+        Assert.assertNotNull(grandchild2);
+
+        Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1_ALT, entity1)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY2, entity2)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD1, child1)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_CHILD2, child2)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD1, grandchild1)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_GRANDCHILD2, grandchild2)
+            .build();
+
+        Iterable<Entity> entitiesInApp = ((EntityInternal)app).getExecutionContext().submit(MutableMap.of(), new Callable<Iterable<Entity>>() {
+            @Override
+            public Iterable<Entity> call() throws Exception {
+                return ((EntityManagerInternal)((EntityInternal)app).getManagementContext().getEntityManager()).getAllEntitiesInApplication((Application)app);
+            }
+        }).get();
+
+        for (Entity entityInApp : entitiesInApp) {
+            checkReferences(entityInApp, keyToEntity);
+            try {
+                getResolvedConfigInTask(entityInApp, ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS);
+                Assert.fail("Should not have resolved "+ReferencingYamlTestEntity.TEST_REFERENCE_BOGUS+" at "+entityInApp);
+            } catch (Exception e) {
+                /* expected */
+            }
+        }
+    }
+
+    private void checkReferences(final Entity entity, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
+        for (final ConfigKey<Entity> key : keyToEntity.keySet()) {
+            try {
+                Assert.assertEquals(getResolvedConfigInTask(entity, key).get(), keyToEntity.get(key));
+            } catch (Throwable t) {
+                Exceptions.propagateIfFatal(t);
+                Assert.fail("Wrong value for "+entity+":"+key+", "+((EntityInternal)entity).config().getLocalRaw(key)+": "+t, t);
+            }
+        }
+    }
+
+    private Maybe<Entity> getResolvedConfigInTask(final Entity entity, final ConfigKey<Entity> key) {
+        return Tasks.resolving(Tasks.<Entity>builder().body(
+            Functionals.callable(Suppliers.compose(EntityFunctions.config(key), Suppliers.ofInstance(entity))) ).build())
+            .as(Entity.class)
+            .context( ((EntityInternal)entity).getExecutionContext() ).embedResolutionInTask(true)
+            .getMaybe();
+    }
+
+    public void testWithAppLocation() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
+            "location: localhost:(name=yaml name)"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getLocations().size(), 1);
+        Location location = app.getLocations().iterator().next();
+        Assert.assertNotNull(location);
+        Assert.assertEquals(location.getDisplayName(), "yaml name");
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(entity.getLocations().size(), 1);
+    }
+
+    @Test
+    public void testWithEntityLocation() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
+            "  location: localhost:(name=yaml name)\n"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getLocations().size(), 0);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertEquals(entity.getLocations().size(), 1);
+        Location location = entity.getLocations().iterator().next();
+        Assert.assertNotNull(location);
+        Assert.assertEquals(location.getDisplayName(), "yaml name");
+        Assert.assertNotNull(entity);
+    }
+
+    @Test
+    public void testWith2AppLocations() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
+            "locations:",
+            "- localhost:(name=localhost name)",
+            "- byon:(hosts=\"1.1.1.1\", name=byon name)"));
+        waitForApplicationTasks(app);
+
+        Assert.assertEquals(app.getLocations().size(), 2);
+        Location localhostLocation = null, byonLocation = null; 
+        for (Location location : app.getLocations()) {
+            if (location.getDisplayName().equals("localhost name"))
+                localhostLocation = location;
+            else if (location.getDisplayName().equals("byon name"))
+                byonLocation = location;
+        }
+        Assert.assertNotNull(localhostLocation);
+        Assert.assertNotNull(byonLocation);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(entity.getLocations().size(), 2);
+    }
+
+    @Test
+    public void testWith2EntityLocations() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
+            "  locations:",
+            "  - localhost:(name=localhost name)",
+            "  - byon:(hosts=\"1.1.1.1\", name=byon name)"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getLocations().size(), 0);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        Assert.assertEquals(entity.getLocations().size(), 2);
+        Location localhostLocation = null, byonLocation = null; 
+        for (Location location : entity.getLocations()) {
+            if (location.getDisplayName().equals("localhost name"))
+                localhostLocation = location;
+            else if (location.getDisplayName().equals("byon name"))
+                byonLocation = location;
+        }
+        Assert.assertNotNull(localhostLocation);
+        Assert.assertNotNull(byonLocation);
+    }
+
+    @Test
+    public void testWithAppAndEntityLocations() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-entity-basic-template.yaml",  
+            "  location: localhost:(name=localhost name)",
+            "location: byon:(hosts=\"1.1.1.1\", name=byon name)"));
+        waitForApplicationTasks(app);
+        Assert.assertEquals(app.getLocations().size(), 1);
+        Assert.assertEquals(app.getChildren().size(), 1);
+        Entity entity = app.getChildren().iterator().next();
+        
+        Assert.assertEquals(entity.getLocations().size(), 2);
+        Iterator<Location> entityLocationIterator = entity.getLocations().iterator();
+        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "localhost name");
+        Assert.assertEquals(entityLocationIterator.next().getDisplayName(), "byon name");
+        
+        Location appLocation = app.getLocations().iterator().next();
+        Assert.assertEquals(appLocation.getDisplayName(), "byon name");
+    }
+
+    @Test
+    public void testCreateClusterWithMemberSpec() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("test-cluster-with-member-spec.yaml"));
+        waitForApplicationTasks(app);
+        assertEquals(app.getChildren().size(), 1);
+
+        Entity clusterEntity = Iterables.getOnlyElement(app.getChildren());
+        assertTrue(clusterEntity instanceof DynamicCluster, "cluster="+clusterEntity);
+
+        DynamicCluster cluster = DynamicCluster.class.cast(clusterEntity);
+        assertEquals(cluster.getMembers().size(), 2, "members="+cluster.getMembers());
+
+        for (Entity member : cluster.getMembers()) {
+            assertTrue(member instanceof TestEntity, "member="+member);
+            assertEquals(member.getConfig(TestEntity.CONF_NAME), "yamlTest");
+        }
+    }
+
+    @Test
+    public void testEntitySpecConfig() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  brooklyn.config:\n"+
+                "   test.childSpec:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       brooklyn.config:\n"+
+                "         test.confName: inchildspec\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
+        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
+    }
+
+    @Test
+    public void testEntitySpecFlags() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  confName: inParent\n"+
+                "  brooklyn.config:\n"+
+                "   test.childSpec:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       confName: inchildspec\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
+        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
+    }
+
+    @Test
+    public void testEntitySpecExplicitFlags() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  brooklyn.flags:\n"+
+                "    confName: inParent\n"+
+                "  brooklyn.config:\n"+
+                "   test.childSpec:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       brooklyn.flags:\n"+
+                "         confName: inchildspec\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
+        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
+    }
+
+    @Test
+    public void testEntitySpecWithChildren() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  brooklyn.config:\n"+
+                "   test.childSpec:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       brooklyn.config:\n"+
+                "         test.confName: child\n"+
+                "       brooklyn.children:\n"+
+                "       - type: brooklyn.test.entity.TestEntity\n" +
+                "         brooklyn.config:\n" +
+                "           test.confName: grandchild\n" +
+                "         brooklyn.children:\n"+
+                "         - type: brooklyn.test.entity.TestEntity\n" +
+                "           brooklyn.config:\n" +
+                "             test.confName: greatgrandchild\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
+        assertEquals(child.getConfig(TestEntity.CONF_NAME), "child");
+        assertEquals(child.getChildren().size(), 1, "Child entity should have exactly one child of its own");
+
+        TestEntity grandchild = (TestEntity) Iterables.getOnlyElement(child.getChildren());
+        assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "grandchild");
+        assertEquals(grandchild.getChildren().size(), 1, "Grandchild entity should have exactly one child of its own");
+
+        TestEntity greatgrandchild = (TestEntity) Iterables.getOnlyElement(grandchild.getChildren());
+        assertEquals(greatgrandchild.getConfig(TestEntity.CONF_NAME), "greatgrandchild");
+    }
+    
+    @Test
+    public void testNestedEntitySpecConfigs() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  brooklyn.config:\n"+
+                "   test.childSpec:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       brooklyn.config:\n"+
+                "         test.confName: inchildspec\n"+
+                "         test.childSpec:\n"+
+                "           $brooklyn:entitySpec:\n"+
+                "             type: brooklyn.test.entity.TestEntity\n"+
+                "             brooklyn.config:\n"+
+                "               test.confName: ingrandchildspec\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        TestEntity child = (TestEntity) entity.createAndManageChildFromConfig();
+        assertEquals(child.getConfig(TestEntity.CONF_NAME), "inchildspec");
+        
+        TestEntity grandchild = (TestEntity) child.createAndManageChildFromConfig();
+        assertEquals(grandchild.getConfig(TestEntity.CONF_NAME), "ingrandchildspec");
+    }
+    
+    @Test
+    public void testEntitySpecInUnmatchedConfig() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntity\n"+
+                "  brooklyn.config:\n"+
+                "   key.does.not.match:\n"+
+                "     $brooklyn:entitySpec:\n"+
+                "       type: brooklyn.test.entity.TestEntity\n"+
+                "       brooklyn.config:\n"+
+                "         test.confName: inchildspec\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        EntitySpec<?> entitySpec = (EntitySpec<?>) entity.config().getBag().getStringKey("key.does.not.match");
+        assertEquals(entitySpec.getType(), TestEntity.class);
+        assertEquals(entitySpec.getConfig(), ImmutableMap.of(TestEntity.CONF_NAME, "inchildspec"));
+    }
+
+    @Test
+    public void testAppWithSameServerEntityStarts() throws Exception {
+        Entity app = createAndStartApplication(loadYaml("same-server-entity-test.yaml"));
+        waitForApplicationTasks(app);
+        assertNotNull(app);
+        assertEquals(app.getAttribute(Attributes.SERVICE_STATE_ACTUAL), Lifecycle.RUNNING, "service state");
+        assertTrue(app.getAttribute(Attributes.SERVICE_UP), "service up");
+
+        assertEquals(app.getChildren().size(), 1);
+        Entity entity = Iterables.getOnlyElement(app.getChildren());
+        assertTrue(entity instanceof SameServerEntity, "entity="+entity);
+
+        SameServerEntity sse = (SameServerEntity) entity;
+        assertEquals(sse.getChildren().size(), 2);
+        for (Entity child : sse.getChildren()) {
+            assertTrue(child instanceof BasicEntity, "child="+child);
+        }
+    }
+    
+    @Test
+    public void testEntityImplExposesAllInterfacesIncludingStartable() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- serviceType: brooklyn.test.entity.TestEntityImpl\n";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        assertTrue(entity.getCallHistory().contains("start"), "history="+entity.getCallHistory());
+    }
+
+    @Test
+    public void testEntityWithInitializer() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- type: "+TestEntity.class.getName()+"\n"+
+                "  brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.class.getName()+" } ]";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        Effector<?> hi = entity.getEffector(TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO);
+        Assert.assertNotNull(hi);
+        
+        Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED) );
+        Assert.assertNotNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED) );
+        Assert.assertNull( entity.getEntityType().getSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO) );
+        
+        Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)) );
+        Assert.assertNull( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED)) );
+        Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_HELLO_DEFINED_EMITTED)),
+            "1");
+        
+        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
+            MutableMap.of("name", "Bob"));
+        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
+        Assert.assertEquals( entity.getAttribute(Sensors.newStringSensor(TestSensorAndEffectorInitializer.SENSOR_LAST_HELLO)),
+            "Bob");
+    }
+
+    @Test
+    public void testEntityWithConfigurableInitializerEmpty() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- type: "+TestEntity.class.getName()+"\n"+
+                "  brooklyn.initializers: [ { type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+" } ]";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
+            MutableMap.of("name", "Bob"));
+        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hello Bob");
+    }
+
+    @Test
+    public void testEntityWithConfigurableInitializerNonEmpty() throws Exception {
+        String yaml =
+                "services:\n"+
+                "- type: "+TestEntity.class.getName()+"\n"+
+                "  brooklyn.initializers: [ { "
+                  + "type: "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.class.getName()+","
+                  + "brooklyn.config: { "+TestSensorAndEffectorInitializer.TestConfigurableInitializer.HELLO_WORD+": Hey }"
+                  + " } ]";
+        
+        Application app = (Application) createStartWaitAndLogApplication(new StringReader(yaml));
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        
+        Task<String> saying = entity.invoke(Effectors.effector(String.class, TestSensorAndEffectorInitializer.EFFECTOR_SAY_HELLO).buildAbstract(), 
+            MutableMap.of("name", "Bob"));
+        Assert.assertEquals(saying.get(Duration.TEN_SECONDS), "Hey Bob");
+    }
+
+    @Test
+    public void testEntityTypeAsImpl() throws Exception {
+        String yaml =
+                "services:"+"\n"+
+                "- type: "+CustomTestEntityImpl.class.getName()+"\n";
+
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+
+        Entity testEntity = Iterables.getOnlyElement(app.getChildren());
+        assertEquals(testEntity.getEntityType().getName(), "CustomTestEntityImpl");
+    }
+    
+    public static class CustomTestEntityImpl extends TestEntityImpl {
+        public CustomTestEntityImpl() {
+            System.out.println("in CustomTestEntityImpl");
+        }
+        @Override
+        protected String getEntityTypeName() {
+            return "CustomTestEntityImpl";
+        }
+    }
+
+    @Test
+    public void testWrapperAppMarkerExists() throws Exception {
+        Entity entity = createAndStartApplication(
+                "services:",
+                "- type: " + BasicEntity.class.getName());
+        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+    }
+
+    @Test
+    public void testWrapperAppMarkerDoesntExist() throws Exception {
+        Entity entity = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+    }
+
+    @Test
+    public void testWrapperAppMarkerForced() throws Exception {
+        Entity entity = createAndStartApplication(
+                "wrappedApp: true",
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+    }
+
+    @Test
+    public void testWrapperAppMarkerUnforced() throws Exception {
+        Entity entity = createAndStartApplication(
+                "wrappedApp: false",
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
new file mode 100644
index 0000000..a83dba2
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppWithDslYamlRebindIntegrationTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+
+import java.io.File;
+import java.io.Reader;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Application;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.io.Files;
+
+@Test
+public class JavaWebAppWithDslYamlRebindIntegrationTest extends AbstractYamlTest {
+    
+    private static final Logger log = LoggerFactory.getLogger(JavaWebAppWithDslYamlRebindIntegrationTest.class);
+    
+    protected ClassLoader classLoader = getClass().getClassLoader();
+    protected File mementoDir;
+    protected Set<ManagementContext> mgmtContexts = MutableSet.of();
+
+    @Override
+    protected LocalManagementContext newTestManagementContext() {
+        if (mementoDir!=null) throw new IllegalStateException("already created mgmt context");
+        mementoDir = Files.createTempDir();
+        log.info("Test "+getClass()+" persisting to "+mementoDir);
+
+        LocalManagementContext mgmt =
+            RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
+        mgmtContexts.add(mgmt);
+        return mgmt;
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    @Override
+    public void tearDown() {
+        for (ManagementContext mgmt: mgmtContexts) Entities.destroyAll(mgmt);
+        super.tearDown();
+        mementoDir = null;
+        mgmtContexts.clear();
+    }
+
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+    public Application rebind(Application app) throws Exception {
+        RebindTestUtils.waitForPersisted(app);
+        // optionally for good measure can also check this:
+//        RebindTestUtils.checkCurrentMementoSerializable(app);
+        Application result = RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+        mgmtContexts.add(result.getManagementContext());
+        return result;
+    }
+
+    /** as {@link JavaWebAppsIntegrationTest#testWithDbDeploy()} but with rebind */
+    @Test(groups="Integration")
+    public void testJavaWebAppDeployAndRebind() throws Exception {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+        final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());
+
+        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
+        for (Task<?> t: tasks) t.blockUntilEnded();
+        Entities.dumpInfo(app);
+
+        Application app2 = rebind(app);
+        Assert.assertEquals(app2.getChildren().size(), 2);
+    }
+
+    // test for https://github.com/brooklyncentral/brooklyn/issues/1422
+    @Test(groups="Integration")
+    public void testJavaWebWithMemberSpecRebind() throws Exception {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("test-java-web-app-spec-and-db-with-function.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+        Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+        final Application app = (Application) mgmt().getEntityManager().getEntity(assembly.getId());
+
+        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
+        for (Task<?> t: tasks) t.blockUntilEnded();
+        Entities.dumpInfo(app);
+        
+        Application app2 = rebind(app);
+        Assert.assertEquals(app2.getChildren().size(), 2);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
new file mode 100644
index 0000000..007c830
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsIntegrationTest.java
@@ -0,0 +1,275 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.PlatformComponent;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+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 brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.Task;
+import brooklyn.policy.Policy;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.test.Asserts;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.net.Urls;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.time.Duration;
+
+import com.google.common.collect.Iterables;
+
+@Test(groups="Integration")
+public class JavaWebAppsIntegrationTest {
+
+    private static final Logger log = LoggerFactory.getLogger(JavaWebAppsIntegrationTest.class);
+    
+    private ManagementContext brooklynMgmt;
+    private BrooklynCampPlatform platform;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() {
+        BrooklynCampPlatformLauncherNoServer launcher = new BrooklynCampPlatformLauncherNoServer();
+        launcher.launch();
+        brooklynMgmt = launcher.getBrooklynMgmt();
+      
+        platform = new BrooklynCampPlatform(
+              PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
+              brooklynMgmt);
+    }
+    
+    @AfterMethod
+    public void teardown() {
+        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
+    }
+    
+    public void testSimpleYamlDeploy() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+        try {
+            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+            log.info("Test - created "+assembly);
+            
+            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+            log.info("App - "+app);
+            Assert.assertEquals(app.getDisplayName(), "sample-single-jboss");
+                        
+            // locations set on AT in this yaml
+            Assert.assertEquals(app.getLocations().size(), 1);
+
+            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
+            log.info("Waiting on "+tasks.size()+" task(s)");
+            for (Task<?> t: tasks) {
+                t.blockUntilEnded();
+            }
+
+            log.info("App started:");
+            Entities.dumpInfo(app);
+
+            Assert.assertEquals(app.getChildren().size(), 1);
+            Assert.assertEquals(app.getChildren().iterator().next().getDisplayName(), "tomcat1");
+            Assert.assertEquals(app.getChildren().iterator().next().getLocations().size(), 1);
+            
+            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                @Override public String call() throws Exception {
+                    String url = app.getChildren().iterator().next().getAttribute(JavaWebAppService.ROOT_URL);
+                    return checkNotNull(url, "url of %s", app);
+                }});
+        
+            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                    @Override public String call() throws Exception {
+                        return new ResourceUtils(this).getResourceAsString(url);
+                    }});
+            
+            log.info("App URL for "+app+": "+url);
+            Assert.assertTrue(url.contains("928"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
+            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
+            Assert.assertTrue(!platform.assemblies().isEmpty());
+        } catch (Exception e) {
+            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    public void testWithDbDeploy() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+        try {
+            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+            log.info("Test - created "+assembly);
+            
+            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+            log.info("App - "+app);
+            
+            // locations set on individual services here
+            Assert.assertEquals(app.getLocations().size(), 0);
+            
+            Iterator<ResolvableLink<PlatformComponent>> pcs = assembly.getPlatformComponents().links().iterator();
+            PlatformComponent pc1 = pcs.next().resolve();
+            Entity cluster = brooklynMgmt.getEntityManager().getEntity(pc1.getId());
+            log.info("pc1 - "+pc1+" - "+cluster);
+            
+            PlatformComponent pc2 = pcs.next().resolve();
+            log.info("pc2 - "+pc2);
+            
+            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
+            log.info("Waiting on "+tasks.size()+" task(s)");
+            AtomicInteger i = new AtomicInteger(0);
+            for (Task<?> t: tasks) {
+                t.blockUntilEnded();
+                log.info("Completed task #" + i.incrementAndGet());
+            }
+
+            log.info("App started:");
+            Entities.dumpInfo(app);
+
+            EntityTestUtils.assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+            Assert.assertEquals(app.getAttribute(Attributes.SERVICE_UP), Boolean.TRUE);
+            
+            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                    @Override public String call() throws Exception {
+                        Entity cluster = Iterables.getOnlyElement( Iterables.filter(app.getChildren(), WebAppService.class) );
+                        String url = cluster.getAttribute(JavaWebAppService.ROOT_URL);
+                        return checkNotNull(url, "url of %s", cluster);
+                    }});
+            
+            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                    @Override public String call() throws Exception {
+                        return new ResourceUtils(this).getResourceAsString(url);
+                    }});
+            
+            log.info("App URL for "+app+": "+url);
+            Assert.assertTrue(url.contains("921"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
+            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
+            Assert.assertTrue(!platform.assemblies().isEmpty());
+            
+            String dbPage = new ResourceUtils(this).getResourceAsString(Urls.mergePaths(url, "db.jsp"));
+            Assert.assertTrue(dbPage.contains("Isaac Asimov"), "db.jsp does not mention Isaac Asimov, probably the DB did not get initialised:\n"+dbPage);
+        } catch (Exception e) {
+            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    public void testWithPolicyDeploy() {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-policy.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+
+        try {
+            Assembly assembly = at.getInstantiator().newInstance().instantiate(at, platform);
+            log.info("Test - created "+assembly);
+            
+            final Entity app = brooklynMgmt.getEntityManager().getEntity(assembly.getId());
+            log.info("App - "+app);
+            
+            // locations set on individual services here
+            Assert.assertEquals(app.getLocations().size(), 0);
+            
+            Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(brooklynMgmt.getExecutionManager(), app);
+            log.info("Waiting on "+tasks.size()+" task(s)");
+            for (Task<?> t: tasks) {
+                t.blockUntilEnded();
+            }
+            
+            log.info("App started:");
+            Entities.dumpInfo(app);
+            
+            Iterator<ResolvableLink<PlatformComponent>> pcs = assembly.getPlatformComponents().links().iterator();
+            PlatformComponent clusterComponent = null;
+            while (pcs.hasNext() && clusterComponent == null) {
+                PlatformComponent component = pcs.next().resolve();
+                if (component.getName().equals("My Web with Policy"))
+                    clusterComponent = component;
+            }
+            Assert.assertNotNull(clusterComponent, "Database PlatformComponent not found");
+            Entity cluster = brooklynMgmt.getEntityManager().getEntity(clusterComponent.getId());
+            log.info("pc1 - "+clusterComponent+" - "+cluster);
+            
+            Assert.assertEquals(cluster.getPolicies().size(), 1);
+            Policy policy = cluster.getPolicies().iterator().next();
+            Assert.assertNotNull(policy);
+            Assert.assertTrue(policy instanceof AutoScalerPolicy, "policy="+policy);
+            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.MAX_POOL_SIZE), (Integer)5);
+            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.MIN_POOL_SIZE), (Integer)1);
+            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC), DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE);
+            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC_LOWER_BOUND), (Integer)10);
+            Assert.assertEquals(policy.getConfig(AutoScalerPolicy.METRIC_UPPER_BOUND), (Integer)100);
+            Assert.assertTrue(policy.isRunning());
+
+            EntityTestUtils.assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+            Assert.assertEquals(app.getAttribute(Attributes.SERVICE_UP), Boolean.TRUE);
+            
+            final String url = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                    @Override public String call() throws Exception {
+                        Entity cluster = Iterables.getOnlyElement( Iterables.filter(app.getChildren(), WebAppService.class) );
+                        String url = cluster.getAttribute(JavaWebAppService.ROOT_URL);
+                        return checkNotNull(url, "url of %s", cluster);
+                    }});
+            
+            String site = Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Callable<String>() {
+                    @Override public String call() throws Exception {
+                        return new ResourceUtils(this).getResourceAsString(url);
+                    }});
+            
+            log.info("App URL for "+app+": "+url);
+            Assert.assertTrue(url.contains("921"), "URL should be on port 9280+ based on config set in yaml, url "+url+", app "+app);
+            Assert.assertTrue(site.toLowerCase().contains("hello"), site);
+            Assert.assertTrue(!platform.assemblies().isEmpty());
+            
+            String dbPage = new ResourceUtils(this).getResourceAsString(Urls.mergePaths(url, "db.jsp"));
+            Assert.assertTrue(dbPage.contains("Isaac Asimov"), "db.jsp does not mention Isaac Asimov, probably the DB did not get initialised:\n"+dbPage);
+        } catch (Exception e) {
+            log.warn("Unable to instantiate "+at+" (rethrowing): "+e);
+            throw Exceptions.propagate(e);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
new file mode 100644
index 0000000..048b8f8
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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;
+
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+import io.brooklyn.camp.spi.pdp.DeploymentPlan;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+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 brooklyn.entity.basic.Entities;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.task.DeferredSupplier;
+
+@Test
+public class JavaWebAppsMatchingTest {
+
+    private static final Logger log = LoggerFactory.getLogger(JavaWebAppsMatchingTest.class);
+    
+    private ManagementContext brooklynMgmt;
+    private BrooklynCampPlatform platform;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() {
+        brooklynMgmt = new LocalManagementContextForTests();
+        platform = new BrooklynCampPlatform(
+              PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
+              brooklynMgmt);
+    }
+    
+    // FIXME all commented-out lines require camp server
+    
+    @AfterMethod(alwaysRun=true)
+    public void teardown() {
+        if (brooklynMgmt!=null) Entities.destroyAll(brooklynMgmt);
+    }
+    
+    public void testSimpleYamlParse() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
+        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
+        log.info("DP is:\n"+plan.toString());
+        Assert.assertEquals(plan.getServices().size(), 1);
+        Assert.assertEquals(plan.getName(), "sample-single-jboss");
+    }
+    
+    public void testSimpleYamlMatch() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-simple.yaml"));
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
+        
+        Assert.assertEquals(at.getName(), "sample-single-jboss");
+    }
+
+    public void testExampleFunctionsYamlMatch() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("example-with-function.yaml"));
+        
+        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
+        log.info("DP is:\n"+plan.toString());
+        Map<?,?> cfg1 = (Map<?, ?>) plan.getServices().get(0).getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
+        Map<?,?> cfg = MutableMap.copyOf(cfg1);
+        
+        Assert.assertEquals(cfg.remove("literalValue1"), "$brooklyn: is a fun place");
+        Assert.assertEquals(cfg.remove("literalValue2"), "$brooklyn: is a fun place");
+        Assert.assertEquals(cfg.remove("literalValue3"), "$brooklyn: is a fun place");
+        Assert.assertEquals(cfg.remove("literalValue4"), "$brooklyn: is a fun place");
+        Assert.assertEquals(cfg.remove("$brooklyn:1"), "key to the city");
+        Assert.assertTrue(cfg.isEmpty(), ""+cfg);
+
+        Assert.assertEquals(plan.getName(), "example-with-function");
+        Assert.assertEquals(plan.getCustomAttributes().get("location"), "localhost");
+        
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(plan);
+        
+        Assert.assertEquals(at.getName(), "example-with-function");
+        Assert.assertEquals(at.getCustomAttributes().get("location"), "localhost");
+        
+        PlatformComponentTemplate pct = at.getPlatformComponentTemplates().links().iterator().next().resolve();
+        Object cfg2 = pct.getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
+        Assert.assertEquals(cfg2, cfg1);
+    }
+
+    public void testJavaAndDbWithFunctionYamlMatch() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function.yaml"));
+        assertWebDbWithFunctionValid(input);
+    }
+    
+    public void testJavaAndDbWithFunctionYamlMatch2() throws IOException {
+        Reader input = Streams.reader(new ResourceUtils(this).getResourceFromUrl("java-web-app-and-db-with-function-2.yaml"));
+        assertWebDbWithFunctionValid(input);
+    }
+    
+    protected void assertWebDbWithFunctionValid(Reader input) { 
+        DeploymentPlan plan = platform.pdp().parseDeploymentPlan(input);
+        log.info("DP is:\n"+plan.toString());
+        
+        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(plan);
+        
+        Assert.assertEquals(at.getName(), "java-cluster-db-example");
+
+        Iterator<ResolvableLink<PlatformComponentTemplate>> pcti = at.getPlatformComponentTemplates().links().iterator();
+        PlatformComponentTemplate pct1 = pcti.next().resolve(); 
+
+        PlatformComponentTemplate pct2 = pcti.next().resolve(); 
+
+        Map<?,?> config = (Map<?, ?>) pct1.getCustomAttributes().get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
+        Map<?,?> javaSysProps = (Map<?, ?>) config.get("java.sysprops");
+        Object dbUrl = javaSysProps.get("brooklyn.example.db.url");
+        Assert.assertTrue(dbUrl instanceof DeferredSupplier<?>, "url is: "+dbUrl);
+        
+        Assert.assertEquals(pct2.getCustomAttributes().get("planId"), "db");
+    }
+
+}



[02/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage-cli

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
new file mode 100644
index 0000000..2ddad9d
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
@@ -0,0 +1,153 @@
+/*
+ * 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.cli.lister;
+
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.reflections.Reflections;
+import org.reflections.scanners.FieldAnnotationsScanner;
+import org.reflections.scanners.SubTypesScanner;
+import org.reflections.scanners.TypeAnnotationsScanner;
+import org.reflections.util.ConfigurationBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.basic.BrooklynObject;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.SoftwareProcessImpl;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.Policy;
+import brooklyn.policy.basic.AbstractPolicy;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.javalang.UrlClassLoader;
+import brooklyn.util.net.Urls;
+import brooklyn.util.os.Os;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class ClassFinder {
+
+    private static final Logger log = LoggerFactory.getLogger(ClassFinder.class);
+
+    private static final Collection<Class<?>> BORING = ImmutableList.<Class<?>>of(
+            Entity.class,
+            AbstractEntity.class,
+            SoftwareProcessImpl.class,
+            Application.class,
+            AbstractApplication.class,
+            Policy.class,
+            Enricher.class,
+            AbstractPolicy.class,
+            AbstractEnricher.class);
+
+    public static Predicate<Class<?>> notBoring() {
+        return new Predicate<Class<?>>() {
+            public boolean apply(Class<?> input) {
+                return (input != null && !BORING.contains(input));
+            }
+        };
+    }
+    
+    public static Predicate<Class<?>> withAnnotation(final Class<? extends Annotation> annotation) {
+        return new Predicate<Class<?>>() {
+            public boolean apply(Class<?> input) {
+                return (input != null && input.getAnnotation(annotation) != null);
+            }
+        };
+    }
+    
+    public static Predicate<? super Class<? extends BrooklynObject>> withClassNameMatching(final String typeRegex) {
+        return new Predicate<Class<?>>() {
+            public boolean apply(Class<?> input) {
+                return (input != null && input.getName() != null && input.getName().matches(typeRegex));
+            }
+        };
+    }
+
+    /** finds a jar at a url, or for directories, jars under a path */
+    @Beta
+    public static List<URL> toJarUrls(String url) throws MalformedURLException {
+        if (url==null) throw new NullPointerException("Cannot read from null");
+        if (url=="") throw new NullPointerException("Cannot read from empty string");
+        
+        List<URL> result = Lists.newArrayList();
+        
+        String protocol = Urls.getProtocol(url);
+        if (protocol!=null) {
+            // it's a URL - easy
+            if ("file".equals(protocol)) {
+                url = ResourceUtils.tidyFileUrl(url);
+            }
+            result.add(new URL(url));
+        } else {
+            // treat as file
+            String tidiedPath = Os.tidyPath(url);
+            File tidiedFile = new File(tidiedPath);
+            if (tidiedFile.isDirectory()) {
+                List<File> toscan = Lists.newLinkedList();
+                toscan.add(tidiedFile);
+                while (toscan.size() > 0) {
+                    File file = toscan.remove(0);
+                    if (file.isFile()) {
+                        if (file.getName().toLowerCase().endsWith(".jar")) {
+                            result.add(new URL("file://"+file.getAbsolutePath()));
+                        }
+                    } else if (file.isDirectory()) {
+                        for (File subfile : file.listFiles()) {
+                            toscan.add(subfile);
+                        }
+                    } else {
+                        log.info("Cannot read "+file+"; not a file or directory");
+                    }
+                }
+            } else {
+                result.add(tidiedFile.toURI().toURL());
+            }
+        }
+        
+        return result;
+    }
+
+    public static <T extends BrooklynObject> Set<Class<? extends T>> findClasses(Collection<URL> urls, Class<T> clazz) {
+        ClassLoader classLoader = new UrlClassLoader(urls.toArray(new URL[urls.size()]));
+        
+        Reflections reflections = new ConfigurationBuilder()
+                .addClassLoader(classLoader)
+                .addScanners(new SubTypesScanner(), new TypeAnnotationsScanner(), new FieldAnnotationsScanner())
+                .addUrls(urls)
+                .build();
+        
+        Set<Class<? extends T>> types = reflections.getSubTypesOf(clazz);
+        
+        return types;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
new file mode 100644
index 0000000..3912dd9
--- /dev/null
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
@@ -0,0 +1,173 @@
+/*
+ * 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.cli.lister;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.basic.BrooklynDynamicType;
+import brooklyn.basic.BrooklynObject;
+import brooklyn.basic.BrooklynType;
+import brooklyn.basic.BrooklynTypes;
+import org.apache.brooklyn.catalog.Catalog;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Effector;
+import brooklyn.entity.EntityType;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.event.Sensor;
+import brooklyn.location.LocationResolver;
+import brooklyn.rest.domain.EffectorSummary;
+import brooklyn.rest.domain.EntityConfigSummary;
+import brooklyn.rest.domain.SensorSummary;
+import brooklyn.rest.domain.SummaryComparators;
+import brooklyn.rest.transform.EffectorTransformer;
+import brooklyn.rest.transform.EntityTransformer;
+import brooklyn.rest.transform.SensorTransformer;
+import brooklyn.util.exceptions.RuntimeInterruptedException;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class ItemDescriptors {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ItemDescriptors.class);
+    
+    public static List<Map<String, Object>> toItemDescriptors(Iterable<? extends Class<? extends BrooklynObject>> types, boolean headingsOnly) {
+        return toItemDescriptors(types, headingsOnly, null);
+    }
+    
+    public static List<Map<String, Object>> toItemDescriptors(Iterable<? extends Class<? extends BrooklynObject>> types, boolean headingsOnly, final String sortField) {
+        List<Map<String, Object>> itemDescriptors = Lists.newArrayList();
+        
+        for (Class<? extends BrooklynObject> type : types) {
+            try {
+                Map<String, Object> itemDescriptor = toItemDescriptor(type, headingsOnly);
+                itemDescriptors.add(itemDescriptor);
+            } catch (Throwable throwable) {
+                if (throwable instanceof InterruptedException)
+                    throw new RuntimeInterruptedException((InterruptedException) throwable);
+                if (throwable instanceof RuntimeInterruptedException)
+                    throw (RuntimeInterruptedException) throwable;
+
+                LOG.warn("Could not load "+type+": "+throwable);
+            }
+        }
+        
+        if (!Strings.isNullOrEmpty(sortField)) {
+            Collections.sort(itemDescriptors, new Comparator<Map<String, Object>>() {
+                @Override public int compare(Map<String, Object> id1, Map<String, Object> id2) {
+                    Object o1 = id1.get(sortField);
+                    Object o2 = id2.get(sortField);
+                    if (o1 == null) {
+                        return o2 == null ? 0 : 1;
+                    }
+                    if (o2 == null) {
+                        return -1;
+                    }
+                    return o1.toString().compareTo(o2.toString());
+                }
+            });
+        }
+        
+        return itemDescriptors;
+    }
+    
+    public static Map<String,Object> toItemDescriptor(Class<? extends BrooklynObject> clazz, boolean headingsOnly) {
+        BrooklynDynamicType<?, ?> dynamicType = BrooklynTypes.getDefinedBrooklynType(clazz);
+        BrooklynType type = dynamicType.getSnapshot();
+        ConfigKey<?> version = dynamicType.getConfigKey(BrooklynConfigKeys.SUGGESTED_VERSION.getName());
+        
+        Map<String,Object> result = Maps.newLinkedHashMap();
+        
+        result.put("type", clazz.getName());
+        if (version != null) {
+            result.put("defaultVersion", version.getDefaultValue());
+        }
+        
+        Catalog catalogAnnotation = clazz.getAnnotation(Catalog.class);
+        if (catalogAnnotation != null) {
+            result.put("name", catalogAnnotation.name());
+            result.put("description", catalogAnnotation.description());
+            result.put("iconUrl", catalogAnnotation.iconUrl());
+        }
+        
+        Deprecated deprecatedAnnotation = clazz.getAnnotation(Deprecated.class);
+        if (deprecatedAnnotation != null) {
+            result.put("deprecated", true);
+        }
+        
+        if (!headingsOnly) {
+            Set<EntityConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
+            Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
+            Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());
+
+            for (ConfigKey<?> x: type.getConfigKeys()) {
+                config.add(EntityTransformer.entityConfigSummary(x, dynamicType.getConfigKeyField(x.getName())));
+            }
+            result.put("config", config);
+            
+            if (type instanceof EntityType) {
+                for (Sensor<?> x: ((EntityType)type).getSensors())
+                    sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
+                result.put("sensors", sensors);
+                
+                for (Effector<?> x: ((EntityType)type).getEffectors())
+                    effectors.add(EffectorTransformer.effectorSummaryForCatalog(x));
+                result.put("effectors", effectors);
+            }
+        }
+        
+        return result;
+    }
+    
+    public static Object toItemDescriptors(List<LocationResolver> resolvers) {
+        return toItemDescriptors(resolvers, false);
+    }
+    
+    public static Object toItemDescriptors(List<LocationResolver> resolvers, Boolean sort) {
+        List<Object> result = Lists.newArrayList();
+        for (LocationResolver resolver : resolvers) {
+            result.add(toItemDescriptor(resolver));
+        }
+        if (sort) {
+            Collections.sort(result, new Comparator<Object>() {
+                @Override public int compare(Object o1, Object o2) {
+                    String s1 = o1 == null ? "" : o1.toString();
+                    String s2 = o2 == null ? "" : o2.toString();
+                    return s1.compareTo(s2);
+                }
+            });
+        }
+        return result;
+    }
+
+    public static Object toItemDescriptor(LocationResolver resolver) {
+        // TODO Get javadoc of LocationResolver? Could use docklet? But that would give dependency here
+        // on com.sun.javadoc.*
+        return resolver.getPrefix();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/java/brooklyn/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/brooklyn/cli/CliTest.java b/usage/cli/src/test/java/brooklyn/cli/CliTest.java
deleted file mode 100644
index 9bf173c..0000000
--- a/usage/cli/src/test/java/brooklyn/cli/CliTest.java
+++ /dev/null
@@ -1,604 +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 brooklyn.cli;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-import groovy.lang.GroovyClassLoader;
-import io.airlift.command.Cli;
-import io.airlift.command.Command;
-import io.airlift.command.ParseException;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Pattern;
-
-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 brooklyn.cli.AbstractMain.BrooklynCommand;
-import brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
-import brooklyn.cli.AbstractMain.HelpCommand;
-import brooklyn.cli.Main.AppShutdownHandler;
-import brooklyn.cli.Main.GeneratePasswordCommand;
-import brooklyn.cli.Main.LaunchCommand;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.proxying.EntityProxy;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.test.Asserts;
-import brooklyn.test.entity.LocalManagementContextForTests;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
-import brooklyn.util.exceptions.UserFacingException;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.io.Files;
-
-public class CliTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CliTest.class);
-
-    // See testInvokeGroovyScript test for usage
-    public static final AtomicBoolean GROOVY_INVOKED = new AtomicBoolean(false);
-
-    private ExecutorService executor;
-    private StartableApplication app;
-    private static volatile ExampleEntity exampleEntity;
-
-    // static so that they can be set from the static classes ExampleApp and ExampleEntity
-    private static volatile boolean exampleAppRunning;
-    private static volatile boolean exampleAppConstructed;
-    private static volatile boolean exampleEntityRunning;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        executor = Executors.newCachedThreadPool();
-        exampleAppConstructed = false;
-        exampleAppRunning = false;
-        exampleEntityRunning = false;
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (executor != null) executor.shutdownNow();
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-        if (exampleEntity != null && exampleEntity.getApplication() != null) Entities.destroyAll(exampleEntity.getApplication().getManagementContext());
-    }
-    
-    @Test
-    public void testLoadApplicationFromClasspath() throws Exception {
-        String appName = ExampleApp.class.getName();
-        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
-        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
-        assertAppWrappedInBuilder((ApplicationBuilder)appBuilder, ExampleApp.class.getCanonicalName());
-    }
-
-    @Test
-    public void testLoadApplicationBuilderFromClasspath() throws Exception {
-        String appName = ExampleAppBuilder.class.getName();
-        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
-        assertTrue(appBuilder instanceof ExampleAppBuilder, "app="+appBuilder);
-    }
-
-    @Test
-    public void testLoadEntityFromClasspath() throws Exception {
-        String entityName = ExampleEntity.class.getName();
-        Object appBuilder = loadApplicationFromClasspathOrParse(entityName);
-        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
-        
-        app = ((ApplicationBuilder)appBuilder).manage();
-        Collection<Entity> entities = app.getChildren();
-        assertEquals(entities.size(), 1, "entities="+entities);
-        assertTrue(Iterables.getOnlyElement(entities) instanceof ExampleEntity, "entities="+entities+"; ifs="+Iterables.getOnlyElement(entities).getClass().getInterfaces());
-        assertTrue(Iterables.getOnlyElement(entities) instanceof EntityProxy, "entities="+entities);
-    }
-
-    @Deprecated // Tests deprecated approach of using impl directly
-    @Test
-    public void testLoadEntityImplFromClasspath() throws Exception {
-        String entityName = ExampleEntityImpl.class.getName();
-        Object appBuilder = loadApplicationFromClasspathOrParse(entityName);
-        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
-        
-        app = ((ApplicationBuilder)appBuilder).manage();
-        Collection<Entity> entities = app.getChildren();
-        assertEquals(entities.size(), 1, "entities="+entities);
-        assertEquals(Iterables.getOnlyElement(entities).getEntityType().getName(), ExampleEntity.class.getCanonicalName(), "entities="+entities);
-        assertTrue(Iterables.getOnlyElement(entities) instanceof EntityProxy, "entities="+entities);
-    }
-
-    @Test
-    public void testLoadApplicationByParsingGroovyFile() throws Exception {
-        String appName = "ExampleAppInFile.groovy"; // file found in src/test/resources (contains empty app)
-        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
-        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
-        assertAppWrappedInBuilder((ApplicationBuilder)appBuilder, "ExampleAppInFile");
-    }
-    
-    private Object loadApplicationFromClasspathOrParse(String appName) throws Exception {
-        LaunchCommand launchCommand = new Main.LaunchCommand();
-        ResourceUtils resourceUtils = ResourceUtils.create(this);
-        GroovyClassLoader loader = new GroovyClassLoader(CliTest.class.getClassLoader());
-        return launchCommand.loadApplicationFromClasspathOrParse(resourceUtils, loader, appName);
-    }
-    
-    private void assertAppWrappedInBuilder(ApplicationBuilder builder, String expectedAppTypeName) {
-        StartableApplication app = builder.manage();
-        try {
-            String typeName = app.getEntityType().getName();
-            assertEquals(typeName, expectedAppTypeName, "app="+app+"; typeName="+typeName);
-        } finally {
-            Entities.destroyAll(app.getManagementContext());
-        }
-    }
-    
-    @Test
-    public void testInvokeGroovyScript() throws Exception {
-        File groovyFile = File.createTempFile("testinvokegroovy", "groovy");
-        try {
-            String contents = CliTest.class.getCanonicalName()+".GROOVY_INVOKED.set(true);";
-            Files.write(contents.getBytes(), groovyFile);
-
-            LaunchCommand launchCommand = new Main.LaunchCommand();
-            ResourceUtils resourceUtils = ResourceUtils.create(this);
-            GroovyClassLoader loader = new GroovyClassLoader(CliTest.class.getClassLoader());
-            launchCommand.execGroovyScript(resourceUtils, loader, groovyFile.toURI().toString());
-            assertTrue(GROOVY_INVOKED.get());
-            
-        } finally {
-            groovyFile.delete();
-            GROOVY_INVOKED.set(false);
-        }
-    }
-    
-    @Test
-    public void testStopAllApplications() throws Exception {
-        LaunchCommand launchCommand = new Main.LaunchCommand();
-        ExampleApp app = new ExampleApp();
-        try {
-            Entities.startManagement(app);
-            app.start(ImmutableList.of(new SimulatedLocation()));
-            assertTrue(app.running);
-            
-            launchCommand.stopAllApps(ImmutableList.of(app));
-            assertFalse(app.running);
-        } finally {
-            Entities.destroyAll(app.getManagementContext());
-        }
-    }
-    
-    @Test
-    public void testWaitsForInterrupt() throws Exception {
-        final AppShutdownHandler listener = new AppShutdownHandler();
-        Thread t = new Thread(new Runnable() {
-            @Override public void run() {
-                listener.waitOnShutdownRequest();
-            }});
-        
-        t.start();
-        t.join(100);
-        assertTrue(t.isAlive());
-        
-        t.interrupt();
-        t.join(10*1000);
-        assertFalse(t.isAlive());
-    }
-
-    protected Cli<BrooklynCommand> buildCli() {
-        return new Main().cliBuilder().build();
-    }
-    
-    @Test
-    public void testLaunchCommandParsesArgs() throws ParseException {
-        BrooklynCommand command = buildCli().parse("launch", 
-                "--app", "my.App", 
-                "--location", "localhost",
-                "--port", "1234",
-                "--bindAddress", "myhostname",
-                "--noConsole", "--noConsoleSecurity", "--stopOnKeyPress", 
-                "--localBrooklynProperties", "/path/to/myprops",
-                LaunchCommand.PERSIST_OPTION, LaunchCommand.PERSIST_OPTION_REBIND, 
-                "--persistenceDir", "/path/to/mypersist",
-                LaunchCommand.HA_OPTION, LaunchCommand.HA_OPTION_STANDBY);
-        assertTrue(command instanceof LaunchCommand, ""+command);
-        String details = command.toString();
-        assertTrue(details.contains("app=my.App"), details);   
-        assertTrue(details.contains("script=null"), details);
-        assertTrue(details.contains("location=localhost"), details);
-        assertTrue(details.contains("port=1234"), details);
-        assertTrue(details.contains("bindAddress=myhostname"), details);
-        assertTrue(details.contains("noConsole=true"), details);
-        assertTrue(details.contains("noConsoleSecurity=true"), details);
-        assertTrue(details.contains("stopOnKeyPress=true"), details);
-        assertTrue(details.contains("localBrooklynProperties=/path/to/myprops"), details);
-        assertTrue(details.contains("persist=rebind"), details);
-        assertTrue(details.contains("persistenceDir=/path/to/mypersist"), details);
-        assertTrue(details.contains("highAvailability=standby"), details);
-    }
-
-    @Test
-    public void testLaunchCommandUsesDefaults() throws ParseException {
-        BrooklynCommand command = buildCli().parse("launch");
-        assertTrue(command instanceof LaunchCommand, ""+command);
-        String details = command.toString();
-        assertTrue(details.contains("app=null"), details);   
-        assertTrue(details.contains("script=null"), details);
-        assertTrue(details.contains("location=null"), details);
-        assertTrue(details.contains("port=null"), details);
-        assertTrue(details.contains("noConsole=false"), details);
-        assertTrue(details.contains("noConsoleSecurity=false"), details);
-        assertTrue(details.contains("stopWhichAppsOnShutdown=theseIfNotPersisted"), details);
-        assertTrue(details.contains("stopOnKeyPress=false"), details);
-        assertTrue(details.contains("localBrooklynProperties=null"), details);
-        assertTrue(details.contains("persist=disabled"), details);
-        assertTrue(details.contains("persistenceDir=null"), details);
-        assertTrue(details.contains("highAvailability=auto"), details);
-    }
-
-    @Test
-    public void testLaunchCommandComplainsWithInvalidArgs() {
-        Cli<BrooklynCommand> cli = buildCli();
-        try {
-            BrooklynCommand command = cli.parse("launch", "invalid");
-            command.call();
-            Assert.fail("Should have thrown exception; instead got "+command);
-        } catch (ParseException e) {
-            /* expected */
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    @Test
-    public void testAppOptionIsOptional() throws ParseException {
-        Cli<BrooklynCommand> cli = buildCli();
-        cli.parse("launch", "blah", "my.App");
-    }
-    
-    public void testHelpCommand() {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("help");
-        assertTrue(command instanceof HelpCommand);
-        command = cli.parse();
-        assertTrue(command instanceof HelpCommand);
-    }
-
-    @Test
-    public void testLaunchWillStartAppWhenGivenImpl() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", ExampleApp.class.getName(), "--location", "localhost");
-        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
-                public void run() {
-                    assertTrue(exampleAppConstructed);
-                    assertTrue(exampleAppRunning);
-                }
-            });
-    }
-
-    @Test
-    public void testLaunchStartsYamlApp() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-no-location.yaml", "--location", "localhost");
-        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
-                public void run() {
-                    assertTrue(exampleEntityRunning);
-                }
-            });
-    }
-    
-    @Test
-    public void testLaunchStartsYamlAppWithCommandLineLocation() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-no-location.yaml", "--location", "localhost:(name=testLocalhost)");
-        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
-                public void run() {
-                    assertTrue(exampleEntityRunning);
-                    assertTrue(Iterables.getOnlyElement(exampleEntity.getApplication().getLocations()).getDisplayName().equals("testLocalhost"));
-                }
-            });
-    }
-    
-    @Test
-    public void testLaunchStartsYamlAppWithYamlAppLocation() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-app-location.yaml");
-        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
-                public void run() {
-                    assertTrue(exampleEntityRunning);
-                    assertTrue(Iterables.getOnlyElement(exampleEntity.getApplication().getLocations()).getDisplayName().equals("appLocalhost"));
-                }
-            });
-    }
-    
-    @Test
-    public void testLaunchStartsYamlAppWithYamlAndAppCliLocation() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-app-location.yaml", "--location", "localhost");
-        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
-                public void run() {
-                    assertTrue(exampleEntityRunning);
-                    assertTrue(Iterables.getFirst(exampleEntity.getApplication().getLocations(), null).getDisplayName().equals("appLocalhost"));
-                }
-            });
-    }
-
-    @Test
-    public void testGeneratePasswordCommandParsed() throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        BrooklynCommand command = cli.parse("generate-password", "--user", "myname");
-        
-        assertTrue(command instanceof GeneratePasswordCommand);
-    }
-
-    @Test
-    public void testGeneratePasswordFromStdin() throws Exception {
-        List<String> stdoutLines = runCommand(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "mypassword\nmypassword\n");
-        
-        System.out.println(stdoutLines);
-    }
-
-    @Test
-    public void testGeneratePasswordFailsIfPasswordsDontMatch() throws Throwable {
-        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "mypassword\ndifferentpassword\n");
-        if (exception instanceof UserFacingException && exception.toString().contains("Passwords did not match")) {
-            // success
-        } else {
-            throw new Exception(exception);
-        }
-    }
-
-    @Test
-    public void testGeneratePasswordFailsIfNoConsole() throws Throwable {
-        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname"), "");
-        if (exception instanceof FatalConfigurationRuntimeException && exception.toString().contains("No console")) {
-            // success
-        } else {
-            throw new Exception(exception);
-        }
-    }
-    
-    @Test
-    public void testGeneratePasswordFailsIfPasswordBlank() throws Throwable {
-        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "\n\n");
-        if (exception instanceof UserFacingException && exception.toString().contains("Password must not be blank")) {
-            // success
-        } else {
-            throw new Exception(exception);
-        }
-    }
-
-    @Test
-    public void testInfoShowsDefaultBanner() throws Exception {
-        List<String> stdoutLines = runCommand(ImmutableList.of("info"), "");
-        
-        for (String line : Splitter.on("\n").split(Main.DEFAULT_BANNER)) {
-            assertTrue(stdoutLines.contains(line), "out="+stdoutLines);
-        }
-    }
-
-    @Test
-    public void testInfoSupportsCustomizedBanner() throws Exception {
-        String origBanner = Main.banner;
-        String origBannerFirstLine = Iterables.get(Splitter.on("\n").split(Main.DEFAULT_BANNER), 0);
-        try {
-            String customBanner = "My Custom Banner";
-            Main.banner = customBanner;
-            List<String> stdoutLines = runCommand(ImmutableList.of("info"), "");
-            
-            assertTrue(stdoutLines.contains(customBanner), "out="+stdoutLines);
-            assertFalse(stdoutLines.contains(origBannerFirstLine), "out="+stdoutLines);
-        } finally {
-            Main.banner = origBanner;
-        }
-    }
-
-    @Test
-    public void testCanCustomiseInfoCommand() throws Exception {
-        Main main = new Main() {
-            protected Class<? extends BrooklynCommand> cliInfoCommand() {
-                return CustomInfoCommand.class;
-            }
-        };
-        List<String> stdoutLines = runCommand(main.cliBuilder().build(), ImmutableList.of("info"), "");
-        assertTrue(stdoutLines.contains("My Custom Info"), "out="+stdoutLines);
-    }
-    
-    @Command(name = "info", description = "Display information about brooklyn")
-    public static class CustomInfoCommand extends BrooklynCommandCollectingArgs {
-        @Override
-        public Void call() throws Exception {
-            System.out.println("My Custom Info");
-            return null;
-        }
-    }
-
-    @Test
-    public void testCanCustomiseLaunchCommand() throws Exception {
-        Main main = new Main() {
-            protected Class<? extends BrooklynCommand> cliLaunchCommand() {
-                return CustomLaunchCommand.class;
-            }
-        };
-        List<String> stdoutLines = runCommand(main.cliBuilder().build(), ImmutableList.of("launch"), "");
-        assertTrue(stdoutLines.contains("My Custom Launch"), "out="+stdoutLines);
-    }
-    
-    @Command(name = "launch", description = "Starts a server, optionally with applications")
-    public static class CustomLaunchCommand extends BrooklynCommandCollectingArgs {
-        @Override
-        public Void call() throws Exception {
-            System.out.println("My Custom Launch");
-            return null;
-        }
-    }
-
-    protected Throwable runCommandExpectingException(Iterable<String> args, String input) throws Exception {
-        try {
-            List<String> stdout = runCommand(args, input);
-            fail("Expected exception, but got stdout="+stdout);
-            return null;
-        } catch (ExecutionException e) {
-            return e.getCause();
-        }
-    }
-
-    protected List<String> runCommand(Iterable<String> args, String input) throws Exception {
-        Cli<BrooklynCommand> cli = buildCli();
-        return runCommand(cli, args, input);
-    }
-    
-    protected List<String> runCommand(Cli<BrooklynCommand> cli, Iterable<String> args, String input) throws Exception {
-        final BrooklynCommand command = cli.parse(args);
-        
-        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
-        Thread t= new Thread(new Runnable() {
-            public void run() {
-                try {
-                    command.call();
-                } catch (Exception e) {
-                    exception.set(e);
-                    throw Exceptions.propagate(e);
-                }
-            }});
-        
-        InputStream origIn = System.in;
-        PrintStream origOut = System.out;
-        try {
-            InputStream stdin = new ByteArrayInputStream(input.getBytes());
-            System.setIn(stdin);
-
-            ByteArrayOutputStream stdoutBytes = new ByteArrayOutputStream();
-            PrintStream stdout = new PrintStream(stdoutBytes);
-            System.setOut(stdout);
-
-            t.start();
-
-            t.join(10*1000);
-            assertFalse(t.isAlive());
-            
-            if (exception.get() != null) {
-                throw new ExecutionException(exception.get());
-            }
-            
-            return ImmutableList.copyOf(Splitter.on(Pattern.compile("\r?\n")).split(new String(stdoutBytes.toByteArray())));
-        } finally {
-            System.setIn(origIn);
-            System.setOut(origOut);
-            t.interrupt();
-        }
-    }
-
-    private void submitCommandAndAssertRunnableSucceeds(final BrooklynCommand command, Runnable runnable) {
-        if (command instanceof LaunchCommand) {
-            ((LaunchCommand)command).useManagementContext(new LocalManagementContextForTests());
-        }
-        executor.submit(new Callable<Void>() {
-            public Void call() throws Exception {
-                try {
-                    LOG.info("Calling command: "+command);
-                    command.call();
-                    return null;
-                } catch (Throwable t) {
-                    LOG.error("Error executing command: "+t, t);
-                    throw Exceptions.propagate(t);
-                }
-            }});
-
-        Asserts.succeedsEventually(MutableMap.of("timeout", Duration.ONE_MINUTE), runnable);
-    }
-
-    //  An empty app to be used for testing
-    public static class ExampleApp extends AbstractApplication {
-        volatile boolean running;
-        volatile boolean constructed;
-        
-        @Override public void init() {
-            super.init();
-            constructed = true;
-            exampleAppConstructed = true;
-        }
-        @Override public void start(Collection<? extends Location> locations) {
-            super.start(locations);
-            running = true;
-            exampleAppRunning = true;
-        }
-        @Override public void stop() {
-            super.stop();
-            running = false;
-            exampleAppRunning = false;
-        }
-    }
-    
-    // An empty entity to be used for testing
-    @ImplementedBy(ExampleEntityImpl.class)
-    public static interface ExampleEntity extends Entity, Startable {
-    }   
-
-    public static class ExampleEntityImpl extends AbstractEntity implements ExampleEntity {
-        public ExampleEntityImpl() {
-            super();
-            exampleEntity = this;
-        }
-        @Override public void start(Collection<? extends Location> locations) {
-            exampleEntityRunning = true;
-        }
-        @Override public void stop() {
-            exampleEntityRunning = false;
-        }
-        @Override public void restart() {
-        }
-    }
-
-    // An empty app builder to be used for testing
-    public static class ExampleAppBuilder extends ApplicationBuilder {
-        @Override protected void doBuild() {
-            // no-op
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java b/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java
deleted file mode 100644
index 6069f74..0000000
--- a/usage/cli/src/test/java/brooklyn/cli/CloudExplorerLiveTest.java
+++ /dev/null
@@ -1,209 +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 brooklyn.cli;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import io.airlift.command.Cli;
-import io.airlift.command.ParseException;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.List;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.cli.AbstractMain.BrooklynCommand;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class CloudExplorerLiveTest {
-
-    private String stdout;
-    private String stderr;
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        stdout = null;
-        stderr = null;
-    }
-
-    @Test
-    public void testNoArgsThrows() throws Exception {
-        try {
-            call(new String[0]);
-            Assert.fail("No args should fail");
-        } catch (ParseException e) {
-            Assert.assertTrue(e.toString().contains("No command specified"), ""+e);
-        }
-    }
-
-    // A user running these tests might not have any instances; so don't assert that there will be one
-    @Test(groups={"Live", "Live-sanity"})
-    public void testListInstances() throws Exception {
-        call("cloud-compute", "list-instances", "--location", "jclouds:aws-ec2:eu-west-1");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Instances {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testListImages() throws Exception {
-        call("cloud-compute", "list-images", "--location", "jclouds:softlayer:ams01");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        // FIXME Now has location details pre-amble; fix assertions
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Images {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-        
-        List<String> imageLines = lines.subList(1, lines.size()-1);
-        assertTrue(imageLines.size() > 0, errmsg);
-        assertTrue(imageLines.get(0).matches(".*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testListHardwareProfiles() throws Exception {
-        call("cloud-compute", "list-hardware-profiles", "--location", "jclouds:softlayer:ams01");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        // FIXME Now has location details pre-amble; fix assertions
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Hardware Profiles {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-        
-        List<String> hardwareProfileLines = lines.subList(1, lines.size()-1);
-        assertTrue(hardwareProfileLines.size() > 0, errmsg);
-        assertTrue(hardwareProfileLines.get(0).matches(".*cpu=.*memory=.*processors=.*"), "line="+hardwareProfileLines.get(0)+"; "+errmsg);
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testGetImage() throws Exception {
-        call("cloud-compute", "get-image", "--location", "jclouds:softlayer:ams01", "CENTOS_6_64");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        // FIXME Now has location details pre-amble; fix assertions
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Image CENTOS_6_64 {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-        
-        List<String> imageLines = lines.subList(1, lines.size()-1);
-        assertTrue(imageLines.size() > 0, errmsg);
-        assertTrue(imageLines.get(0).matches(".*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testGetDefaultTemplate() throws Exception {
-        call("cloud-compute", "default-template", "--location", "jclouds:softlayer:ams01");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        // FIXME Now has location details pre-amble; fix assertions
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Default template {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-        
-        List<String> imageLines = lines.subList(1, lines.size()-1);
-        assertTrue(imageLines.size() > 0, errmsg);
-        assertTrue(imageLines.get(0).matches("\tImage.*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
-        assertTrue(imageLines.get(1).matches("\tHardware.*cpu=.*memory=.*processors=.*"), "line="+imageLines.get(1)+"; "+errmsg);
-        assertTrue(imageLines.get(2).matches("\tLocation.*scope=.*"), "line="+imageLines.get(2)+"; "+errmsg);
-        assertTrue(imageLines.get(3).matches("\tOptions.*"), "line="+imageLines.get(3)+"; "+errmsg);
-    }
-
-    /**
-     * Expects in brooklyn.properties:
-     *     brooklyn.location.named.softlayer-swift-ams01=jclouds:swift:https://ams01.objectstorage.softlayer.net/auth/v1.0
-     *     brooklyn.location.named.softlayer-swift-ams01.identity=ABCDEFGH:myusername
-     *     brooklyn.location.named.softlayer-swift-ams01.credential=1234567890...
-     */
-    @Test(groups={"Live", "Live-sanity"})
-    public void testListContainers() throws Exception {
-        call("cloud-blobstore", "list-containers", "--location", "named:softlayer-swift-ams01");
-        
-        String errmsg = "stdout="+stdout+"; stderr="+stderr;
-        
-        // FIXME Now has location details pre-amble; fix assertions
-        List<String> lines = assertAndStipSingleLocationHeader(stdout);
-        assertTrue(lines.get(0).equals("Containers {"), errmsg);
-        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
-        assertTrue(stderr.isEmpty(), errmsg);
-    }
-
-    protected void call(String... args) throws Exception {
-        call(new ByteArrayInputStream(new byte[0]), args);
-    }
-
-    protected void call(InputStream instream, String... args) throws Exception {
-        ByteArrayOutputStream stdoutStream = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderrStream = new ByteArrayOutputStream();
-        
-        Cli<BrooklynCommand> parser = new Main().cliBuilder().build();
-        
-        BrooklynCommand command = parser.parse(args);
-        command.stdout = new PrintStream(stdoutStream);
-        command.stderr = new PrintStream(stderrStream);
-        command.stdin = instream;
-        try {
-            command.call();
-        } finally {
-            stdout = new String(stdoutStream.toByteArray());
-            stderr = new String(stderrStream.toByteArray());
-        }
-    }
-    
-    private List<String> assertAndStipSingleLocationHeader(String stdout) {
-        List<String> lines = ImmutableList.copyOf(Splitter.on("\n").omitEmptyStrings().split(stdout));
-
-        String errmsg = "lines="+lines;
-        
-        int nextLineCount = 0;
-        assertEquals(lines.get(nextLineCount++), "Location {", errmsg);
-        assertEquals(lines.get(lines.size()-1), "}", errmsg);
-        assertTrue(lines.get(nextLineCount++).startsWith("\tprovider: "), errmsg);
-        assertTrue(lines.get(nextLineCount++).startsWith("\tdisplayName: "), errmsg);
-        assertTrue(lines.get(nextLineCount++).startsWith("\tidentity: "), errmsg);
-        if (lines.get(nextLineCount).startsWith("\tendpoint: ")) nextLineCount++;
-        if (lines.get(nextLineCount).startsWith("\tregion: ")) nextLineCount++;
-        
-        List<String> result = Lists.newArrayList();
-        for (String line : lines.subList(nextLineCount, lines.size()-1)) {
-            assertTrue(line.startsWith("\t"), errmsg);
-            result.add(line.substring(1));
-        }
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
new file mode 100644
index 0000000..96e3e93
--- /dev/null
+++ b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
@@ -0,0 +1,605 @@
+/*
+ * 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.cli;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import groovy.lang.GroovyClassLoader;
+import io.airlift.command.Cli;
+import io.airlift.command.Command;
+import io.airlift.command.ParseException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.cli.Main;
+import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
+import org.apache.brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
+import org.apache.brooklyn.cli.AbstractMain.HelpCommand;
+import org.apache.brooklyn.cli.Main.AppShutdownHandler;
+import org.apache.brooklyn.cli.Main.GeneratePasswordCommand;
+import org.apache.brooklyn.cli.Main.LaunchCommand;
+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 brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxying.EntityProxy;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.entity.trait.Startable;
+import brooklyn.location.Location;
+import brooklyn.location.basic.SimulatedLocation;
+import brooklyn.test.Asserts;
+import brooklyn.test.entity.LocalManagementContextForTests;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
+import brooklyn.util.exceptions.UserFacingException;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.io.Files;
+
+public class CliTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CliTest.class);
+
+    // See testInvokeGroovyScript test for usage
+    public static final AtomicBoolean GROOVY_INVOKED = new AtomicBoolean(false);
+
+    private ExecutorService executor;
+    private StartableApplication app;
+    private static volatile ExampleEntity exampleEntity;
+
+    // static so that they can be set from the static classes ExampleApp and ExampleEntity
+    private static volatile boolean exampleAppRunning;
+    private static volatile boolean exampleAppConstructed;
+    private static volatile boolean exampleEntityRunning;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        executor = Executors.newCachedThreadPool();
+        exampleAppConstructed = false;
+        exampleAppRunning = false;
+        exampleEntityRunning = false;
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (executor != null) executor.shutdownNow();
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        if (exampleEntity != null && exampleEntity.getApplication() != null) Entities.destroyAll(exampleEntity.getApplication().getManagementContext());
+    }
+    
+    @Test
+    public void testLoadApplicationFromClasspath() throws Exception {
+        String appName = ExampleApp.class.getName();
+        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
+        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
+        assertAppWrappedInBuilder((ApplicationBuilder)appBuilder, ExampleApp.class.getCanonicalName());
+    }
+
+    @Test
+    public void testLoadApplicationBuilderFromClasspath() throws Exception {
+        String appName = ExampleAppBuilder.class.getName();
+        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
+        assertTrue(appBuilder instanceof ExampleAppBuilder, "app="+appBuilder);
+    }
+
+    @Test
+    public void testLoadEntityFromClasspath() throws Exception {
+        String entityName = ExampleEntity.class.getName();
+        Object appBuilder = loadApplicationFromClasspathOrParse(entityName);
+        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
+        
+        app = ((ApplicationBuilder)appBuilder).manage();
+        Collection<Entity> entities = app.getChildren();
+        assertEquals(entities.size(), 1, "entities="+entities);
+        assertTrue(Iterables.getOnlyElement(entities) instanceof ExampleEntity, "entities="+entities+"; ifs="+Iterables.getOnlyElement(entities).getClass().getInterfaces());
+        assertTrue(Iterables.getOnlyElement(entities) instanceof EntityProxy, "entities="+entities);
+    }
+
+    @Deprecated // Tests deprecated approach of using impl directly
+    @Test
+    public void testLoadEntityImplFromClasspath() throws Exception {
+        String entityName = ExampleEntityImpl.class.getName();
+        Object appBuilder = loadApplicationFromClasspathOrParse(entityName);
+        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
+        
+        app = ((ApplicationBuilder)appBuilder).manage();
+        Collection<Entity> entities = app.getChildren();
+        assertEquals(entities.size(), 1, "entities="+entities);
+        assertEquals(Iterables.getOnlyElement(entities).getEntityType().getName(), ExampleEntity.class.getCanonicalName(), "entities="+entities);
+        assertTrue(Iterables.getOnlyElement(entities) instanceof EntityProxy, "entities="+entities);
+    }
+
+    @Test
+    public void testLoadApplicationByParsingGroovyFile() throws Exception {
+        String appName = "ExampleAppInFile.groovy"; // file found in src/test/resources (contains empty app)
+        Object appBuilder = loadApplicationFromClasspathOrParse(appName);
+        assertTrue(appBuilder instanceof ApplicationBuilder, "app="+appBuilder);
+        assertAppWrappedInBuilder((ApplicationBuilder)appBuilder, "ExampleAppInFile");
+    }
+    
+    private Object loadApplicationFromClasspathOrParse(String appName) throws Exception {
+        LaunchCommand launchCommand = new Main.LaunchCommand();
+        ResourceUtils resourceUtils = ResourceUtils.create(this);
+        GroovyClassLoader loader = new GroovyClassLoader(CliTest.class.getClassLoader());
+        return launchCommand.loadApplicationFromClasspathOrParse(resourceUtils, loader, appName);
+    }
+    
+    private void assertAppWrappedInBuilder(ApplicationBuilder builder, String expectedAppTypeName) {
+        StartableApplication app = builder.manage();
+        try {
+            String typeName = app.getEntityType().getName();
+            assertEquals(typeName, expectedAppTypeName, "app="+app+"; typeName="+typeName);
+        } finally {
+            Entities.destroyAll(app.getManagementContext());
+        }
+    }
+    
+    @Test
+    public void testInvokeGroovyScript() throws Exception {
+        File groovyFile = File.createTempFile("testinvokegroovy", "groovy");
+        try {
+            String contents = CliTest.class.getCanonicalName()+".GROOVY_INVOKED.set(true);";
+            Files.write(contents.getBytes(), groovyFile);
+
+            LaunchCommand launchCommand = new Main.LaunchCommand();
+            ResourceUtils resourceUtils = ResourceUtils.create(this);
+            GroovyClassLoader loader = new GroovyClassLoader(CliTest.class.getClassLoader());
+            launchCommand.execGroovyScript(resourceUtils, loader, groovyFile.toURI().toString());
+            assertTrue(GROOVY_INVOKED.get());
+            
+        } finally {
+            groovyFile.delete();
+            GROOVY_INVOKED.set(false);
+        }
+    }
+    
+    @Test
+    public void testStopAllApplications() throws Exception {
+        LaunchCommand launchCommand = new Main.LaunchCommand();
+        ExampleApp app = new ExampleApp();
+        try {
+            Entities.startManagement(app);
+            app.start(ImmutableList.of(new SimulatedLocation()));
+            assertTrue(app.running);
+            
+            launchCommand.stopAllApps(ImmutableList.of(app));
+            assertFalse(app.running);
+        } finally {
+            Entities.destroyAll(app.getManagementContext());
+        }
+    }
+    
+    @Test
+    public void testWaitsForInterrupt() throws Exception {
+        final AppShutdownHandler listener = new AppShutdownHandler();
+        Thread t = new Thread(new Runnable() {
+            @Override public void run() {
+                listener.waitOnShutdownRequest();
+            }});
+        
+        t.start();
+        t.join(100);
+        assertTrue(t.isAlive());
+        
+        t.interrupt();
+        t.join(10*1000);
+        assertFalse(t.isAlive());
+    }
+
+    protected Cli<BrooklynCommand> buildCli() {
+        return new Main().cliBuilder().build();
+    }
+    
+    @Test
+    public void testLaunchCommandParsesArgs() throws ParseException {
+        BrooklynCommand command = buildCli().parse("launch", 
+                "--app", "my.App", 
+                "--location", "localhost",
+                "--port", "1234",
+                "--bindAddress", "myhostname",
+                "--noConsole", "--noConsoleSecurity", "--stopOnKeyPress", 
+                "--localBrooklynProperties", "/path/to/myprops",
+                LaunchCommand.PERSIST_OPTION, LaunchCommand.PERSIST_OPTION_REBIND, 
+                "--persistenceDir", "/path/to/mypersist",
+                LaunchCommand.HA_OPTION, LaunchCommand.HA_OPTION_STANDBY);
+        assertTrue(command instanceof LaunchCommand, ""+command);
+        String details = command.toString();
+        assertTrue(details.contains("app=my.App"), details);   
+        assertTrue(details.contains("script=null"), details);
+        assertTrue(details.contains("location=localhost"), details);
+        assertTrue(details.contains("port=1234"), details);
+        assertTrue(details.contains("bindAddress=myhostname"), details);
+        assertTrue(details.contains("noConsole=true"), details);
+        assertTrue(details.contains("noConsoleSecurity=true"), details);
+        assertTrue(details.contains("stopOnKeyPress=true"), details);
+        assertTrue(details.contains("localBrooklynProperties=/path/to/myprops"), details);
+        assertTrue(details.contains("persist=rebind"), details);
+        assertTrue(details.contains("persistenceDir=/path/to/mypersist"), details);
+        assertTrue(details.contains("highAvailability=standby"), details);
+    }
+
+    @Test
+    public void testLaunchCommandUsesDefaults() throws ParseException {
+        BrooklynCommand command = buildCli().parse("launch");
+        assertTrue(command instanceof LaunchCommand, ""+command);
+        String details = command.toString();
+        assertTrue(details.contains("app=null"), details);   
+        assertTrue(details.contains("script=null"), details);
+        assertTrue(details.contains("location=null"), details);
+        assertTrue(details.contains("port=null"), details);
+        assertTrue(details.contains("noConsole=false"), details);
+        assertTrue(details.contains("noConsoleSecurity=false"), details);
+        assertTrue(details.contains("stopWhichAppsOnShutdown=theseIfNotPersisted"), details);
+        assertTrue(details.contains("stopOnKeyPress=false"), details);
+        assertTrue(details.contains("localBrooklynProperties=null"), details);
+        assertTrue(details.contains("persist=disabled"), details);
+        assertTrue(details.contains("persistenceDir=null"), details);
+        assertTrue(details.contains("highAvailability=auto"), details);
+    }
+
+    @Test
+    public void testLaunchCommandComplainsWithInvalidArgs() {
+        Cli<BrooklynCommand> cli = buildCli();
+        try {
+            BrooklynCommand command = cli.parse("launch", "invalid");
+            command.call();
+            Assert.fail("Should have thrown exception; instead got "+command);
+        } catch (ParseException e) {
+            /* expected */
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    @Test
+    public void testAppOptionIsOptional() throws ParseException {
+        Cli<BrooklynCommand> cli = buildCli();
+        cli.parse("launch", "blah", "my.App");
+    }
+    
+    public void testHelpCommand() {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("help");
+        assertTrue(command instanceof HelpCommand);
+        command = cli.parse();
+        assertTrue(command instanceof HelpCommand);
+    }
+
+    @Test
+    public void testLaunchWillStartAppWhenGivenImpl() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", ExampleApp.class.getName(), "--location", "localhost");
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    assertTrue(exampleAppConstructed);
+                    assertTrue(exampleAppRunning);
+                }
+            });
+    }
+
+    @Test
+    public void testLaunchStartsYamlApp() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-no-location.yaml", "--location", "localhost");
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    assertTrue(exampleEntityRunning);
+                }
+            });
+    }
+    
+    @Test
+    public void testLaunchStartsYamlAppWithCommandLineLocation() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-no-location.yaml", "--location", "localhost:(name=testLocalhost)");
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    assertTrue(exampleEntityRunning);
+                    assertTrue(Iterables.getOnlyElement(exampleEntity.getApplication().getLocations()).getDisplayName().equals("testLocalhost"));
+                }
+            });
+    }
+    
+    @Test
+    public void testLaunchStartsYamlAppWithYamlAppLocation() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-app-location.yaml");
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    assertTrue(exampleEntityRunning);
+                    assertTrue(Iterables.getOnlyElement(exampleEntity.getApplication().getLocations()).getDisplayName().equals("appLocalhost"));
+                }
+            });
+    }
+    
+    @Test
+    public void testLaunchStartsYamlAppWithYamlAndAppCliLocation() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("launch", "--noConsole", "--app", "example-app-app-location.yaml", "--location", "localhost");
+        submitCommandAndAssertRunnableSucceeds(command, new Runnable() {
+                public void run() {
+                    assertTrue(exampleEntityRunning);
+                    assertTrue(Iterables.getFirst(exampleEntity.getApplication().getLocations(), null).getDisplayName().equals("appLocalhost"));
+                }
+            });
+    }
+
+    @Test
+    public void testGeneratePasswordCommandParsed() throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        BrooklynCommand command = cli.parse("generate-password", "--user", "myname");
+        
+        assertTrue(command instanceof GeneratePasswordCommand);
+    }
+
+    @Test
+    public void testGeneratePasswordFromStdin() throws Exception {
+        List<String> stdoutLines = runCommand(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "mypassword\nmypassword\n");
+        
+        System.out.println(stdoutLines);
+    }
+
+    @Test
+    public void testGeneratePasswordFailsIfPasswordsDontMatch() throws Throwable {
+        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "mypassword\ndifferentpassword\n");
+        if (exception instanceof UserFacingException && exception.toString().contains("Passwords did not match")) {
+            // success
+        } else {
+            throw new Exception(exception);
+        }
+    }
+
+    @Test
+    public void testGeneratePasswordFailsIfNoConsole() throws Throwable {
+        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname"), "");
+        if (exception instanceof FatalConfigurationRuntimeException && exception.toString().contains("No console")) {
+            // success
+        } else {
+            throw new Exception(exception);
+        }
+    }
+    
+    @Test
+    public void testGeneratePasswordFailsIfPasswordBlank() throws Throwable {
+        Throwable exception = runCommandExpectingException(ImmutableList.of("generate-password", "--user", "myname", "--stdin"), "\n\n");
+        if (exception instanceof UserFacingException && exception.toString().contains("Password must not be blank")) {
+            // success
+        } else {
+            throw new Exception(exception);
+        }
+    }
+
+    @Test
+    public void testInfoShowsDefaultBanner() throws Exception {
+        List<String> stdoutLines = runCommand(ImmutableList.of("info"), "");
+        
+        for (String line : Splitter.on("\n").split(Main.DEFAULT_BANNER)) {
+            assertTrue(stdoutLines.contains(line), "out="+stdoutLines);
+        }
+    }
+
+    @Test
+    public void testInfoSupportsCustomizedBanner() throws Exception {
+        String origBanner = Main.banner;
+        String origBannerFirstLine = Iterables.get(Splitter.on("\n").split(Main.DEFAULT_BANNER), 0);
+        try {
+            String customBanner = "My Custom Banner";
+            Main.banner = customBanner;
+            List<String> stdoutLines = runCommand(ImmutableList.of("info"), "");
+            
+            assertTrue(stdoutLines.contains(customBanner), "out="+stdoutLines);
+            assertFalse(stdoutLines.contains(origBannerFirstLine), "out="+stdoutLines);
+        } finally {
+            Main.banner = origBanner;
+        }
+    }
+
+    @Test
+    public void testCanCustomiseInfoCommand() throws Exception {
+        Main main = new Main() {
+            protected Class<? extends BrooklynCommand> cliInfoCommand() {
+                return CustomInfoCommand.class;
+            }
+        };
+        List<String> stdoutLines = runCommand(main.cliBuilder().build(), ImmutableList.of("info"), "");
+        assertTrue(stdoutLines.contains("My Custom Info"), "out="+stdoutLines);
+    }
+    
+    @Command(name = "info", description = "Display information about brooklyn")
+    public static class CustomInfoCommand extends BrooklynCommandCollectingArgs {
+        @Override
+        public Void call() throws Exception {
+            System.out.println("My Custom Info");
+            return null;
+        }
+    }
+
+    @Test
+    public void testCanCustomiseLaunchCommand() throws Exception {
+        Main main = new Main() {
+            protected Class<? extends BrooklynCommand> cliLaunchCommand() {
+                return CustomLaunchCommand.class;
+            }
+        };
+        List<String> stdoutLines = runCommand(main.cliBuilder().build(), ImmutableList.of("launch"), "");
+        assertTrue(stdoutLines.contains("My Custom Launch"), "out="+stdoutLines);
+    }
+    
+    @Command(name = "launch", description = "Starts a server, optionally with applications")
+    public static class CustomLaunchCommand extends BrooklynCommandCollectingArgs {
+        @Override
+        public Void call() throws Exception {
+            System.out.println("My Custom Launch");
+            return null;
+        }
+    }
+
+    protected Throwable runCommandExpectingException(Iterable<String> args, String input) throws Exception {
+        try {
+            List<String> stdout = runCommand(args, input);
+            fail("Expected exception, but got stdout="+stdout);
+            return null;
+        } catch (ExecutionException e) {
+            return e.getCause();
+        }
+    }
+
+    protected List<String> runCommand(Iterable<String> args, String input) throws Exception {
+        Cli<BrooklynCommand> cli = buildCli();
+        return runCommand(cli, args, input);
+    }
+    
+    protected List<String> runCommand(Cli<BrooklynCommand> cli, Iterable<String> args, String input) throws Exception {
+        final BrooklynCommand command = cli.parse(args);
+        
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        Thread t= new Thread(new Runnable() {
+            public void run() {
+                try {
+                    command.call();
+                } catch (Exception e) {
+                    exception.set(e);
+                    throw Exceptions.propagate(e);
+                }
+            }});
+        
+        InputStream origIn = System.in;
+        PrintStream origOut = System.out;
+        try {
+            InputStream stdin = new ByteArrayInputStream(input.getBytes());
+            System.setIn(stdin);
+
+            ByteArrayOutputStream stdoutBytes = new ByteArrayOutputStream();
+            PrintStream stdout = new PrintStream(stdoutBytes);
+            System.setOut(stdout);
+
+            t.start();
+
+            t.join(10*1000);
+            assertFalse(t.isAlive());
+            
+            if (exception.get() != null) {
+                throw new ExecutionException(exception.get());
+            }
+            
+            return ImmutableList.copyOf(Splitter.on(Pattern.compile("\r?\n")).split(new String(stdoutBytes.toByteArray())));
+        } finally {
+            System.setIn(origIn);
+            System.setOut(origOut);
+            t.interrupt();
+        }
+    }
+
+    private void submitCommandAndAssertRunnableSucceeds(final BrooklynCommand command, Runnable runnable) {
+        if (command instanceof LaunchCommand) {
+            ((LaunchCommand)command).useManagementContext(new LocalManagementContextForTests());
+        }
+        executor.submit(new Callable<Void>() {
+            public Void call() throws Exception {
+                try {
+                    LOG.info("Calling command: "+command);
+                    command.call();
+                    return null;
+                } catch (Throwable t) {
+                    LOG.error("Error executing command: "+t, t);
+                    throw Exceptions.propagate(t);
+                }
+            }});
+
+        Asserts.succeedsEventually(MutableMap.of("timeout", Duration.ONE_MINUTE), runnable);
+    }
+
+    //  An empty app to be used for testing
+    public static class ExampleApp extends AbstractApplication {
+        volatile boolean running;
+        volatile boolean constructed;
+        
+        @Override public void init() {
+            super.init();
+            constructed = true;
+            exampleAppConstructed = true;
+        }
+        @Override public void start(Collection<? extends Location> locations) {
+            super.start(locations);
+            running = true;
+            exampleAppRunning = true;
+        }
+        @Override public void stop() {
+            super.stop();
+            running = false;
+            exampleAppRunning = false;
+        }
+    }
+    
+    // An empty entity to be used for testing
+    @ImplementedBy(ExampleEntityImpl.class)
+    public static interface ExampleEntity extends Entity, Startable {
+    }   
+
+    public static class ExampleEntityImpl extends AbstractEntity implements ExampleEntity {
+        public ExampleEntityImpl() {
+            super();
+            exampleEntity = this;
+        }
+        @Override public void start(Collection<? extends Location> locations) {
+            exampleEntityRunning = true;
+        }
+        @Override public void stop() {
+            exampleEntityRunning = false;
+        }
+        @Override public void restart() {
+        }
+    }
+
+    // An empty app builder to be used for testing
+    public static class ExampleAppBuilder extends ApplicationBuilder {
+        @Override protected void doBuild() {
+            // no-op
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/java/org/apache/brooklyn/cli/CloudExplorerLiveTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/org/apache/brooklyn/cli/CloudExplorerLiveTest.java b/usage/cli/src/test/java/org/apache/brooklyn/cli/CloudExplorerLiveTest.java
new file mode 100644
index 0000000..8abe1c0
--- /dev/null
+++ b/usage/cli/src/test/java/org/apache/brooklyn/cli/CloudExplorerLiveTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.cli;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import io.airlift.command.Cli;
+import io.airlift.command.ParseException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.brooklyn.cli.Main;
+import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class CloudExplorerLiveTest {
+
+    private String stdout;
+    private String stderr;
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        stdout = null;
+        stderr = null;
+    }
+
+    @Test
+    public void testNoArgsThrows() throws Exception {
+        try {
+            call(new String[0]);
+            Assert.fail("No args should fail");
+        } catch (ParseException e) {
+            Assert.assertTrue(e.toString().contains("No command specified"), ""+e);
+        }
+    }
+
+    // A user running these tests might not have any instances; so don't assert that there will be one
+    @Test(groups={"Live", "Live-sanity"})
+    public void testListInstances() throws Exception {
+        call("cloud-compute", "list-instances", "--location", "jclouds:aws-ec2:eu-west-1");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Instances {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testListImages() throws Exception {
+        call("cloud-compute", "list-images", "--location", "jclouds:softlayer:ams01");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        // FIXME Now has location details pre-amble; fix assertions
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Images {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+        
+        List<String> imageLines = lines.subList(1, lines.size()-1);
+        assertTrue(imageLines.size() > 0, errmsg);
+        assertTrue(imageLines.get(0).matches(".*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testListHardwareProfiles() throws Exception {
+        call("cloud-compute", "list-hardware-profiles", "--location", "jclouds:softlayer:ams01");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        // FIXME Now has location details pre-amble; fix assertions
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Hardware Profiles {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+        
+        List<String> hardwareProfileLines = lines.subList(1, lines.size()-1);
+        assertTrue(hardwareProfileLines.size() > 0, errmsg);
+        assertTrue(hardwareProfileLines.get(0).matches(".*cpu=.*memory=.*processors=.*"), "line="+hardwareProfileLines.get(0)+"; "+errmsg);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testGetImage() throws Exception {
+        call("cloud-compute", "get-image", "--location", "jclouds:softlayer:ams01", "CENTOS_6_64");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        // FIXME Now has location details pre-amble; fix assertions
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Image CENTOS_6_64 {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+        
+        List<String> imageLines = lines.subList(1, lines.size()-1);
+        assertTrue(imageLines.size() > 0, errmsg);
+        assertTrue(imageLines.get(0).matches(".*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testGetDefaultTemplate() throws Exception {
+        call("cloud-compute", "default-template", "--location", "jclouds:softlayer:ams01");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        // FIXME Now has location details pre-amble; fix assertions
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Default template {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+        
+        List<String> imageLines = lines.subList(1, lines.size()-1);
+        assertTrue(imageLines.size() > 0, errmsg);
+        assertTrue(imageLines.get(0).matches("\tImage.*id=.*providerId=.*os=.*description=.*"), "line="+imageLines.get(0)+"; "+errmsg);
+        assertTrue(imageLines.get(1).matches("\tHardware.*cpu=.*memory=.*processors=.*"), "line="+imageLines.get(1)+"; "+errmsg);
+        assertTrue(imageLines.get(2).matches("\tLocation.*scope=.*"), "line="+imageLines.get(2)+"; "+errmsg);
+        assertTrue(imageLines.get(3).matches("\tOptions.*"), "line="+imageLines.get(3)+"; "+errmsg);
+    }
+
+    /**
+     * Expects in brooklyn.properties:
+     *     brooklyn.location.named.softlayer-swift-ams01=jclouds:swift:https://ams01.objectstorage.softlayer.net/auth/v1.0
+     *     brooklyn.location.named.softlayer-swift-ams01.identity=ABCDEFGH:myusername
+     *     brooklyn.location.named.softlayer-swift-ams01.credential=1234567890...
+     */
+    @Test(groups={"Live", "Live-sanity"})
+    public void testListContainers() throws Exception {
+        call("cloud-blobstore", "list-containers", "--location", "named:softlayer-swift-ams01");
+        
+        String errmsg = "stdout="+stdout+"; stderr="+stderr;
+        
+        // FIXME Now has location details pre-amble; fix assertions
+        List<String> lines = assertAndStipSingleLocationHeader(stdout);
+        assertTrue(lines.get(0).equals("Containers {"), errmsg);
+        assertTrue(lines.get(lines.size()-1).equals("}"), errmsg);
+        assertTrue(stderr.isEmpty(), errmsg);
+    }
+
+    protected void call(String... args) throws Exception {
+        call(new ByteArrayInputStream(new byte[0]), args);
+    }
+
+    protected void call(InputStream instream, String... args) throws Exception {
+        ByteArrayOutputStream stdoutStream = new ByteArrayOutputStream();
+        ByteArrayOutputStream stderrStream = new ByteArrayOutputStream();
+        
+        Cli<BrooklynCommand> parser = new Main().cliBuilder().build();
+        
+        BrooklynCommand command = parser.parse(args);
+        command.stdout = new PrintStream(stdoutStream);
+        command.stderr = new PrintStream(stderrStream);
+        command.stdin = instream;
+        try {
+            command.call();
+        } finally {
+            stdout = new String(stdoutStream.toByteArray());
+            stderr = new String(stderrStream.toByteArray());
+        }
+    }
+    
+    private List<String> assertAndStipSingleLocationHeader(String stdout) {
+        List<String> lines = ImmutableList.copyOf(Splitter.on("\n").omitEmptyStrings().split(stdout));
+
+        String errmsg = "lines="+lines;
+        
+        int nextLineCount = 0;
+        assertEquals(lines.get(nextLineCount++), "Location {", errmsg);
+        assertEquals(lines.get(lines.size()-1), "}", errmsg);
+        assertTrue(lines.get(nextLineCount++).startsWith("\tprovider: "), errmsg);
+        assertTrue(lines.get(nextLineCount++).startsWith("\tdisplayName: "), errmsg);
+        assertTrue(lines.get(nextLineCount++).startsWith("\tidentity: "), errmsg);
+        if (lines.get(nextLineCount).startsWith("\tendpoint: ")) nextLineCount++;
+        if (lines.get(nextLineCount).startsWith("\tregion: ")) nextLineCount++;
+        
+        List<String> result = Lists.newArrayList();
+        for (String line : lines.subList(nextLineCount, lines.size()-1)) {
+            assertTrue(line.startsWith("\t"), errmsg);
+            result.add(line.substring(1));
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/resources/example-app-app-location.yaml
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/resources/example-app-app-location.yaml b/usage/cli/src/test/resources/example-app-app-location.yaml
index aca5362..f161e8d 100644
--- a/usage/cli/src/test/resources/example-app-app-location.yaml
+++ b/usage/cli/src/test/resources/example-app-app-location.yaml
@@ -19,5 +19,5 @@
 name: example-app-app-location
 location: localhost:(name=appLocalhost)
 services:
-- serviceType: brooklyn.cli.CliTest$ExampleEntity
+- serviceType: org.apache.brooklyn.cli.CliTest$ExampleEntity
   name: Example app
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/resources/example-app-entity-location.yaml
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/resources/example-app-entity-location.yaml b/usage/cli/src/test/resources/example-app-entity-location.yaml
index cbca856..5b2e466 100644
--- a/usage/cli/src/test/resources/example-app-entity-location.yaml
+++ b/usage/cli/src/test/resources/example-app-entity-location.yaml
@@ -18,6 +18,6 @@
 #
 name: example-app-entity-location
 services:
-- serviceType: brooklyn.cli.CliTest$ExampleEntity
+- serviceType: org.apache.brooklyn.cli.CliTest$ExampleEntity
   name: Example app
   location: localhost:(name=entityLocalhost)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/74ee6aac/usage/cli/src/test/resources/example-app-no-location.yaml
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/resources/example-app-no-location.yaml b/usage/cli/src/test/resources/example-app-no-location.yaml
index 9592e61..60cff1c 100644
--- a/usage/cli/src/test/resources/example-app-no-location.yaml
+++ b/usage/cli/src/test/resources/example-app-no-location.yaml
@@ -18,5 +18,5 @@
 #
 name: example-app-no-location
 services:
-- serviceType: brooklyn.cli.CliTest$ExampleEntity
+- serviceType: org.apache.brooklyn.cli.CliTest$ExampleEntity
   name: Example app



[15/20] incubator-brooklyn git commit: Package rename to org.apache.brooklyn: usage/camp/

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
new file mode 100644
index 0000000..e30f7f2
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
@@ -0,0 +1,188 @@
+/*
+ * 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.dsl;
+
+import io.brooklyn.camp.spi.resolve.PlanInterpreter;
+import io.brooklyn.camp.spi.resolve.PlanInterpreter.PlanInterpreterAdapter;
+import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
+import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode.Role;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.DslParser;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.FunctionWithArgs;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.parse.QuotedString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.javalang.Reflections;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Optional;
+
+/**
+ * {@link PlanInterpreter} which understands the $brooklyn DSL
+ */
+public class BrooklynDslInterpreter extends PlanInterpreterAdapter {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynDslInterpreter.class);
+
+    @Override
+    public boolean isInterestedIn(PlanInterpretationNode node) {
+        return node.matchesPrefix("$brooklyn:") || node.getNewValue() instanceof FunctionWithArgs;
+    }
+
+    private static ThreadLocal<PlanInterpretationNode> currentNode = new ThreadLocal<PlanInterpretationNode>();
+    /** returns the current node, stored in a thread-local, to populate the dsl field of {@link BrooklynDslDeferredSupplier} instances */
+    public static PlanInterpretationNode currentNode() {
+        return currentNode.get();
+    }
+    /** sets the current node */
+    public static void currentNode(PlanInterpretationNode node) {
+        currentNode.set(node);
+    }
+    public static void currentNodeClear() {
+        currentNode.set(null);
+    }
+    
+    @Override
+    public void applyYamlPrimitive(PlanInterpretationNode node) {
+        String expression = node.getNewValue().toString();
+
+        try {
+            currentNode.set(node);
+            Object parsedNode = new DslParser(expression).parse();
+            if ((parsedNode instanceof FunctionWithArgs) && ((FunctionWithArgs)parsedNode).getArgs()==null) {
+                if (node.getRoleInParent() == Role.MAP_KEY) {
+                    node.setNewValue(parsedNode);
+                    // will be handled later
+                } else {
+                    throw new IllegalStateException("Invalid function-only expression '"+((FunctionWithArgs)parsedNode).getFunction()+"'");
+                }
+            } else {
+                node.setNewValue( evaluate(parsedNode, true) );
+            }
+        } catch (Exception e) {
+            log.warn("Error evaluating node (rethrowing) '"+expression+"': "+e);
+            Exceptions.propagateIfFatal(e);
+            throw new IllegalArgumentException("Error evaluating node '"+expression+"'", e);
+        } finally {
+            currentNodeClear();
+        }
+    }
+    
+    @Override
+    public boolean applyMapEntry(PlanInterpretationNode node, Map<Object, Object> mapIn, Map<Object, Object> mapOut,
+            PlanInterpretationNode key, PlanInterpretationNode value) {
+        if (key.getNewValue() instanceof FunctionWithArgs) {
+            try {
+                currentNode.set(node);
+
+                FunctionWithArgs f = (FunctionWithArgs) key.getNewValue();
+                if (f.getArgs()!=null)
+                    throw new IllegalStateException("Invalid map key function "+f.getFunction()+"; should not have arguments if taking arguments from map");
+
+                // means evaluation acts on values
+                List<Object> args = new ArrayList<Object>();
+                if (value.getNewValue() instanceof Iterable<?>) {
+                    for (Object vi: (Iterable<?>)value.getNewValue())
+                        args.add(vi);
+                } else {
+                    args.add(value.getNewValue());
+                }
+
+                try {
+                    // TODO in future we should support functions of the form 'Maps.clear', 'Maps.reset', 'Maps.remove', etc;
+                    // default approach only supported if mapIn has single item and mapOut is empty
+                    if (mapIn.size()!=1) 
+                        throw new IllegalStateException("Map-entry DSL syntax only supported with single item in map, not "+mapIn);
+                    if (mapOut.size()!=0) 
+                        throw new IllegalStateException("Map-entry DSL syntax only supported with empty output map-so-far, not "+mapOut);
+
+                    node.setNewValue( evaluate(new FunctionWithArgs(f.getFunction(), args), false) );
+                    return false;
+                } catch (Exception e) {
+                    log.warn("Error evaluating map-entry (rethrowing) '"+f.getFunction()+args+"': "+e);
+                    Exceptions.propagateIfFatal(e);
+                    throw new IllegalArgumentException("Error evaluating map-entry '"+f.getFunction()+args+"'", e);
+                }
+
+            } finally {
+                currentNodeClear();
+            }
+        }
+        return super.applyMapEntry(node, mapIn, mapOut, key, value);
+    }
+
+    public Object evaluate(Object f, boolean deepEvaluation) {
+        if (f instanceof FunctionWithArgs) {
+            return evaluateOn(BrooklynDslCommon.class, (FunctionWithArgs) f, deepEvaluation);
+        }
+        
+        if (f instanceof List) {
+            Object o = BrooklynDslCommon.class;
+            for (Object i: (List<?>)f) {
+                o = evaluateOn( o, (FunctionWithArgs)i, deepEvaluation );
+            }
+            return o;
+        }
+
+        if (f instanceof QuotedString) {
+            return ((QuotedString)f).unwrapped();
+        }
+
+        throw new IllegalArgumentException("Unexpected element in parse tree: '"+f+"' (type "+(f!=null ? f.getClass() : null)+")");
+    }
+    
+    public Object evaluateOn(Object o, FunctionWithArgs f, boolean deepEvaluation) {
+        if (f.getArgs()==null)
+            throw new IllegalStateException("Invalid function-only expression '"+f.getFunction()+"'");
+
+        Class<?> clazz;
+        if (o instanceof Class) {
+            clazz = (Class<?>)o;
+        } else {
+            clazz = o.getClass();
+        }
+        if (!(clazz.getPackage().getName().startsWith(BrooklynDslCommon.class.getPackage().getName())))
+            throw new IllegalArgumentException("Not permitted to invoke function on '"+clazz+"' (outside allowed package scope)");
+        
+        String fn = f.getFunction();
+        fn = Strings.removeFromStart(fn, "$brooklyn:");
+        try {
+            List<Object> args = new ArrayList<Object>();
+            for (Object arg: f.getArgs()) {
+                args.add( deepEvaluation ? evaluate(arg, true) : arg );
+            }
+            Optional<Object> v = Reflections.invokeMethodWithArgs(o, fn, args);
+            if (v.isPresent()) return v.get();
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            throw Exceptions.propagate(new InvocationTargetException(e, "Error invoking '"+fn+"' on '"+o+"'"));
+        }
+        
+        throw new IllegalArgumentException("No such function '"+fn+"' on "+o);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
new file mode 100644
index 0000000..e5194bf
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslUtils.java
@@ -0,0 +1,44 @@
+/*
+ * 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.dsl;
+
+import brooklyn.util.task.DeferredSupplier;
+
+import com.google.common.collect.Iterables;
+
+public class DslUtils {
+
+    /** true iff none of the args are deferred / tasks */
+    public static boolean resolved(Iterable<Object> args) {
+        return resolved(Iterables.toArray(args, Object.class));
+    }
+
+    /** true iff none of the args are deferred / tasks */
+    public static boolean resolved(final Object... args) {
+        boolean allResolved = true;
+        for (Object arg: args) {
+            if (arg instanceof DeferredSupplier<?>) {
+                allResolved = false;
+                break;
+            }
+        }
+        return allResolved;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
new file mode 100644
index 0000000..37bc043
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -0,0 +1,301 @@
+/*
+ * 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.dsl.methods;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator;
+import org.apache.brooklyn.camp.brooklyn.spi.creation.EntitySpecConfiguration;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
+import org.apache.commons.beanutils.BeanUtils;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EntityDynamicType;
+import brooklyn.entity.trait.Configurable;
+import brooklyn.event.Sensor;
+import brooklyn.event.basic.DependentConfiguration;
+import brooklyn.management.Task;
+import brooklyn.management.TaskAdaptable;
+import brooklyn.management.TaskFactory;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.ClassCoercionException;
+import brooklyn.util.flags.FlagUtils;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.javalang.Reflections;
+import brooklyn.util.task.DeferredSupplier;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/** static import functions which can be used in `$brooklyn:xxx` contexts */
+public class BrooklynDslCommon {
+
+    // Access specific entities
+
+    public static DslComponent entity(String id) {
+        return new DslComponent(Scope.GLOBAL, id);
+    }
+    public static DslComponent parent() {
+        return new DslComponent(Scope.PARENT, null);
+    }
+    public static DslComponent child(String id) {
+        return new DslComponent(Scope.CHILD, id);
+    }
+    public static DslComponent sibling(String id) {
+        return new DslComponent(Scope.SIBLING, id);
+    }
+    public static DslComponent descendant(String id) {
+        return new DslComponent(Scope.DESCENDANT, id);
+    }
+    public static DslComponent ancestor(String id) {
+        return new DslComponent(Scope.ANCESTOR, id);
+    }
+    // prefer the syntax above to the below now, but not deprecating the below
+    public static DslComponent component(String id) {
+        return component("global", id);
+    }
+    public static DslComponent component(String scope, String id) {
+        if (!DslComponent.Scope.isValid(scope)) {
+            throw new IllegalArgumentException(scope + " is not a valid scope");
+        }
+        return new DslComponent(DslComponent.Scope.fromString(scope), id);
+    }
+
+    // Access things on entities
+
+    public static BrooklynDslDeferredSupplier<?> config(String keyName) {
+        return new DslComponent(Scope.THIS, "").config(keyName);
+    }
+
+    public static BrooklynDslDeferredSupplier<?> attributeWhenReady(String sensorName) {
+        return new DslComponent(Scope.THIS, "").attributeWhenReady(sensorName);
+    }
+
+    /** Returns a {@link Sensor}, looking up the sensor on the context if available and using that,
+     * or else defining an untyped (Object) sensor */
+    public static BrooklynDslDeferredSupplier<Sensor<?>> sensor(String sensorName) {
+        return new DslComponent(Scope.THIS, "").sensor(sensorName);
+    }
+    
+    /** Returns a {@link Sensor} declared on the type (e.g. entity class) declared in the first argument. */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static Sensor<?> sensor(String clazzName, String sensorName) {
+        try {
+            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
+            Class<?> clazz = Class.forName(clazzName);
+            Sensor<?> sensor;
+            if (Entity.class.isAssignableFrom(clazz)) {
+                sensor = new EntityDynamicType((Class<? extends Entity>) clazz).getSensor(sensorName);
+            } else {
+                // Some non-entity classes (e.g. ServiceRestarter policy) declare sensors that other
+                // entities/policies/enrichers may wish to reference.
+                Map<String,Sensor<?>> sensors = EntityDynamicType.findSensors((Class)clazz, null);
+                sensor = sensors.get(sensorName);
+            }
+            if (sensor == null) {
+                // TODO could extend API to return a sensor of the given type; useful but makes API ambiguous in theory (unlikely in practise, but still...)
+                throw new IllegalArgumentException("Sensor " + sensorName + " not found on class " + clazzName);
+            }
+            return sensor;
+        } catch (ClassNotFoundException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    // Build complex things
+
+    public static EntitySpecConfiguration entitySpec(Map<String, Object> arguments) {
+        return new EntitySpecConfiguration(arguments);
+    }
+
+    /**
+     * Return an instance of the specified class with its fields set according
+     * to the {@link Map} or a {@link BrooklynDslDeferredSupplier} if the arguments are not
+     * yet fully resolved.
+     */
+    @SuppressWarnings("unchecked")
+    public static Object object(Map<String, Object> arguments) {
+        ConfigBag config = ConfigBag.newInstance(arguments);
+        String typeName = BrooklynYamlTypeInstantiator.InstantiatorFromKey.extractTypeName("object", config).orNull();
+        Map<String,Object> objectFields = (Map<String, Object>) config.getStringKeyMaybe("object.fields").or(MutableMap.of());
+        Map<String,Object> brooklynConfig = (Map<String, Object>) config.getStringKeyMaybe(BrooklynCampReservedKeys.BROOKLYN_CONFIG).or(MutableMap.of());
+        try {
+            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
+            Class<?> type = Class.forName(typeName);
+            if (!Reflections.hasNoArgConstructor(type)) {
+                throw new IllegalStateException(String.format("Cannot construct %s bean: No public no-arg constructor available", type));
+            }
+            if ((objectFields.isEmpty() || DslUtils.resolved(objectFields.values())) &&
+                    (brooklynConfig.isEmpty() || DslUtils.resolved(brooklynConfig.values()))) {
+                return DslObject.create(type, objectFields, brooklynConfig);
+            } else {
+                return new DslObject(type, objectFields, brooklynConfig);
+            }
+        } catch (ClassNotFoundException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    // String manipulation
+
+    /** Return the expression as a literal string without any further parsing. */
+    public static Object literal(Object expression) {
+        return expression;
+    }
+
+    /**
+     * Returns a formatted string or a {@link BrooklynDslDeferredSupplier} if the arguments
+     * are not yet fully resolved.
+     */
+    public static Object formatString(final String pattern, final Object...args) {
+        if (DslUtils.resolved(args)) {
+            // if all args are resolved, apply the format string now
+            return String.format(pattern, args);
+        } else {
+            return new DslFormatString(pattern, args);
+        }
+    }
+
+    /**
+     * Deferred execution of String formatting.
+     *
+     * @see DependentConfiguration#formatString(String, Object...)
+     */
+    protected static class DslFormatString extends BrooklynDslDeferredSupplier<String> {
+
+        private static final long serialVersionUID = -4849297712650560863L;
+
+        private String pattern;
+        private Object[] args;
+
+        public DslFormatString(String pattern, Object ...args) {
+            this.pattern = pattern;
+            this.args = args;
+        }
+
+        @Override
+        public Task<String> newTask() {
+            return DependentConfiguration.formatString(pattern, args);
+        }
+
+        @Override
+        public String toString() {
+            return "$brooklyn:formatString("+
+                JavaStringEscapes.wrapJavaString(pattern)+
+                (args==null || args.length==0 ? "" : ","+Strings.join(args, ","))+")";
+        }
+    }
+
+    /** @deprecated since 0.7.0; use {@link DslFormatString} */
+    @SuppressWarnings("serial")
+    @Deprecated
+    protected static class FormatString extends DslFormatString {
+        public FormatString(String pattern, Object[] args) {
+            super(pattern, args);
+        }
+    }
+
+    /** Deferred execution of Object creation. */
+    protected static class DslObject extends BrooklynDslDeferredSupplier<Object> {
+
+        private static final long serialVersionUID = 8878388748085419L;
+
+        private Class<?> type;
+        private Map<String,Object> fields, config;
+
+        public DslObject(Class<?> type, Map<String,Object> fields,  Map<String,Object> config) {
+            this.type = type;
+            this.fields = MutableMap.copyOf(fields);
+            this.config = MutableMap.copyOf(config);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Task<Object> newTask() {
+            List<TaskAdaptable<Object>> tasks = Lists.newLinkedList();
+            for (Object value : Iterables.concat(fields.values(), config.values())) {
+                if (value instanceof TaskAdaptable) {
+                    tasks.add((TaskAdaptable<Object>) value);
+                } else if (value instanceof TaskFactory) {
+                    tasks.add(((TaskFactory<TaskAdaptable<Object>>) value).newTask());
+                }
+            }
+            Map<String,?> flags = MutableMap.<String,String>of("displayName", "building '"+type+"' with "+tasks.size()+" task"+(tasks.size()!=1?"s":""));
+            return DependentConfiguration.transformMultiple(flags, new Function<List<Object>, Object>() {
+                        @Override
+                        public Object apply(List<Object> input) {
+                            Iterator<Object> values = input.iterator();
+                            for (String name : fields.keySet()) {
+                                Object value = fields.get(name);
+                                if (value instanceof TaskAdaptable || value instanceof TaskFactory) {
+                                    fields.put(name, values.next());
+                                } else if (value instanceof DeferredSupplier) {
+                                    fields.put(name, ((DeferredSupplier<?>) value).get());
+                                }
+                            }
+                            for (String name : config.keySet()) {
+                                Object value = config.get(name);
+                                if (value instanceof TaskAdaptable || value instanceof TaskFactory) {
+                                    config.put(name, values.next());
+                                } else if (value instanceof DeferredSupplier) {
+                                    config.put(name, ((DeferredSupplier<?>) value).get());
+                                }
+                            }
+                            return create(type, fields, config);
+                        }
+                    }, tasks);
+        }
+
+        public static <T> T create(Class<T> type, Map<String,?> fields, Map<String,?> config) {
+            try {
+                T bean;
+                try {
+                    bean = (T) TypeCoercions.coerce(fields, type);
+                } catch (ClassCoercionException ex) {
+                    bean = Reflections.invokeConstructorWithArgs(type).get();
+                    BeanUtils.populate(bean, fields);
+                }
+                if (bean instanceof Configurable && config.size() > 0) {
+                    ConfigBag brooklyn = ConfigBag.newInstance(config);
+                    FlagUtils.setFieldsFromFlags(bean, brooklyn);
+                    FlagUtils.setAllConfigKeys((Configurable) bean, brooklyn, true);
+                }
+                return bean;
+            } catch (Exception e) {
+                throw Exceptions.propagate(e);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "$brooklyn:object(\""+type.getName()+"\")";
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
new file mode 100644
index 0000000..4801a41
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -0,0 +1,320 @@
+/*
+ * 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.dsl.methods;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityPredicates;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.Sensor;
+import brooklyn.event.basic.DependentConfiguration;
+import brooklyn.event.basic.Sensors;
+import brooklyn.management.Task;
+import brooklyn.management.internal.EntityManagerInternal;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.task.TaskBuilder;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
+
+    private static final long serialVersionUID = -7715984495268724954L;
+    
+    private final String componentId;
+    private final DslComponent scopeComponent;
+    private final Scope scope;
+
+    public DslComponent(String componentId) {
+        this(Scope.GLOBAL, componentId);
+    }
+    
+    public DslComponent(Scope scope, String componentId) {
+        this(null, scope, componentId);
+    }
+    
+    public DslComponent(DslComponent scopeComponent, Scope scope, String componentId) {
+        Preconditions.checkNotNull(scope, "scope");
+        this.scopeComponent = scopeComponent;
+        this.componentId = componentId;
+        this.scope = scope;
+    }
+
+    // ---------------------------
+    
+    @Override
+    public Task<Entity> newTask() {
+        return TaskBuilder.<Entity>builder().name(toString()).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG)
+            .body(new EntityInScopeFinder(scopeComponent, scope, componentId)).build();
+    }
+    
+    protected static class EntityInScopeFinder implements Callable<Entity> {
+        protected final DslComponent scopeComponent;
+        protected final Scope scope;
+        protected final String componentId;
+
+        public EntityInScopeFinder(DslComponent scopeComponent, Scope scope, String componentId) {
+            this.scopeComponent = scopeComponent;
+            this.scope = scope;
+            this.componentId = componentId;
+        }
+
+        protected EntityInternal getEntity() {
+            if (scopeComponent!=null) {
+                return (EntityInternal)scopeComponent.get();
+            } else {
+                return entity();
+            }
+        }
+        
+        @Override
+        public Entity call() throws Exception {
+            Iterable<Entity> entitiesToSearch = null;
+            switch (scope) {
+                case THIS:
+                    return getEntity();
+                case PARENT:
+                    return getEntity().getParent();
+                case GLOBAL:
+                    entitiesToSearch = ((EntityManagerInternal)getEntity().getManagementContext().getEntityManager())
+                        .getAllEntitiesInApplication( entity().getApplication() );
+                    break;
+                case DESCENDANT:
+                    entitiesToSearch = Entities.descendants(getEntity());
+                    break;
+                case ANCESTOR:
+                    entitiesToSearch = Entities.ancestors(getEntity());
+                    break;
+                case SIBLING:
+                    entitiesToSearch = getEntity().getParent().getChildren();
+                    break;
+                case CHILD:
+                    entitiesToSearch = getEntity().getChildren();
+                    break;
+                default:
+                    throw new IllegalStateException("Unexpected scope "+scope);
+            }
+            
+            Optional<Entity> result = Iterables.tryFind(entitiesToSearch, EntityPredicates.configEqualTo(BrooklynCampConstants.PLAN_ID, componentId));
+            
+            if (result.isPresent())
+                return result.get();
+            
+            // TODO may want to block and repeat on new entities joining?
+            throw new NoSuchElementException("No entity matching id " + componentId+
+                (scope==Scope.GLOBAL ? "" : ", in scope "+scope+" wrt "+getEntity()+
+                (scopeComponent!=null ? " ("+scopeComponent+" from "+entity()+")" : "")));
+        }        
+    }
+    
+    // -------------------------------
+
+    // DSL words which move to a new component
+    
+    public DslComponent entity(String scopeOrId) {
+        return new DslComponent(this, Scope.GLOBAL, scopeOrId);
+    }
+    public DslComponent child(String scopeOrId) {
+        return new DslComponent(this, Scope.CHILD, scopeOrId);
+    }
+    public DslComponent sibling(String scopeOrId) {
+        return new DslComponent(this, Scope.SIBLING, scopeOrId);
+    }
+    public DslComponent descendant(String scopeOrId) {
+        return new DslComponent(this, Scope.DESCENDANT, scopeOrId);
+    }
+    public DslComponent ancestor(String scopeOrId) {
+        return new DslComponent(this, Scope.ANCESTOR, scopeOrId);
+    }
+    
+    @Deprecated /** @deprecated since 0.7.0 */
+    public DslComponent component(String scopeOrId) {
+        return new DslComponent(this, Scope.GLOBAL, scopeOrId);
+    }
+    
+    public DslComponent parent() {
+        return new DslComponent(this, Scope.PARENT, "");
+    }
+    
+    public DslComponent component(String scope, String id) {
+        if (!DslComponent.Scope.isValid(scope)) {
+            throw new IllegalArgumentException(scope + " is not a vlaid scope");
+        }
+        return new DslComponent(this, DslComponent.Scope.fromString(scope), id);
+    }
+
+    // DSL words which return things
+    
+    public BrooklynDslDeferredSupplier<?> attributeWhenReady(final String sensorName) {
+        return new AttributeWhenReady(this, sensorName);
+    }
+    // class simply makes the memento XML files nicer
+    protected static class AttributeWhenReady extends BrooklynDslDeferredSupplier<Object> {
+        private static final long serialVersionUID = 1740899524088902383L;
+        private final DslComponent component;
+        private final String sensorName;
+        public AttributeWhenReady(DslComponent component, String sensorName) {
+            this.component = Preconditions.checkNotNull(component);
+            this.sensorName = sensorName;
+        }
+        @SuppressWarnings("unchecked")
+        @Override
+        public Task<Object> newTask() {
+            Entity targetEntity = component.get();
+            Sensor<?> targetSensor = targetEntity.getEntityType().getSensor(sensorName);
+            if (!(targetSensor instanceof AttributeSensor<?>)) {
+                targetSensor = Sensors.newSensor(Object.class, sensorName);
+            }
+            return (Task<Object>) DependentConfiguration.attributeWhenReady(targetEntity, (AttributeSensor<?>)targetSensor);
+        }
+        @Override
+        public String toString() {
+            return (component.scope==Scope.THIS ? "" : component.toString()+".") +
+                "attributeWhenReady("+JavaStringEscapes.wrapJavaString(sensorName)+")";
+        }
+    }
+
+    public BrooklynDslDeferredSupplier<?> config(final String keyName) {
+        return new DslConfigSupplier(this, keyName);
+    }
+    protected final static class DslConfigSupplier extends BrooklynDslDeferredSupplier<Object> {
+        private final DslComponent component;
+        private final String keyName;
+        private static final long serialVersionUID = -4735177561947722511L;
+
+        public DslConfigSupplier(DslComponent component, String keyName) {
+            this.component = Preconditions.checkNotNull(component);
+            this.keyName = keyName;
+        }
+
+        @Override
+        public Task<Object> newTask() {
+            return Tasks.builder().name("retrieving config for "+keyName).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG).dynamic(false).body(new Callable<Object>() {
+                @Override
+                public Object call() throws Exception {
+                    Entity targetEntity = component.get();
+                    return targetEntity.getConfig(ConfigKeys.newConfigKey(Object.class, keyName));
+                }
+            }).build();
+        }
+
+        @Override
+        public String toString() {
+            return (component.scope==Scope.THIS ? "" : component.toString()+".") + 
+                "config("+JavaStringEscapes.wrapJavaString(keyName)+")";
+        }
+    }
+    
+    public BrooklynDslDeferredSupplier<Sensor<?>> sensor(final String sensorName) {
+        return new DslSensorSupplier(this, sensorName);
+    }
+    protected final static class DslSensorSupplier extends BrooklynDslDeferredSupplier<Sensor<?>> {
+        private final DslComponent component;
+        private final String sensorName;
+        private static final long serialVersionUID = -4735177561947722511L;
+
+        public DslSensorSupplier(DslComponent component, String sensorName) {
+            this.component = Preconditions.checkNotNull(component);
+            this.sensorName = sensorName;
+        }
+
+        @Override
+        public Task<Sensor<?>> newTask() {
+            return Tasks.<Sensor<?>>builder().name("looking up sensor for "+sensorName).dynamic(false).body(new Callable<Sensor<?>>() {
+                @Override
+                public Sensor<?> call() throws Exception {
+                    Entity targetEntity = component.get();
+                    Sensor<?> result = null;
+                    if (targetEntity!=null) {
+                        result = targetEntity.getEntityType().getSensor(sensorName);
+                    }
+                    if (result!=null) return result;
+                    return Sensors.newSensor(Object.class, sensorName);
+                }
+            }).build();
+        }
+
+        @Override
+        public String toString() {
+            return (component.scope==Scope.THIS ? "" : component.toString()+".") + 
+                "sensor("+JavaStringEscapes.wrapJavaString(sensorName)+")";
+        }
+    }
+
+    public static enum Scope {
+        GLOBAL ("global"),
+        CHILD ("child"),
+        PARENT ("parent"),
+        SIBLING ("sibling"),
+        DESCENDANT ("descendant"),
+        ANCESTOR("ancestor"),
+        THIS ("this");
+        
+        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, THIS);
+        
+        private final String name;
+        
+        private Scope(String name) {
+            this.name = name;
+        }
+        
+        public static Scope fromString(String name) {
+            return tryFromString(name).get();
+        }
+        
+        public static Maybe<Scope> tryFromString(String name) {
+            for (Scope scope : VALUES)
+                if (scope.name.toLowerCase().equals(name.toLowerCase()))
+                    return Maybe.of(scope);
+            return Maybe.absent(new IllegalArgumentException(name + " is not a valid scope"));
+        }
+        
+        public static boolean isValid(String name) {
+            for (Scope scope : VALUES)
+                if (scope.name.toLowerCase().equals(name.toLowerCase()))
+                    return true;
+            return false;
+        }
+    }
+
+
+    @Override
+    public String toString() {
+        return "$brooklyn:entity("+
+            (scopeComponent==null ? "" : JavaStringEscapes.wrapJavaString(scopeComponent.toString())+", ")+
+            (scope==Scope.GLOBAL ? "" : JavaStringEscapes.wrapJavaString(scope.toString())+", ")+
+            JavaStringEscapes.wrapJavaString(componentId)+
+            ")";
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
new file mode 100644
index 0000000..345de05
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java
@@ -0,0 +1,144 @@
+/*
+ * 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.dsl.parse;
+
+import java.util.Collection;
+import java.util.List;
+
+import brooklyn.util.collections.MutableList;
+
+public class DslParser {
+    private final String expression;
+    int index = -1;
+    
+    public DslParser(String expression) {
+        this.expression = expression;
+    }
+    
+    public synchronized Object parse() {
+        if (index>=0)
+            throw new IllegalStateException("Parser can only be used once");
+        
+        index++;
+        Object result = next();
+        
+        if (index < expression.length())
+            throw new IllegalStateException("Unexpected character at position "+index+" in "+expression);
+        
+        return result;
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Object next() {
+        int start = index;
+        
+        skipWhitespace();
+        if (index >= expression.length())
+            throw new IllegalStateException("Unexpected end of expression to parse, looking for content since position "+start);
+        
+        if (expression.charAt(index)=='"') {
+            // assume a string
+            int stringStart = index;
+            index++;
+            do {
+                if (index >= expression.length())
+                    throw new IllegalStateException("Unexpected end of expression to parse, looking for close quote since position "+stringStart);
+                char c = expression.charAt(index);
+                if (c=='"') break;
+                if (c=='\\') index++;
+                index++;
+            } while (true);
+            index++;
+            return new QuotedString(expression.substring(stringStart, index));
+        }
+
+        // not a string, must be a function (or chain thereof)
+        List<FunctionWithArgs> result = new MutableList<FunctionWithArgs>();
+
+        int fnStart = index;
+        do {
+            if (index >= expression.length())
+                break;
+            char c = expression.charAt(index);
+            if (Character.isJavaIdentifierPart(c)) ;
+            // these chars also permitted
+            else if (".:".indexOf(c)>=0) ;
+            // other things e.g. whitespace, parentheses, etc, skip
+            else break;
+            index++;
+        } while (true);
+        String fn = expression.substring(fnStart, index);
+        if (fn.length()==0)
+            throw new IllegalStateException("Expected a function name at position "+start);
+        skipWhitespace();
+        
+        if (index < expression.length() && expression.charAt(index)=='(') {
+            // collect arguments
+            int parenStart = index;
+            List<Object> args = new MutableList<Object>();
+            index ++;
+            do {
+                skipWhitespace();
+                if (index >= expression.length())
+                    throw new IllegalStateException("Unexpected end of arguments to function '"+fn+"', no close parenthesis matching character at position "+parenStart);
+                char c = expression.charAt(index);
+                if (c==')') break;
+                if (c==',') {
+                    if (args.isEmpty())
+                        throw new IllegalStateException("Invalid character at position"+index);
+                    index++;
+                } else {
+                    if (!args.isEmpty())
+                        throw new IllegalStateException("Expected , before position"+index);
+                }
+                args.add(next());
+            } while (true);
+            result.add(new FunctionWithArgs(fn, args));
+            index++;
+            skipWhitespace();
+            if (index >= expression.length())
+                return result;
+            char c = expression.charAt(index);
+            if (c=='.') {
+                // chained expression
+                int chainStart = index;
+                index++;
+                Object next = next();
+                if (next instanceof List) {
+                    result.addAll((Collection<? extends FunctionWithArgs>) next);
+                    return result;
+                } else {
+                    throw new IllegalStateException("Expected functions following position"+chainStart);
+                }
+            } else {
+                // following word not something handled at this level; assume parent will handle (or throw) - e.g. a , or extra )
+                return result;
+            }
+        } else {
+            // it is just a word; return it with args as null
+            return new FunctionWithArgs(fn, null);
+        }
+    }
+
+    private void skipWhitespace() {
+        while (index<expression.length() && Character.isWhitespace(expression.charAt(index)))
+            index++;
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
new file mode 100644
index 0000000..41bc837
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/FunctionWithArgs.java
@@ -0,0 +1,57 @@
+/*
+ * 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.dsl.parse;
+
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+
+public class FunctionWithArgs {
+    private final String function;
+    private final List<Object> args;
+    
+    public FunctionWithArgs(String function, List<Object> args) {
+        this.function = function;
+        this.args = args==null ? null : ImmutableList.copyOf(args);
+    }
+    
+    public String getFunction() {
+        return function;
+    }
+    
+    /**
+     * arguments (typically {@link QuotedString} or more {@link FunctionWithArgs}).
+     * 
+     * null means it is a function in a map key which expects map value to be the arguments -- specified without parentheses;
+     * empty means parentheses already applied, with 0 args.
+     */
+    public List<Object> getArgs() {
+        return args;
+    }
+    
+    @Override
+    public String toString() {
+        return function+(args==null ? "" : args);
+    }
+
+    public Object arg(int i) {
+        return args.get(i);
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
new file mode 100644
index 0000000..8076bfb
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/QuotedString.java
@@ -0,0 +1,49 @@
+/*
+ * 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.dsl.parse;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+
+import com.google.common.base.Objects;
+
+public class QuotedString {
+    private final String s;
+    
+    public QuotedString(String s) {
+        this.s = checkNotNull(s, "string");
+    }
+    @Override
+    public String toString() {
+        return s;
+    }
+    public String unwrapped() {
+        return JavaStringEscapes.unwrapJavaString(s);
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof QuotedString) && ((QuotedString)obj).toString().equals(toString());
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(s);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.java
new file mode 100644
index 0000000..6f4670d
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractBrooklynResourceLookup.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.spi.lookup;
+
+import io.brooklyn.camp.spi.AbstractResource;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.AbstractResourceLookup;
+import brooklyn.management.ManagementContext;
+
+public abstract class AbstractBrooklynResourceLookup<T extends AbstractResource>  extends AbstractResourceLookup<T> {
+
+    protected final PlatformRootSummary root;
+    protected final ManagementContext bmc;
+
+    public AbstractBrooklynResourceLookup(PlatformRootSummary root, ManagementContext bmc) {
+        this.root = root;
+        this.bmc = bmc;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
new file mode 100644
index 0000000..b7a276c
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AbstractTemplateBrooklynLookup.java
@@ -0,0 +1,62 @@
+/*
+ * 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.lookup;
+
+import io.brooklyn.camp.spi.AbstractResource;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.internal.CatalogUtils;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
+
+public abstract class AbstractTemplateBrooklynLookup<T extends AbstractResource>  extends AbstractBrooklynResourceLookup<T> {
+
+    private static final Logger log = LoggerFactory.getLogger(AbstractTemplateBrooklynLookup.class);
+    
+    public AbstractTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
+        super(root, bmc);
+    }
+
+    @Override
+    public T get(String id) {
+        CatalogItem<?,?> item = getCatalogItem(id);
+        if (item==null) {
+            log.warn("Could not find item '"+id+"' in Brooklyn catalog; returning null");
+            return null;
+        }
+        return adapt(item);
+    }
+
+    private CatalogItem<?, ?> getCatalogItem(String versionedId) {
+        return CatalogUtils.getCatalogItemOptionalVersion(bmc, versionedId);
+    }
+
+    public abstract T adapt(CatalogItem<?,?> item);
+
+    protected ResolvableLink<T> newLink(CatalogItem<? extends Entity,EntitySpec<?>> li) {
+        return newLink(li.getId(), li.getDisplayName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
new file mode 100644
index 0000000..e3130e0
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyBrooklynLookup.java
@@ -0,0 +1,69 @@
+/*
+ * 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.lookup;
+
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.management.ManagementContext;
+
+
+public class AssemblyBrooklynLookup extends AbstractBrooklynResourceLookup<Assembly> {
+
+    private PlatformComponentBrooklynLookup pcs;
+
+    public AssemblyBrooklynLookup(PlatformRootSummary root, ManagementContext bmc, PlatformComponentBrooklynLookup pcs) {
+        super(root, bmc);
+        this.pcs = pcs;
+    }
+
+    @Override
+    public Assembly get(String id) {
+        Entity entity = bmc.getEntityManager().getEntity(id);
+        if (!(entity instanceof Application))
+            throw new IllegalArgumentException("Element for "+id+" is not an Application ("+entity+")");
+        Assembly.Builder<? extends Assembly> builder = Assembly.builder()
+                .created(new Date(entity.getCreationTime()))
+                .id(entity.getId())
+                .name(entity.getDisplayName());
+        
+        builder.customAttribute("externalManagementUri", BrooklynUrlLookup.getUrl(bmc, entity));
+        
+        for (Entity child: entity.getChildren())
+            // FIXME this walks the whole damn tree!
+            builder.add( pcs.get(child.getId() ));
+        return builder.build();
+    }
+
+    @Override
+    public List<ResolvableLink<Assembly>> links() {
+        List<ResolvableLink<Assembly>> result = new ArrayList<ResolvableLink<Assembly>>();
+        for (Application app: bmc.getApplications())
+            result.add(newLink(app.getId(), app.getDisplayName()));
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
new file mode 100644
index 0000000..1e0d6a1
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/AssemblyTemplateBrooklynLookup.java
@@ -0,0 +1,70 @@
+/*
+ * 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.lookup;
+
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
+
+public class AssemblyTemplateBrooklynLookup extends AbstractTemplateBrooklynLookup<AssemblyTemplate> {
+
+    public AssemblyTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
+        super(root, bmc);
+    }
+
+    @Override
+    public AssemblyTemplate adapt(CatalogItem<?,?> item) {
+        return AssemblyTemplate.builder().
+                name(item.getDisplayName()).
+                id(item.getId()).
+                description(item.getDescription()).
+                created(root.getCreated()).
+                instantiator(BrooklynAssemblyTemplateInstantiator.class).
+                build();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    // why can I not pass an EntitySpec<? extends Application> to    newLink(EntitySpec<?> spec)  ?
+    // feels to me (alexheneveld) that `? extends Application` should be both covariant and contravariant to `?` ..
+    // but it's not, so we introduce this conversion method
+    protected ResolvableLink<AssemblyTemplate> newApplicationLink(CatalogItem<? extends Entity, EntitySpec<? extends Application>> li) {
+        return super.newLink((CatalogItem)li);
+    }
+    
+    @Override
+    public List<ResolvableLink<AssemblyTemplate>> links() {
+        Iterable<CatalogItem<Application,EntitySpec<? extends Application>>> l = bmc.getCatalog().getCatalogItems(CatalogPredicates.IS_TEMPLATE);
+        List<ResolvableLink<AssemblyTemplate>> result = new ArrayList<ResolvableLink<AssemblyTemplate>>();
+        for (CatalogItem<Application,EntitySpec<? extends Application>> li: l)
+            result.add(newApplicationLink(li));
+        return result;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
new file mode 100644
index 0000000..f9bc390
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/BrooklynUrlLookup.java
@@ -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.
+ */
+package org.apache.brooklyn.camp.brooklyn.spi.lookup;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.management.ManagementContext;
+import brooklyn.util.net.Urls;
+
+public class BrooklynUrlLookup {
+
+    public static ConfigKey<String> BROOKLYN_ROOT_URL = ConfigKeys.newStringConfigKey("brooklyn.root.url");
+    
+    public static String getUrl(ManagementContext bmc, Entity entity) {
+        String root = bmc.getConfig().getConfig(BROOKLYN_ROOT_URL);
+        if (root==null) return null;
+        return Urls.mergePaths(root, "#/", 
+                "/v1/applications/"+entity.getApplicationId()+"/entities/"+entity.getId());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
new file mode 100644
index 0000000..6b26849
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentBrooklynLookup.java
@@ -0,0 +1,61 @@
+/*
+ * 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.lookup;
+
+import io.brooklyn.camp.spi.PlatformComponent;
+import io.brooklyn.camp.spi.PlatformComponent.Builder;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import brooklyn.entity.Entity;
+import brooklyn.management.ManagementContext;
+
+
+public class PlatformComponentBrooklynLookup extends AbstractBrooklynResourceLookup<PlatformComponent> {
+
+    public PlatformComponentBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
+        super(root, bmc);
+    }
+
+    @Override
+    public PlatformComponent get(String id) {
+        Entity entity = bmc.getEntityManager().getEntity(id);
+        Builder<? extends PlatformComponent> builder = PlatformComponent.builder()
+            .created(new Date(entity.getCreationTime()))
+            .id(entity.getId())
+            .name(entity.getDisplayName())
+            .externalManagementUri(BrooklynUrlLookup.getUrl(bmc, entity));
+        
+        for (Entity child: entity.getChildren())
+            // FIXME this walks the whole damn tree!
+            builder.add( get(child.getId() ));
+        return builder.build();
+    }
+
+    // platform components are not listed at the top level -- you have to walk the assemblies
+    @Override
+    public List<ResolvableLink<PlatformComponent>> links() {
+        return Collections.emptyList();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
new file mode 100644
index 0000000..b990464
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/lookup/PlatformComponentTemplateBrooklynLookup.java
@@ -0,0 +1,59 @@
+/*
+ * 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.lookup;
+
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.collection.ResolvableLink;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.brooklyn.catalog.CatalogItem;
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.entity.Entity;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.management.ManagementContext;
+
+public class PlatformComponentTemplateBrooklynLookup extends AbstractTemplateBrooklynLookup<PlatformComponentTemplate> {
+
+    public PlatformComponentTemplateBrooklynLookup(PlatformRootSummary root, ManagementContext bmc) {
+        super(root, bmc);
+    }
+
+    @Override
+    public PlatformComponentTemplate adapt(CatalogItem<?,?> item) {
+        return PlatformComponentTemplate.builder().
+                name(item.getDisplayName()).
+                id(item.getId()).
+                description(item.getDescription()).
+                created(root.getCreated()).
+                build();
+    }
+
+    @Override
+    public List<ResolvableLink<PlatformComponentTemplate>> links() {
+        Iterable<CatalogItem<Entity,EntitySpec<?>>> l = bmc.getCatalog().getCatalogItems(CatalogPredicates.IS_ENTITY);
+        List<ResolvableLink<PlatformComponentTemplate>> result = new ArrayList<ResolvableLink<PlatformComponentTemplate>>();
+        for (CatalogItem<Entity,EntitySpec<?>> li: l)
+            result.add(newLink(li));
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
new file mode 100644
index 0000000..c04c134
--- /dev/null
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/platform/BrooklynImmutableCampPlatform.java
@@ -0,0 +1,109 @@
+/*
+ * 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.platform;
+
+import io.brooklyn.camp.CampPlatform;
+import io.brooklyn.camp.spi.ApplicationComponent;
+import io.brooklyn.camp.spi.ApplicationComponentTemplate;
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.PlatformComponent;
+import io.brooklyn.camp.spi.PlatformComponentTemplate;
+import io.brooklyn.camp.spi.PlatformRootSummary;
+import io.brooklyn.camp.spi.PlatformTransaction;
+import io.brooklyn.camp.spi.collection.BasicResourceLookup;
+import io.brooklyn.camp.spi.collection.ResourceLookup;
+import io.brooklyn.camp.spi.collection.ResourceLookup.EmptyResourceLookup;
+
+import org.apache.brooklyn.camp.brooklyn.spi.lookup.AssemblyBrooklynLookup;
+import org.apache.brooklyn.camp.brooklyn.spi.lookup.AssemblyTemplateBrooklynLookup;
+import org.apache.brooklyn.camp.brooklyn.spi.lookup.PlatformComponentBrooklynLookup;
+import org.apache.brooklyn.camp.brooklyn.spi.lookup.PlatformComponentTemplateBrooklynLookup;
+
+import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+import brooklyn.management.ManagementContext;
+
+/** Immutable CAMP platform which reflects things in the underlying Brooklyn system */
+public class BrooklynImmutableCampPlatform extends CampPlatform implements HasBrooklynManagementContext {
+
+    private final ManagementContext bmc;
+    private final AssemblyTemplateBrooklynLookup ats;
+    private final PlatformComponentTemplateBrooklynLookup pcts;
+    private final BasicResourceLookup<ApplicationComponentTemplate> acts;
+    private final PlatformComponentBrooklynLookup pcs;
+    private final AssemblyBrooklynLookup assemblies;
+
+    public BrooklynImmutableCampPlatform(PlatformRootSummary root, ManagementContext managementContext) {
+        super(root);
+        this.bmc = managementContext;
+        
+        // these come from brooklyn
+        pcts = new PlatformComponentTemplateBrooklynLookup(root(), getBrooklynManagementContext());
+        ats = new AssemblyTemplateBrooklynLookup(root(), getBrooklynManagementContext());
+        pcs = new PlatformComponentBrooklynLookup(root(), getBrooklynManagementContext());
+        assemblies = new AssemblyBrooklynLookup(root(), getBrooklynManagementContext(), pcs);
+        
+        // ACT's are not known in brooklyn (everything comes in as config) -- to be extended to support!
+        acts = new BasicResourceLookup<ApplicationComponentTemplate>();
+    }
+
+    // --- brooklyn setup
+    
+    public ManagementContext getBrooklynManagementContext() {
+        return bmc;
+    }
+    
+    // --- camp comatibility setup
+    
+    @Override
+    public ResourceLookup<PlatformComponentTemplate> platformComponentTemplates() {
+        return pcts;
+    }
+
+    @Override
+    public ResourceLookup<ApplicationComponentTemplate> applicationComponentTemplates() {
+        return acts;
+    }
+
+    @Override
+    public ResourceLookup<AssemblyTemplate> assemblyTemplates() {
+        return ats;
+    }
+    
+    @Override
+    public ResourceLookup<PlatformComponent> platformComponents() {
+        return pcs;
+    }
+
+    @Override
+    public ResourceLookup<ApplicationComponent> applicationComponents() {
+        return new EmptyResourceLookup<ApplicationComponent>();
+    }
+
+    @Override
+    public ResourceLookup<Assembly> assemblies() {
+        return assemblies;
+    }
+    
+    @Override
+    public PlatformTransaction transaction() {
+        throw new IllegalStateException(this+" does not support adding new items");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver b/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
deleted file mode 100644
index 1a48ccb..0000000
--- a/usage/camp/src/main/resources/META-INF/services/io.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
+++ /dev/null
@@ -1,22 +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.
-#
-io.brooklyn.camp.brooklyn.spi.creation.service.BrooklynServiceTypeResolver
-io.brooklyn.camp.brooklyn.spi.creation.service.CatalogServiceTypeResolver
-io.brooklyn.camp.brooklyn.spi.creation.service.ChefServiceTypeResolver
-io.brooklyn.camp.brooklyn.spi.creation.service.JavaServiceTypeResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver b/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
new file mode 100644
index 0000000..9c941df
--- /dev/null
+++ b/usage/camp/src/main/resources/META-INF/services/org.apache.brooklyn.camp.brooklyn.spi.creation.service.ServiceTypeResolver
@@ -0,0 +1,22 @@
+#
+# 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.service.BrooklynServiceTypeResolver
+org.apache.brooklyn.camp.brooklyn.spi.creation.service.CatalogServiceTypeResolver
+org.apache.brooklyn.camp.brooklyn.spi.creation.service.ChefServiceTypeResolver
+org.apache.brooklyn.camp.brooklyn.spi.creation.service.JavaServiceTypeResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e406d1ad/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
deleted file mode 100644
index 226ec67..0000000
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
+++ /dev/null
@@ -1,206 +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 io.brooklyn.camp.brooklyn;
-
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.rebind.RebindOptions;
-import brooklyn.entity.rebind.RebindTestFixture;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.Task;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplication> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractYamlTest.class);
-    protected static final String TEST_VERSION = "0.1.2";
-
-    protected BrooklynCampPlatform platform;
-    protected BrooklynCampPlatformLauncherNoServer launcher;
-    private boolean forceUpdate;
-    
-    @BeforeMethod(alwaysRun = true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        launcher = new BrooklynCampPlatformLauncherNoServer() {
-            @Override
-            protected LocalManagementContext newMgmtContext() {
-                return (LocalManagementContext) mgmt();
-            }
-        };
-        launcher.launch();
-        platform = launcher.getCampPlatform();
-    }
-
-    @AfterMethod(alwaysRun = true)
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            super.tearDown();
-        } finally {
-            if (launcher != null) launcher.stopServers();
-        }
-    }
-
-    protected StartableApplication rebind(RebindOptions options) throws Exception {
-        StartableApplication result = super.rebind(options);
-        if (launcher != null) {
-            launcher.stopServers();
-            launcher = new BrooklynCampPlatformLauncherNoServer() {
-                @Override
-                protected LocalManagementContext newMgmtContext() {
-                    return (LocalManagementContext) mgmt();
-                }
-            };
-            launcher.launch();
-            platform = launcher.getCampPlatform();
-        }
-        return result;
-    }
-    
-    @Override
-    protected StartableApplication createApp() {
-        return null;
-    }
-
-    protected ManagementContext mgmt() {
-        return (newManagementContext != null) ? newManagementContext : origManagementContext;
-    }
-    
-    ///////////////////////////////////////////////////
-    // TODO code below is duplicate of AbstractYamlTest
-    ///////////////////////////////////////////////////
-    
-    protected void waitForApplicationTasks(Entity app) {
-        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(origManagementContext.getExecutionManager(), app);
-        getLogger().info("Waiting on " + tasks.size() + " task(s)");
-        for (Task<?> t : tasks) {
-            t.blockUntilEnded();
-        }
-    }
-
-    protected Reader loadYaml(String yamlFileName, String ...extraLines) throws Exception {
-        String input = new ResourceUtils(this).getResourceAsString(yamlFileName).trim();
-        StringBuilder builder = new StringBuilder(input);
-        for (String l: extraLines)
-            builder.append("\n").append(l);
-        return new StringReader(builder.toString());
-    }
-    
-    protected Entity createAndStartApplication(String... multiLineYaml) throws Exception {
-        return createAndStartApplication(joinLines(multiLineYaml));
-    }
-    
-    protected Entity createAndStartApplication(String input) throws Exception {
-        return createAndStartApplication(new StringReader(input));
-    }
-
-    protected Entity createAndStartApplication(Reader input) throws Exception {
-        AssemblyTemplate at = platform.pdp().registerDeploymentPlan(input);
-        Assembly assembly;
-        try {
-            assembly = at.getInstantiator().newInstance().instantiate(at, platform);
-        } catch (Exception e) {
-            getLogger().warn("Unable to instantiate " + at + " (rethrowing): " + e);
-            throw e;
-        }
-        getLogger().info("Test - created " + assembly);
-        final Entity app = origManagementContext.getEntityManager().getEntity(assembly.getId());
-        getLogger().info("App - " + app);
-        
-        // wait for app to have started
-        Set<Task<?>> tasks = origManagementContext.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
-                BrooklynTaskTags.EFFECTOR_TAG, 
-                BrooklynTaskTags.tagForContextEntity(app), 
-                BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
-        Iterables.getOnlyElement(tasks).get();
-        
-        return app;
-    }
-
-    protected Entity createStartWaitAndLogApplication(Reader input) throws Exception {
-        Entity app = createAndStartApplication(input);
-        waitForApplicationTasks(app);
-
-        getLogger().info("App started:");
-        Entities.dumpInfo(app);
-        
-        return app;
-    }
-
-    protected void addCatalogItems(Iterable<String> catalogYaml) {
-        addCatalogItems(joinLines(catalogYaml));
-    }
-
-    protected void addCatalogItems(String... catalogYaml) {
-        addCatalogItems(joinLines(catalogYaml));
-    }
-
-    protected void addCatalogItems(String catalogYaml) {
-        mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
-    }
-
-    protected void deleteCatalogEntity(String catalogItem) {
-        mgmt().getCatalog().deleteCatalogItem(catalogItem, TEST_VERSION);
-    }
-
-    protected Logger getLogger() {
-        return LOG;
-    }
-
-    private String joinLines(Iterable<String> catalogYaml) {
-        return Joiner.on("\n").join(catalogYaml);
-    }
-
-    private String joinLines(String[] catalogYaml) {
-        return Joiner.on("\n").join(catalogYaml);
-    }
-
-    protected String ver(String id) {
-        return CatalogUtils.getVersionedId(id, TEST_VERSION);
-    }
-
-    public void forceCatalogUpdate() {
-        forceUpdate = true;
-    }
-
-}