You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/12/23 12:07:21 UTC

[58/71] [abbrv] incubator-brooklyn git commit: [LIBRARY] move camp webapp related tests from software-webapp to qa module adding them to software-webapp had introduced a dependency on software-database

[LIBRARY] move camp webapp related tests from software-webapp to qa module
adding them to software-webapp had introduced a dependency on software-database


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

Branch: refs/heads/master
Commit: b32a37b4e0f2bf7d1eeed52ff97b1be2e15f36b9
Parents: 3d92033
Author: John McCabe <jo...@johnmccabe.net>
Authored: Sat Dec 19 19:17:26 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Dec 21 16:43:39 2015 +0000

----------------------------------------------------------------------
 brooklyn-library/qa/pom.xml                     |   7 +
 .../camp/EnrichersSlightlySimplerYamlTest.java  | 134 +++++++++
 .../qa/camp/EntitiesYamlIntegrationTest.java    |  71 +++++
 .../qa/camp/JavaWebAppsIntegrationTest.java     | 273 +++++++++++++++++++
 .../qa/camp/JavaWebAppsMatchingTest.java        | 144 ++++++++++
 .../java-web-app-and-db-with-function.yaml      |  36 +++
 .../java-web-app-and-db-with-policy.yaml        |  46 ++++
 .../src/test/resources/java-web-app-simple.yaml |  28 ++
 ...est-app-with-enrichers-slightly-simpler.yaml |  74 +++++
 .../src/test/resources/test-tomcat-cluster.yaml |  30 ++
 .../test-webapp-with-averaging-enricher.yaml    |  47 ++++
 .../camp/EnrichersSlightlySimplerYamlTest.java  | 134 ---------
 .../test/camp/EntitiesYamlIntegrationTest.java  |  71 -----
 .../test/camp/JavaWebAppsIntegrationTest.java   | 273 -------------------
 .../test/camp/JavaWebAppsMatchingTest.java      | 144 ----------
 .../java-web-app-and-db-with-function.yaml      |  36 ---
 .../java-web-app-and-db-with-policy.yaml        |  46 ----
 .../src/test/resources/java-web-app-simple.yaml |  28 --
 ...est-app-with-enrichers-slightly-simpler.yaml |  74 -----
 .../src/test/resources/test-tomcat-cluster.yaml |  30 --
 .../test-webapp-with-averaging-enricher.yaml    |  47 ----
 21 files changed, 890 insertions(+), 883 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/pom.xml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/pom.xml b/brooklyn-library/qa/pom.xml
index f3be308..e9fe0c4 100644
--- a/brooklyn-library/qa/pom.xml
+++ b/brooklyn-library/qa/pom.xml
@@ -84,6 +84,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-camp</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
             <artifactId>brooklyn-core</artifactId>
             <version>${project.version}</version>
             <classifier>tests</classifier>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EnrichersSlightlySimplerYamlTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EnrichersSlightlySimplerYamlTest.java b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EnrichersSlightlySimplerYamlTest.java
new file mode 100644
index 0000000..c24ead1
--- /dev/null
+++ b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/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.qa.camp;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.entity.group.DynamicCluster;
+import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.math.MathPredicates;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+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).sensors().set(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).sensors().set(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.sensors().set(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.sensors().set(Sensors.newDoubleSensor("my.load"), null);
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            Predicates.isNull());
+
+        ((EntityInternal) appservers.get(1)).sensors().set(Sensors.newDoubleSensor("my.load"), 10.0);
+        ((EntityInternal) appservers.get(2)).sensors().set(Sensors.newDoubleSensor("my.load"), 20.0);
+        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
+            MathPredicates.equalsApproximately(15));
+        srv0.sensors().set(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/b32a37b4/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EntitiesYamlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EntitiesYamlIntegrationTest.java b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/EntitiesYamlIntegrationTest.java
new file mode 100644
index 0000000..f92af6c
--- /dev/null
+++ b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/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.qa.camp;
+
+import static org.testng.Assert.*;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.entity.group.DynamicCluster;
+import org.apache.brooklyn.entity.proxy.nginx.NginxController;
+import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
+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;
+
+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/b32a37b4/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsIntegrationTest.java b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsIntegrationTest.java
new file mode 100644
index 0000000..1367ddd
--- /dev/null
+++ b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsIntegrationTest.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.qa.camp;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+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.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+import org.apache.brooklyn.camp.spi.Assembly;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.PlatformComponent;
+import org.apache.brooklyn.camp.spi.PlatformRootSummary;
+import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
+import org.apache.brooklyn.entity.webapp.JavaWebAppService;
+import org.apache.brooklyn.entity.webapp.WebAppService;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
+
+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.policies().size(), 1);
+            Policy policy = cluster.policies().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/b32a37b4/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsMatchingTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsMatchingTest.java b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsMatchingTest.java
new file mode 100644
index 0000000..92e29b9
--- /dev/null
+++ b/brooklyn-library/qa/src/test/java/org/apache/brooklyn/qa/camp/JavaWebAppsMatchingTest.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.qa.camp;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
+import org.apache.brooklyn.camp.spi.PlatformRootSummary;
+import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
+import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.core.task.DeferredSupplier;
+import org.apache.brooklyn.util.stream.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@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/b32a37b4/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-function.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-function.yaml b/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-function.yaml
new file mode 100644
index 0000000..0f15729
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-function.yaml
@@ -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.
+#
+name: java-cluster-db-example
+services:
+- serviceType: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  name: My Web
+  location: localhost
+  brooklyn.config:
+    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.7.0-M1/brooklyn-example-hello-world-sql-webapp-0.7.0-M1.war
+    http.port: 9280+
+    proxy.http.port: 9210+
+    java.sysprops: 
+      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
+         component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
+- serviceType: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: My DB
+  location: localhost
+  brooklyn.config:
+    datastore.creation.script.url: classpath://visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-policy.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-policy.yaml b/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-policy.yaml
new file mode 100644
index 0000000..10ea4e5
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/java-web-app-and-db-with-policy.yaml
@@ -0,0 +1,46 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+name: java-cluster-db-policy-example
+services:
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  name: My Web with Policy
+  location: localhost
+  brooklyn.config:
+    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0-M2/brooklyn-example-hello-world-sql-webapp-0.6.0-M2.war
+    http.port: 9280+
+    proxy.http.port: 9210+
+    java.sysprops: 
+      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
+         component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
+  brooklyn.policies:
+  - policyType: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+    brooklyn.config:
+      metric: $brooklyn:sensor("org.apache.brooklyn.entity.webapp.DynamicWebAppCluster", "webapp.reqs.perSec.windowed.perNode")
+      metricLowerBound: 10
+      metricUpperBound: 100
+      minPoolSize: 1
+      maxPoolSize: 5
+      
+- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+  id: db
+  name: My DB
+  location: localhost
+  brooklyn.config:
+    # this also uses the flag rather than the config key
+    creationScriptUrl: classpath://visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/resources/java-web-app-simple.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/java-web-app-simple.yaml b/brooklyn-library/qa/src/test/resources/java-web-app-simple.yaml
new file mode 100644
index 0000000..526e90b
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/java-web-app-simple.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.
+#
+name: sample-single-jboss
+description: Single JBoss using Brooklyn
+origin: https://github.com/apache/incubator-brooklyn
+location: localhost
+services:
+- serviceType: org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server
+  name: tomcat1
+  brooklyn.config:
+    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-webapp/0.7.0-M1/brooklyn-example-hello-world-webapp-0.7.0-M1.war
+    http.port: 9280+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml b/brooklyn-library/qa/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
new file mode 100644
index 0000000..2b55237
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
@@ -0,0 +1,74 @@
+#
+# 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.
+#
+# example showing how enrichers can be set 
+#
+name: test-app-with-enrichers
+description: Testing many enrichers
+services:
+- type: org.apache.brooklyn.entity.group.DynamicCluster
+  id: cluster
+  initialSize: 3
+  location: localhost
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.core.test.entity.TestEntity
+      brooklyn.enrichers:
+      - type: org.apache.brooklyn.enricher.stock.Transformer
+        # transform "ip" (which we expect a feed, not shown here, to set) to a URL;
+        # you can curl an address string to the sensors/ip endpoint an entity to trigger these enrichers 
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("ip")
+          enricher.targetSensor: $brooklyn:sensor("url")
+          enricher.targetValue: $brooklyn:formatString("http://%s/", $brooklyn:attributeWhenReady("ip"))
+      - type: org.apache.brooklyn.enricher.stock.Propagator
+        # use propagator to duplicate one sensor as another, giving the supplied sensor mapping;
+        # the other use of Propagator is where you specify a producer (using $brooklyn:entity(...) as below)
+        # from which to take sensors; in that mode you can specify `propagate` as a list of sensors whose names are unchanged,
+        # instead of (or in addition to) this map 
+        brooklyn.config:
+          sensorMapping:
+            $brooklyn:sensor("url"): $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+  brooklyn.enrichers:
+  - type: org.apache.brooklyn.enricher.stock.Aggregator
+    # aggregate `url` sensors from children into a list
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("url")
+      enricher.targetSensor: $brooklyn:sensor("urls.list")
+      enricher.aggregating.fromMembers: true
+  - type: org.apache.brooklyn.enricher.stock.Joiner
+    # create a string from that list, for use e.g. in bash scripts
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("urls.list")
+      enricher.targetSensor: $brooklyn:sensor("urls.list.comma_separated.max_2")
+      maximum: 2
+      # TODO infer uniqueTag, name etc
+      uniqueTag: urls.list.comma_separated.max_2
+  - type: org.apache.brooklyn.enricher.stock.Joiner
+    # pick one uri as the main one to use
+    brooklyn.config:
+      enricher.sourceSensor: $brooklyn:sensor("urls.list")
+      enricher.targetSensor: $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+      quote: false
+      maximum: 1
+brooklyn.enrichers:
+- type: org.apache.brooklyn.enricher.stock.Propagator
+  # if nothing specified for `propagating` or `sensorMapping` then 
+  # Propagator will do all but the usual lifecycle defaults, handy at the root!
+  brooklyn.config:
+    producer: $brooklyn:entity("cluster")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/resources/test-tomcat-cluster.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/test-tomcat-cluster.yaml b/brooklyn-library/qa/src/test/resources/test-tomcat-cluster.yaml
new file mode 100644
index 0000000..e3087b8
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/test-tomcat-cluster.yaml
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+name: Test Tomcat cluster
+location: localhost
+services:
+- serviceType: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  name: tomcat-cluster
+  initialSize: 2
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
+      brooklyn.config:
+        dynamiccluster.quarantineFailedEntities: false
+        cluster.initial.quorumSize: 2
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/qa/src/test/resources/test-webapp-with-averaging-enricher.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/qa/src/test/resources/test-webapp-with-averaging-enricher.yaml b/brooklyn-library/qa/src/test/resources/test-webapp-with-averaging-enricher.yaml
new file mode 100644
index 0000000..9a508cb
--- /dev/null
+++ b/brooklyn-library/qa/src/test/resources/test-webapp-with-averaging-enricher.yaml
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+# example showing how enrichers can be set 
+#
+name: test-webapp-with-averaging-enricher
+description: Testing many enrichers
+services:
+- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+  initialSize: 3
+  location: localhost
+  
+  # define the web cluster, adding an averaging enricher to the cluster.
+  # this assumes the test fixture will set the "my.load" sensor on the member-specs in here. 
+  webClusterSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.webapp.DynamicWebAppCluster
+      id: cluster
+      brooklyn.enrichers:
+      - type: org.apache.brooklyn.enricher.stock.Aggregator
+        brooklyn.config:
+          enricher.sourceSensor: $brooklyn:sensor("my.load")
+          enricher.targetSensor: $brooklyn:sensor("my.load.averaged")
+          enricher.aggregating.fromMembers: true
+          transformation: average
+            
+  brooklyn.enrichers:
+  - type: org.apache.brooklyn.enricher.stock.Propagator
+    brooklyn.config:
+      producer: $brooklyn:entity("cluster")
+      propagating:
+      - $brooklyn:sensor("my.load.averaged")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EnrichersSlightlySimplerYamlTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EnrichersSlightlySimplerYamlTest.java b/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EnrichersSlightlySimplerYamlTest.java
deleted file mode 100644
index b74d9af..0000000
--- a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/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 org.apache.brooklyn.test.camp;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.math.MathPredicates;
-import org.apache.brooklyn.util.text.StringPredicates;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-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).sensors().set(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).sensors().set(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.sensors().set(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.sensors().set(Sensors.newDoubleSensor("my.load"), null);
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            Predicates.isNull());
-
-        ((EntityInternal) appservers.get(1)).sensors().set(Sensors.newDoubleSensor("my.load"), 10.0);
-        ((EntityInternal) appservers.get(2)).sensors().set(Sensors.newDoubleSensor("my.load"), 20.0);
-        EntityTestUtils.assertAttributeEventually(cdwac, Sensors.newSensor(Double.class, "my.load.averaged"),
-            MathPredicates.equalsApproximately(15));
-        srv0.sensors().set(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/b32a37b4/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EntitiesYamlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EntitiesYamlIntegrationTest.java b/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/EntitiesYamlIntegrationTest.java
deleted file mode 100644
index a600fc1..0000000
--- a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/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 org.apache.brooklyn.test.camp;
-
-import static org.testng.Assert.*;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
-import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
-import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
-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;
-
-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/b32a37b4/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsIntegrationTest.java b/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsIntegrationTest.java
deleted file mode 100644
index a812998..0000000
--- a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsIntegrationTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.test.camp;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-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.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.policy.Policy;
-import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
-import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
-import org.apache.brooklyn.camp.spi.Assembly;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.PlatformComponent;
-import org.apache.brooklyn.camp.spi.PlatformRootSummary;
-import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.JavaWebAppService;
-import org.apache.brooklyn.entity.webapp.WebAppService;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.ResourceUtils;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
-
-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.policies().size(), 1);
-            Policy policy = cluster.policies().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/b32a37b4/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsMatchingTest.java
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsMatchingTest.java b/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/JavaWebAppsMatchingTest.java
deleted file mode 100644
index a3479ec..0000000
--- a/brooklyn-library/software/webapp/src/test/java/org/apache/brooklyn/test/camp/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 org.apache.brooklyn.test.camp;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatform;
-import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
-import org.apache.brooklyn.camp.spi.PlatformRootSummary;
-import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
-import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.ResourceUtils;
-import org.apache.brooklyn.util.core.task.DeferredSupplier;
-import org.apache.brooklyn.util.stream.Streams;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-@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/b32a37b4/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-function.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-function.yaml b/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-function.yaml
deleted file mode 100644
index 0f15729..0000000
--- a/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-function.yaml
+++ /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.
-#
-name: java-cluster-db-example
-services:
-- serviceType: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
-  name: My Web
-  location: localhost
-  brooklyn.config:
-    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.7.0-M1/brooklyn-example-hello-world-sql-webapp-0.7.0-M1.war
-    http.port: 9280+
-    proxy.http.port: 9210+
-    java.sysprops: 
-      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
-         component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
-- serviceType: org.apache.brooklyn.entity.database.mysql.MySqlNode
-  id: db
-  name: My DB
-  location: localhost
-  brooklyn.config:
-    datastore.creation.script.url: classpath://visitors-creation-script.sql

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b32a37b4/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-policy.yaml
----------------------------------------------------------------------
diff --git a/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-policy.yaml b/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-policy.yaml
deleted file mode 100644
index 10ea4e5..0000000
--- a/brooklyn-library/software/webapp/src/test/resources/java-web-app-and-db-with-policy.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#  http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-name: java-cluster-db-policy-example
-services:
-- type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
-  name: My Web with Policy
-  location: localhost
-  brooklyn.config:
-    wars.root: http://search.maven.org/remotecontent?filepath=io/brooklyn/example/brooklyn-example-hello-world-sql-webapp/0.6.0-M2/brooklyn-example-hello-world-sql-webapp-0.6.0-M2.war
-    http.port: 9280+
-    proxy.http.port: 9210+
-    java.sysprops: 
-      brooklyn.example.db.url: $brooklyn:formatString("jdbc:%s%s?user=%s&password=%s",
-         component("db").attributeWhenReady("datastore.url"), "visitors", "brooklyn", "br00k11n")
-  brooklyn.policies:
-  - policyType: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
-    brooklyn.config:
-      metric: $brooklyn:sensor("org.apache.brooklyn.entity.webapp.DynamicWebAppCluster", "webapp.reqs.perSec.windowed.perNode")
-      metricLowerBound: 10
-      metricUpperBound: 100
-      minPoolSize: 1
-      maxPoolSize: 5
-      
-- type: org.apache.brooklyn.entity.database.mysql.MySqlNode
-  id: db
-  name: My DB
-  location: localhost
-  brooklyn.config:
-    # this also uses the flag rather than the config key
-    creationScriptUrl: classpath://visitors-creation-script.sql