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/11/09 13:55:10 UTC

[01/21] incubator-brooklyn git commit: Fix installed test osgi jar name

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 703354d68 -> be46512ac


Fix installed test osgi jar name

Previously changed due to a copy&paste error


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

Branch: refs/heads/master
Commit: 92d8560ea42f8f1591aed83593126406b4268245
Parents: 5c5e087
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Oct 28 19:00:33 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 14:23:24 2015 +0200

----------------------------------------------------------------------
 .../resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/92d8560e/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml
----------------------------------------------------------------------
diff --git a/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml b/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml
index ae70461..d9a3e79 100644
--- a/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml
+++ b/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2-evil-twin/pom.xml
@@ -69,7 +69,7 @@
                 <version>2.3.2</version>
                 <configuration>
                     <outputDirectory>../../../resources/brooklyn/osgi</outputDirectory>
-                    <finalName>brooklyn-test-osgi-more-entities_evil-twin_${project.version}</finalName>
+                    <finalName>brooklyn-test-osgi-more-entities_${project.version}</finalName>
                 </configuration>
             </plugin>
             <plugin>


[07/21] incubator-brooklyn git commit: Parameters docs

Posted by he...@apache.org.
Parameters docs


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

Branch: refs/heads/master
Commit: 5a69cd68796d041ea8608fb510f70344c5586e1c
Parents: 9b98543
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Nov 3 17:58:23 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:38 2015 +0200

----------------------------------------------------------------------
 docs/guide/ops/catalog/index.md | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5a69cd68/docs/guide/ops/catalog/index.md
----------------------------------------------------------------------
diff --git a/docs/guide/ops/catalog/index.md b/docs/guide/ops/catalog/index.md
index 700b24f..b738954 100644
--- a/docs/guide/ops/catalog/index.md
+++ b/docs/guide/ops/catalog/index.md
@@ -111,6 +111,31 @@ The following optional catalog metadata is supported:
   This feature is experimental and may change or be removed.
   Also note that external OSGi dependencies are not supported 
   and other metadata (such as versions, etc) may not be applied.
+- `brooklyn.parameters`: a list of parameters the blueprint accepts. The items have
+  the following properties:
+  - `name` (required): identifier by which to reference the parameter when setting
+    or retrieving its value
+  - `label`: a value to present to the user, same as `name` if empty
+  - `description`: Short text describing the parameter behaviour/usage, presented
+    to the user
+  - `type`: the type of the parameter, one of `string`, `integer`, `long`, `float`,
+    `double`, `timestamp`, `port`, a fully qualified Java type name. Default is `string`.
+  - `default`: a default value, converted to the type above
+  - `constraints`: a list of constraints the parameter should meet, currently
+    `required` is supported
+  A shorthand notation is also supported where the name of the parameter is directly
+  passed as an item in the list. For example:
+
+~~~ yaml
+brooklyn.properties:
+- displayName
+- name: user.name
+  constraints:
+  - required
+- name: user.age
+  type: integer
+~~~
+
 - `brooklyn.libraries`: a list of pointers to OSGi bundles required for the catalog item.
   This can be omitted if blueprints are pure YAML and everything required is included in the classpath and catalog.
   Where custom Java code or bundled resources is needed, however, OSGi JARs supply


[16/21] incubator-brooklyn git commit: Fix failing integration tests

Posted by he...@apache.org.
Fix failing integration tests


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

Branch: refs/heads/master
Commit: 76d480fdb31f2f2bf8ec5798aa1a364f0b2521da
Parents: 35a227f
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Nov 6 12:20:48 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Fri Nov 6 16:20:23 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |  3 +-
 .../apache/brooklyn/util/core/osgi/Osgis.java   | 39 +++++++++-----------
 .../core/mgmt/osgi/OsgiStandaloneTest.java      |  8 ++--
 .../mysql/MySqlClusterIntegrationTest.java      |  5 +--
 .../database/mysql/MySqlClusterTestHelper.java  | 36 +++++++++++++++++-
 .../rt/felix/EmbeddedFelixFramework.java        | 12 ++++++
 6 files changed, 71 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 0e941bd..b6f85f1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -36,6 +36,7 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.BrooklynVersion;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
 import org.apache.brooklyn.core.server.BrooklynServerPaths;
+import org.apache.brooklyn.rt.felix.EmbeddedFelixFramework;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.osgi.Osgis;
@@ -190,7 +191,7 @@ public class OsgiManager {
                     Class<T> clazz;
                     //Extension bundles don't support loadClass.
                     //Instead load from the app classpath.
-                    if (Osgis.isExtensionBundle(b)) {
+                    if (EmbeddedFelixFramework.isExtensionBundle(b)) {
                         @SuppressWarnings("unchecked")
                         Class<T> c = (Class<T>)Class.forName(type);
                         clazz = c;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
index 6d5dc91..be24dc1 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
@@ -26,40 +26,37 @@ import java.net.URISyntaxException;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Version;
-import org.osgi.framework.launch.Framework;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.rt.felix.EmbeddedFelixFramework;
 import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.osgi.OsgiUtils;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
-import java.util.Map;
-import org.apache.brooklyn.util.osgi.OsgiUtils;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.launch.FrameworkFactory;
 
 /** 
  * utilities for working with osgi.
@@ -71,9 +68,6 @@ import org.osgi.framework.launch.FrameworkFactory;
 public class Osgis {
     private static final Logger LOG = LoggerFactory.getLogger(Osgis.class);
 
-    private static final String EXTENSION_PROTOCOL = "system";
-    private static final Set<String> SYSTEM_BUNDLES = MutableSet.of();
-
     /** @deprecated since 0.9.0, replaced with {@link org.apache.brooklyn.util.osgi.VersionedName} */
     @Deprecated
     public static class VersionedName extends org.apache.brooklyn.util.osgi.VersionedName {
@@ -246,6 +240,7 @@ public class Osgis {
             return Joiner.on(";").join(parts);
         }
         
+        @Override
         public String toString() {
             return getClass().getCanonicalName()+"["+getConstraintsDescription()+"]";
         }
@@ -444,7 +439,7 @@ public class Osgis {
         String versionedId = OsgiUtils.getVersionedId(manifest);
         for (Bundle installedBundle : framework.getBundleContext().getBundles()) {
             if (versionedId.equals(OsgiUtils.getVersionedId(installedBundle))) {
-                if (SYSTEM_BUNDLES.contains(versionedId)) {
+                if (EmbeddedFelixFramework.isSystemBundle(installedBundle)) {
                     LOG.debug("Already have system bundle "+versionedId+" from "+installedBundle+"/"+installedBundle.getLocation()+" when requested "+url+"; not installing");
                     // "System bundles" (ie things on the classpath) cannot be overridden
                     return installedBundle;
@@ -462,10 +457,10 @@ public class Osgis {
         return ResourceUtils.create(Osgis.class).getResourceFromUrl(url);
     }
     
+    /** @deprecated since 0.9.0, replaced with {@link EmbeddedFelixFramework#isExtensionBundle(Bundle)} */
+    @Deprecated
     public static boolean isExtensionBundle(Bundle bundle) {
-        String location = bundle.getLocation();
-        return location != null && 
-                EXTENSION_PROTOCOL.equals(Urls.getProtocol(location));
+        return EmbeddedFelixFramework.isExtensionBundle(bundle);
     }
 
     /** @deprecated since 0.9.0, replaced with {@link OsgiUtils#parseOsgiIdentifier(java.lang.String) } */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiStandaloneTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiStandaloneTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiStandaloneTest.java
index e48ff70..524e248 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiStandaloneTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiStandaloneTest.java
@@ -19,8 +19,8 @@
 package org.apache.brooklyn.core.mgmt.osgi;
 
 
-import org.apache.brooklyn.util.osgi.OsgiTestResources;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.rt.felix.EmbeddedFelixFramework;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.osgi.OsgiTestBase;
@@ -29,6 +29,7 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.maven.MavenArtifact;
 import org.apache.brooklyn.util.maven.MavenRetriever;
 import org.apache.brooklyn.util.net.Urls;
+import org.apache.brooklyn.util.osgi.OsgiTestResources;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.slf4j.Logger;
@@ -84,8 +85,7 @@ public class OsgiStandaloneTest extends OsgiTestBase {
         Assert.assertEquals(Entity.class, bundleCls.getClassLoader().loadClass(Entity.class.getName()));
     }
 
-    // FIXME re-enable
-    @Test(enabled = false)
+    @Test
     public void testDuplicateBundle() throws Exception {
         MavenArtifact artifact = new MavenArtifact("org.apache.brooklyn", "brooklyn-api", "jar", "0.9.0-SNAPSHOT"); // BROOKLYN_VERSION
         String localUrl = MavenRetriever.localUrl(artifact);
@@ -106,7 +106,7 @@ public class OsgiStandaloneTest extends OsgiTestBase {
         //Make sure that we still get the initially loaded
         //bundle after trying to install the same version.
         Bundle bundle = install(url);
-        Assert.assertTrue(Osgis.isExtensionBundle(bundle));
+        Assert.assertTrue(EmbeddedFelixFramework.isExtensionBundle(bundle));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java
index c93de8c..baaefe4 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterIntegrationTest.java
@@ -35,7 +35,6 @@ import org.apache.brooklyn.entity.database.mysql.MySqlCluster.MySqlMaster;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.task.ssh.SshTasks;
 import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.ssh.BashCommands;
@@ -74,7 +73,7 @@ public class MySqlClusterIntegrationTest extends BrooklynAppLiveTestSupport {
             Location loc = getLocation();
             EntitySpec<MySqlCluster> clusterSpec = EntitySpec.create(MySqlCluster.class)
                     .configure(MySqlMaster.MASTER_CREATION_SCRIPT_CONTENTS, MySqlClusterTestHelper.CREATION_SCRIPT)
-                    .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve",""));
+                    .configure(MySqlNode.MYSQL_SERVER_CONF, MySqlClusterTestHelper.minimalMemoryConfig());
             MySqlCluster cluster = MySqlClusterTestHelper.initCluster(app, loc, clusterSpec);
             MySqlNode master = (MySqlNode) cluster.getAttribute(MySqlCluster.FIRST);
             purgeLogs(cluster, master);
@@ -108,7 +107,7 @@ public class MySqlClusterIntegrationTest extends BrooklynAppLiveTestSupport {
             Location loc = getLocation();
             EntitySpec<MySqlCluster> clusterSpec = EntitySpec.create(MySqlCluster.class)
                     .configure(MySqlMaster.MASTER_CREATION_SCRIPT_CONTENTS, MySqlClusterTestHelper.CREATION_SCRIPT)
-                    .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve",""))
+                    .configure(MySqlNode.MYSQL_SERVER_CONF, MySqlClusterTestHelper.minimalMemoryConfig())
                     .configure(MySqlCluster.SLAVE_REPLICATE_DO_DB, ImmutableList.of("feedback", "items", "mysql"))
                     .configure(MySqlCluster.SLAVE_REPLICATE_DUMP_DB, ImmutableList.of("feedback", "items", "mysql"));
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
index d99e119..71c0165 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
@@ -92,14 +92,46 @@ public class MySqlClusterTestHelper {
         test(app, location, EntitySpec.create(MySqlCluster.class)
                 .configure(MySqlCluster.INITIAL_SIZE, 2)
                 .configure(MySqlNode.CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT)
-                .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve","")));
+                .configure(MySqlNode.MYSQL_SERVER_CONF, minimalMemoryConfig()));
+    }
+
+    public static MutableMap<String, Object> minimalMemoryConfig() {
+        // http://www.tocker.ca/2014/03/10/configuring-mysql-to-use-minimal-memory.html
+        return MutableMap.<String, Object>of()
+                .add("skip-name-resolve","")
+                .add("performance_schema","0")
+                .add("innodb_buffer_pool_size","5M")
+                .add("innodb_log_buffer_size","256K")
+                .add("query_cache_size","0")
+                .add("max_connections","10")
+                .add("key_buffer_size","8")
+                .add("thread_cache_size","0")
+                .add("host_cache_size","0")
+                .add("innodb_ft_cache_size","1600000")
+                .add("innodb_ft_total_cache_size","32000000")
+
+                // per thread or per operation settings
+                .add("thread_stack","131072")
+                .add("sort_buffer_size","32K")
+                .add("read_buffer_size","8200")
+                .add("read_rnd_buffer_size","8200")
+                .add("max_heap_table_size","16K")
+                .add("tmp_table_size","1K")
+                .add("bulk_insert_buffer_size","0")
+                .add("join_buffer_size","128")
+                .add("net_buffer_length","1K")
+                .add("innodb_sort_buffer_size","64K")
+
+                // settings that relate to the binary log (if enabled)
+                .add("binlog_cache_size","4K")
+                .add("binlog_stmt_cache_size","4K");
     }
 
     public static void testMasterInit(TestApplication app, Location location) throws Exception {
         test(app, location, EntitySpec.create(MySqlCluster.class)
                 .configure(MySqlCluster.INITIAL_SIZE, 2)
                 .configure(MySqlMaster.MASTER_CREATION_SCRIPT_CONTENTS, CREATION_SCRIPT)
-                .configure(MySqlNode.MYSQL_SERVER_CONF, MutableMap.<String, Object>of("skip-name-resolve","")));
+                .configure(MySqlNode.MYSQL_SERVER_CONF, minimalMemoryConfig()));
     }
 
     public static void test(TestApplication app, Location location, EntitySpec<MySqlCluster> clusterSpec) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/76d480fd/utils/rt-felix/src/main/java/org/apache/brooklyn/rt/felix/EmbeddedFelixFramework.java
----------------------------------------------------------------------
diff --git a/utils/rt-felix/src/main/java/org/apache/brooklyn/rt/felix/EmbeddedFelixFramework.java b/utils/rt-felix/src/main/java/org/apache/brooklyn/rt/felix/EmbeddedFelixFramework.java
index 6d2bb5f..2bc467a 100644
--- a/utils/rt-felix/src/main/java/org/apache/brooklyn/rt/felix/EmbeddedFelixFramework.java
+++ b/utils/rt-felix/src/main/java/org/apache/brooklyn/rt/felix/EmbeddedFelixFramework.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.ReferenceWithError;
+import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.osgi.OsgiUtils;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
@@ -255,4 +256,15 @@ public class EmbeddedFelixFramework {
         return atts.containsKey(new Attributes.Name(Constants.BUNDLE_MANIFESTVERSION));
     }
 
+    public static boolean isSystemBundle(Bundle bundle) {
+        String versionedId = OsgiUtils.getVersionedId( bundle );
+        return SYSTEM_BUNDLES.contains(versionedId);
+    }
+
+    public static boolean isExtensionBundle(Bundle bundle) {
+        String location = bundle.getLocation();
+        return location != null && 
+                EXTENSION_PROTOCOL.equals(Urls.getProtocol(location));
+    }
+
 }


[18/21] incubator-brooklyn git commit: Fix - don't unwrap if policies/initializers/enrichers set at top level

Posted by he...@apache.org.
Fix - don't unwrap if policies/initializers/enrichers set at top level


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

Branch: refs/heads/master
Commit: 51ca806617510c1bf8fc76ecd20cc08fa277904a
Parents: 94263c6
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Mon Nov 9 12:50:53 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Mon Nov 9 12:56:13 2015 +0200

----------------------------------------------------------------------
 .../core/mgmt/EntityManagementUtils.java        |  4 ++-
 .../camp/brooklyn/ApplicationsYamlTest.java     | 28 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/51ca8066/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index 59bcc87..6047985 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -287,8 +287,10 @@ public class EntityManagementUtils {
         return isWrapperApp(spec) && hasSingleChild(spec) &&
                 //equivalent to no keys starting with "brooklyn."
                 spec.getEnrichers().isEmpty() &&
+                spec.getEnricherSpecs().isEmpty() &&
                 spec.getInitializers().isEmpty() &&
-                spec.getPolicies().isEmpty();
+                spec.getPolicies().isEmpty() &&
+                spec.getPolicySpecs().isEmpty();
     }
 
     public static boolean isWrapperApp(EntitySpec<?> spec) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/51ca8066/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
index b58e5ca..374df13 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
@@ -67,6 +67,34 @@ public class ApplicationsYamlTest extends AbstractYamlTest {
         assertEquals(app.getChildren().size(), 2);
     }
 
+    @Test
+    public void testWrapsWhenEnrichers() throws Exception {
+        Entity app = createAndStartApplication(
+                "brooklyn.enrichers:",
+                "- type: " + TestEnricher.class.getName(),
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertWrapped(app, BasicApplication.class);
+    }
+
+    @Test
+    public void testWrapsWhenPolicy() throws Exception {
+        Entity app = createAndStartApplication(
+                "brooklyn.policies:",
+                "- type: " + TestPolicy.class.getName(),
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertWrapped(app, BasicApplication.class);
+    }
+
+    @Test
+    public void testWrapsWhenInitializer() throws Exception {
+        Entity app = createAndStartApplication(
+                "brooklyn.initializers:",
+                "- type: " + TestConfigurableInitializer.class.getName(),
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertWrapped(app, BasicApplication.class);
     }
 
     @Test


[09/21] incubator-brooklyn git commit: Parameter aware specs

Posted by he...@apache.org.
Parameter aware specs

Let specs be aware of the parameters the underlying brooklyn object is accepting. Catalog items return the same spec parameters derived at addition time. The catalog item can override the underlying entity parameters by including the list in its meta.


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

Branch: refs/heads/master
Commit: 0149bf09972fcfde9819708756cfda176d9865e3
Parents: 5fb4771
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Oct 29 18:44:24 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:38 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/api/catalog/CatalogItem.java       |  13 +-
 .../apache/brooklyn/api/entity/EntitySpec.java  |  50 +--
 .../internal/AbstractBrooklynObjectSpec.java    |  24 ++
 .../apache/brooklyn/api/objs/SpecParameter.java |  32 ++
 .../catalog/internal/BasicBrooklynCatalog.java  |  44 ++-
 .../catalog/internal/CatalogClasspathDo.java    |   9 +-
 .../core/catalog/internal/CatalogInputDto.java  | 240 --------------
 .../catalog/internal/CatalogItemBuilder.java    |  10 +-
 .../core/catalog/internal/CatalogItemDo.java    |   5 +-
 .../internal/CatalogItemDtoAbstract.java        |  22 +-
 .../internal/JavaCatalogToSpecTransformer.java  |  14 +-
 .../brooklyn/core/entity/AbstractEntity.java    |  19 ++
 .../brooklyn/core/entity/EntityDynamicType.java |  37 +++
 .../core/mgmt/EntityManagementUtils.java        |   6 +-
 .../brooklyn/core/objs/BasicSpecParameter.java  | 322 +++++++++++++++++++
 .../core/objs/proxy/InternalEntityFactory.java  |  12 +
 .../brooklyn/util/core/flags/FlagUtils.java     |  30 +-
 .../internal/CatalogInputDtoClassTest.java      |  65 ----
 .../internal/CatalogInputDtoYamlTest.java       | 185 -----------
 .../core/catalog/internal/CatalogInputTest.java | 139 --------
 .../internal/SpecParameterInMetaTest.java       | 139 ++++++++
 .../entity/DynamicEntityTypeConfigTest.java     | 126 ++++++++
 .../brooklyn/core/entity/EntityTypeTest.java    |  15 +-
 .../objs/BasicSpecParameterFromClassTest.java   |  65 ++++
 .../objs/BasicSpecParameterFromListTest.java    | 186 +++++++++++
 .../camp/brooklyn/BrooklynCampPlatform.java     |   1 +
 .../BrooklynCampPlatformLauncherNoServer.java   |   1 +
 .../camp/brooklyn/BrooklynCampReservedKeys.java |   1 +
 .../BrooklynAssemblyTemplateInstantiator.java   |  22 +-
 .../BrooklynComponentTemplateResolver.java      |   2 +
 .../BrooklynEntityDecorationResolver.java       |  74 ++++-
 .../spi/creation/BrooklynEntityMatcher.java     |   1 +
 .../creation/BrooklynYamlTypeInstantiator.java  |   2 +
 .../brooklyn/spi/creation/CampCatalogUtils.java |  12 +-
 .../camp/brooklyn/spi/creation/CampUtils.java   |  74 ++++-
 .../service/UrlServiceSpecResolver.java         |   7 +-
 .../platform/BrooklynImmutableCampPlatform.java |   1 +
 .../rest/transform/CatalogTransformer.java      |   4 +-
 .../rest/transform/EntityTransformer.java       |   4 +-
 39 files changed, 1243 insertions(+), 772 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
index e5a2636..7f4e3b3 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.Rebindable;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
-import org.apache.brooklyn.config.ConfigKey;
 
 import com.google.common.annotations.Beta;
 
@@ -47,15 +47,6 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
         public boolean isNamed();
     }
 
-    public static interface CatalogInput<T> {
-        /** Short name, to be used in UI */
-        String getLabel();
-        /** Visible by default in UI, not all inputs may be visible at once */
-        boolean isPinned();
-        /** Type information for the input */
-        ConfigKey<T> getType();
-    }
-
     /**
      * @throws UnsupportedOperationException; config not supported for catalog items
      */
@@ -106,7 +97,7 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
 
     public String getVersion();
 
-    public List<CatalogInput<?>> getInputs();
+    public List<SpecParameter<?>> getParameters();
 
     public Collection<CatalogBundle> getLibraries();
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java
index a1f7dec..a38e52e 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java
@@ -103,27 +103,7 @@ public class EntitySpec<T extends Entity> extends AbstractBrooklynObjectSpec<T,E
      * original entity spec.
      */
     public static <T extends Entity> EntitySpec<T> create(EntitySpec<T> spec) {
-        EntitySpec<T> result = create(spec.getType())
-                .displayName(spec.getDisplayName())
-                .tags(spec.getTags())
-                .additionalInterfaces(spec.getAdditionalInterfaces())
-                .configure(spec.getConfig())
-                .configure(spec.getFlags())
-                .policySpecs(spec.getPolicySpecs())
-                .policies(spec.getPolicies())
-                .enricherSpecs(spec.getEnricherSpecs())
-                .enrichers(spec.getEnrichers())
-                .addInitializers(spec.getInitializers())
-                .children(spec.getChildren())
-                .members(spec.getMembers())
-                .groups(spec.getGroups())
-                .catalogItemId(spec.getCatalogItemId())
-                .locations(spec.getLocations());
-        
-        if (spec.getParent() != null) result.parent(spec.getParent());
-        if (spec.getImplementation() != null) result.impl(spec.getImplementation());
-        
-        return result;
+        return create(spec.getType()).copyFrom(spec);
     }
     
     public static <T extends Entity> EntitySpec<T> newInstance(Class<T> type) {
@@ -149,7 +129,33 @@ public class EntitySpec<T extends Entity> extends AbstractBrooklynObjectSpec<T,E
     public EntitySpec(Class<T> type) {
         super(type);
     }
-    
+
+    @Override
+    protected EntitySpec<T> copyFrom(EntitySpec<T> otherSpec) {
+        super.copyFrom(otherSpec)
+                .displayName(otherSpec.getDisplayName())
+                .tags(otherSpec.getTags())
+                .additionalInterfaces(otherSpec.getAdditionalInterfaces())
+                .configure(otherSpec.getConfig())
+                .configure(otherSpec.getFlags())
+                .policySpecs(otherSpec.getPolicySpecs())
+                .policies(otherSpec.getPolicies())
+                .enricherSpecs(otherSpec.getEnricherSpecs())
+                .enrichers(otherSpec.getEnrichers())
+                .addInitializers(otherSpec.getInitializers())
+                .children(otherSpec.getChildren())
+                .members(otherSpec.getMembers())
+                .groups(otherSpec.getGroups())
+                .catalogItemId(otherSpec.getCatalogItemId())
+                .locations(otherSpec.getLocations());
+        
+        if (otherSpec.getParent() != null) parent(otherSpec.getParent());
+        if (otherSpec.getImplementation() != null) impl(otherSpec.getImplementation());
+        
+        return this;
+    }
+
+    @Override
     @SuppressWarnings("unchecked")
     public Class<T> getType() {
         return (Class<T>)super.getType();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java b/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
index 7e8a022..6ba5a3c 100644
--- a/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
+++ b/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
@@ -18,14 +18,19 @@
  */
 package org.apache.brooklyn.api.internal;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.io.Serializable;
 import java.lang.reflect.Modifier;
+import java.util.List;
 import java.util.Set;
 
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 
@@ -37,6 +42,7 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
     private String displayName;
     private String catalogItemId;
     private Set<Object> tags = MutableSet.of();
+    private List<SpecParameter<?>> parameters = ImmutableList.of();
 
     protected AbstractBrooklynObjectSpec(Class<? extends T> type) {
         checkValidType(type);
@@ -76,6 +82,11 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
         Iterables.addAll(this.tags, tagsToAdd);
         return self();
     }
+    
+    public SpecT parameters(List<? extends SpecParameter<?>> parameters) {
+        this.parameters = ImmutableList.copyOf(checkNotNull(parameters, "parameters"));
+        return self();
+    }
 
     /**
      * @return The type of the object (or significant interface)
@@ -99,6 +110,11 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
         return ImmutableSet.copyOf(tags);
     }
 
+    /** A list of configuration options that the entity supports. */
+    public final List<SpecParameter<?>> getParameters() {
+        return ImmutableList.copyOf(parameters);
+    }
+
     // TODO Duplicates method in BasicEntityTypeRegistry and InternalEntityFactory.isNewStyleEntity
     protected final void checkIsNewStyleImplementation(Class<?> implClazz) {
         try {
@@ -119,6 +135,13 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
         if (val.isInterface()) throw new IllegalStateException("Implementation "+val+" is an interface, but must be a non-abstract class");
         if (Modifier.isAbstract(val.getModifiers())) throw new IllegalStateException("Implementation "+val+" is abstract, but must be a non-abstract class");
     }
+    
+    protected SpecT copyFrom(SpecT otherSpec) {
+        return displayName(otherSpec.getDisplayName())
+            .tags(otherSpec.getTags())
+            .catalogItemId(otherSpec.getCatalogItemId())
+            .parameters(otherSpec.getParameters());
+    }
 
     @Override
     public boolean equals(Object obj) {
@@ -129,6 +152,7 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
         if (!Objects.equal(getCatalogItemId(), other.getCatalogItemId())) return false;
         if (!Objects.equal(getType(), other.getType())) return false;
         if (!Objects.equal(getTags(), other.getTags())) return false;
+        if (!Objects.equal(getParameters(), other.getParameters())) return false;
         return true;
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/api/src/main/java/org/apache/brooklyn/api/objs/SpecParameter.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/SpecParameter.java b/api/src/main/java/org/apache/brooklyn/api/objs/SpecParameter.java
new file mode 100644
index 0000000..4e9dc62
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/SpecParameter.java
@@ -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.
+ */
+package org.apache.brooklyn.api.objs;
+
+import java.io.Serializable;
+
+import org.apache.brooklyn.config.ConfigKey;
+
+public interface SpecParameter<T> extends Serializable {
+    /** Short name, to be used in UI */
+    String getLabel();
+    /** Visible by default in UI, not all inputs may be visible at once */
+    boolean isPinned();
+    /** Type information for the input */
+    ConfigKey<T> getType();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index e9f8d34..262e3b4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -32,17 +32,18 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.core.catalog.CatalogPredicates;
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
 import org.apache.brooklyn.core.location.BasicLocationRegistry;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.core.plan.PlanToSpecFactory;
 import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
 import org.apache.brooklyn.util.collections.MutableList;
@@ -318,12 +319,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         if (encounteredTypes.contains(item.getSymbolicName())) {
             throw new IllegalStateException("Type being resolved '"+item.getSymbolicName()+"' has already been encountered in " + encounteredTypes + "; recursive cycle detected");
         }
-        return PlanToSpecFactory.attemptWithLoaders(mgmt, new Function<PlanToSpecTransformer, SpecT>() {
+        Maybe<SpecT> specMaybe = PlanToSpecFactory.attemptWithLoaders(mgmt, new Function<PlanToSpecTransformer, SpecT>() {
             @Override
             public SpecT apply(PlanToSpecTransformer input) {
                 return input.createCatalogSpec(item, encounteredTypes);
             }
-        }).get();
+        });
+        if (specMaybe.isPresent() && !item.getParameters().isEmpty()) {
+            specMaybe.get().parameters(item.getParameters());
+        }
+        return specMaybe.get();
     }
 
     /**
@@ -421,8 +426,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         // (this load is required for the scan below and I think also for yaml resolution)
         CatalogUtils.installLibraries(mgmt, libraryBundlesNew);
 
-        List<?> inputsRaw = MutableList.copyOf(getFirstAs(itemMetadata, List.class, "brooklyn.inputs", "inputs").orNull());
-        List<CatalogInput<?>> inputs = CatalogInputDto.ParseYamlInputs.parseInputs(inputsRaw, CatalogUtils.newClassLoadingContext(mgmt, "<catalog_input_parser>", libraryBundles));
+        List<?> parametersRaw = MutableList.copyOf(getFirstAs(itemMetadata, List.class, "brooklyn.parameters", "parameters").orNull());
+        List<SpecParameter<?>> metaParameters = BasicSpecParameter.fromConfigList(parametersRaw, CatalogUtils.newClassLoadingContext(mgmt, "<catalog_input_parser>", libraryBundles));
 
         Boolean scanJavaAnnotations = getFirstAs(itemMetadata, Boolean.class, "scanJavaAnnotations", "scan_java_annotations").orNull();
         if (scanJavaAnnotations==null || !scanJavaAnnotations) {
@@ -571,8 +576,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         String sourcePlanYaml = planInterpreter.getPlanYaml();
         
         CatalogItemDtoAbstract<?, ?> dto = createItemBuilder(itemType, symbolicName, version)
-            .inputs(inputs)
             .libraries(libraryBundles)
+            .parameters(getParameters(metaParameters, planInterpreter))
             .displayName(displayName)
             .description(description)
             .deprecated(catalogDeprecated)
@@ -584,6 +589,14 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         result.add(dto);
     }
 
+    private List<SpecParameter<?>> getParameters(List<SpecParameter<?>> metaParameters, PlanInterpreterGuessingType planInterpreter) {
+        if (!metaParameters.isEmpty()) {
+            return metaParameters;
+        } else {
+            return planInterpreter.parameters;
+        }
+    }
+
     private String setFromItemIfUnset(String oldValue, Map<?,?> item, String fieldAttr) {
         if (Strings.isNonBlank(oldValue)) return oldValue;
         if (item!=null) {
@@ -647,6 +660,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         CatalogItemType catalogItemType;
         String planYaml;
         boolean resolved = false;
+        List<SpecParameter<?>> parameters = ImmutableList.of();
         List<Exception> errors = MutableList.of();
         List<Exception> entityErrors = MutableList.of();
         
@@ -684,11 +698,16 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
             if (!resolved && catalogItemType==CatalogItemType.TEMPLATE) {
                 // anything goes, for an explicit template, because we can't easily recurse into the types
                 planYaml = itemYaml;
+                parameters = getItemParameters();
                 resolved = true;
             }
             
             return this;
         }
+
+        private List<SpecParameter<?>> getItemParameters() {
+            return BasicSpecParameter.fromConfigList((List<?>)item.get("brooklyn.parameters"), CatalogUtils.newClassLoadingContext(mgmt, "<template_parameters_parser>", libraryBundles));
+        }
         
         public boolean isResolved() { return resolved; }
         
@@ -734,6 +753,10 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                             // matched - exit
                             catalogItemType = candidateCiType;
                             planYaml = candidateYaml;
+                            parameters = getItemParameters();
+                            if (parameters.isEmpty()) {
+                                parameters = candidate.getParameters();
+                            }
                             resolved = true;
                             return true;
                         }
@@ -749,10 +772,14 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                     .libraries(libraryBundles)
                     .build();
                 @SuppressWarnings("unchecked")
-                Object spec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of());
+                AbstractBrooklynObjectSpec<?, ?> spec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of());
                 if (spec!=null) {
                     catalogItemType = candidateCiType;
                     planYaml = candidateYaml;
+                    parameters = getItemParameters();
+                    if (parameters.isEmpty()) {
+                        parameters = spec.getParameters();
+                    }
                     resolved = true;
                 }
                 return true;
@@ -787,10 +814,11 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                             .libraries(libraryBundles)
                             .build();
                     @SuppressWarnings("unchecked")
-                    Object cutdownSpec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of());
+                    AbstractBrooklynObjectSpec<?, ?> cutdownSpec = internalCreateSpecAttempting(mgmt, itemToAttempt, MutableSet.<String>of());
                     if (cutdownSpec!=null) {
                         catalogItemType = candidateCiType;
                         planYaml = candidateYaml;
+                        parameters = cutdownSpec.getParameters();
                         resolved = true;
                     }
                     return true;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
index 7b2fb53..69ee940 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
@@ -31,14 +31,15 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ImplementedBy;
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.javalang.ReflectionScanner;
 import org.apache.brooklyn.util.core.javalang.UrlClassLoader;
@@ -312,7 +313,7 @@ public class CatalogClasspathDo {
         }
         if (log.isTraceEnabled())
             log.trace("adding to catalog: "+c+" (from catalog "+catalog+")");
-        item.setInputs(getJavaTypeInputs(c));
+        item.setParameters(getJavaTypeParameters(c));
         catalog.addEntry(item);
         return item;
     }
@@ -352,8 +353,8 @@ public class CatalogClasspathDo {
         classloader.addFirst(loader);
     }
 
-    private List<CatalogInput<?>> getJavaTypeInputs(Class<?> c) {
-        return CatalogInputDto.ParseClassInputs.parseInputs(c);
+    private List<SpecParameter<?>> getJavaTypeParameters(Class<?> c) {
+        return BasicSpecParameter.fromClass(catalog.mgmt, c);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
deleted file mode 100644
index c549137..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.catalog.CatalogConfig;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityType;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.core.entity.EntityDynamicType;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.objs.BrooklynTypes;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.text.StringPredicates;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
-
-public class CatalogInputDto<T> implements CatalogInput<T> {
-    private static final String DEFAULT_TYPE = "string";
-    private static final Map<String, Class<?>> BUILT_IN_TYPES = ImmutableMap.<String, Class<?>>builder()
-            .put(DEFAULT_TYPE, String.class)
-            .put("integer", Integer.class)
-            .put("long", Long.class)
-            .put("float", Float.class)
-            .put("double", Double.class)
-            .put("timestamp", Date.class)
-            .build();
-
-    private static final Map<String, Predicate<?>> BUILT_IN_CONSTRAINTS = ImmutableMap.<String, Predicate<?>>of(
-            "required", StringPredicates.isNonBlank());
-
-    private String label;
-    private boolean pinned;
-    private ConfigKey<T> type;
-
-    public CatalogInputDto(String label, boolean pinned, ConfigKey<T> type) {
-        this.label = label;
-        this.pinned = pinned;
-        this.type = type;
-    }
-
-    @Override
-    public String getLabel() {
-        return label;
-    }
-
-    @Override
-    public boolean isPinned() {
-        return pinned;
-    }
-
-    @Override
-    public ConfigKey<T> getType() {
-        return type;
-    }
-
-    public static final class ParseYamlInputs {
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        public static List<CatalogInput<?>> parseInputs(List<?> inputsRaw, BrooklynClassLoadingContext loader) {
-            List<CatalogInput<?>> inputs = new ArrayList<>(inputsRaw.size());
-            for (Object obj : inputsRaw) {
-                Map inputDef;
-                if (obj instanceof String) {
-                    inputDef = ImmutableMap.of("name", obj);
-                } else if (obj instanceof Map) {
-                    inputDef = (Map) obj;
-                } else {
-                    throw new IllegalArgumentException("Catalog input definition expected to be a map, but is " + obj.getClass() + " instead: " + obj);
-                }
-                String name = (String)inputDef.get("name");
-                String label = (String)inputDef.get("label");
-                String description = (String)inputDef.get("description");
-                String type = (String)inputDef.get("type");
-                Object defaultValue = inputDef.get("default");
-                Predicate<?> constraints = parseConstraints(inputDef.get("constraints"), loader);
-
-                if (name == null) {
-                    throw new IllegalArgumentException("'name' value missing from input definition " + obj + " but is required. Check for typos.");
-                }
-
-                ConfigKey inputType = BasicConfigKey.builder(inferType(type, loader))
-                        .name(name)
-                        .description(description)
-                        .defaultValue(defaultValue)
-                        .constraint(constraints)
-                        .build();
-                inputs.add(new CatalogInputDto(Maybe.fromNullable(label).or(name), true, inputType));
-            }
-            return inputs;
-        }
-
-        @SuppressWarnings({ "rawtypes" })
-        private static TypeToken inferType(String typeRaw, BrooklynClassLoadingContext loader) {
-            if (typeRaw == null) return TypeToken.of(String.class);
-            String type = typeRaw.trim();
-            if (BUILT_IN_TYPES.containsKey(type)) {
-                return TypeToken.of(BUILT_IN_TYPES.get(type));
-            } else {
-                // Assume it's a Java type
-                Maybe<Class<?>> inputType = loader.tryLoadClass(type);
-                if (inputType.isPresent()) {
-                    return TypeToken.of(inputType.get());
-                } else {
-                    throw new IllegalArgumentException("The type '" + type + "' for a catalog input not recognised as a built-in (" + BUILT_IN_TYPES.keySet() + ") or a java type");
-                }
-            }
-        }
-    
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        private static Predicate parseConstraints(Object obj, BrooklynClassLoadingContext loader) {
-            List constraintsRaw;
-            if (obj == null) {
-                constraintsRaw = ImmutableList.of();
-            } else if (obj instanceof String) {
-                constraintsRaw = ImmutableList.of(obj);
-            } else if (obj instanceof List) {
-                constraintsRaw = (List) obj;
-            } else {
-                throw new IllegalArgumentException ("The constraint '" + obj + "' for a catalog input is invalid format - string or list supported");
-            }
-            List<Predicate> constraints = new ArrayList(constraintsRaw.size());
-            for (Object untypedConstraint : constraintsRaw) {
-                String constraint = (String)untypedConstraint;
-                if (BUILT_IN_CONSTRAINTS.containsKey(constraint)) {
-                    constraints.add(BUILT_IN_CONSTRAINTS.get(constraint));
-                } else {
-                    throw new IllegalArgumentException("The constraint '" + constraint + "' for a catalog input is not recognized as a built-in (" + BUILT_IN_CONSTRAINTS.keySet() + ")");
-                }
-            }
-            if (!constraints.isEmpty()) {
-                if (constraints.size() == 1) {
-                    return constraints.get(0);
-                } else {
-                    return Predicates.and((List<Predicate<Object>>)(List) constraints);
-                }
-            } else {
-                return Predicates.alwaysTrue();
-            }
-        }
-    }
-
-    public static final class ParseClassInputs {
-        private static final class WeightedCatalogInput {
-            private Double weight;
-            private CatalogInput<?> input;
-            public WeightedCatalogInput(Double weight, CatalogInput<?> input) {
-                this.weight = weight;
-                this.input = input;
-            }
-            public Double getWeight() {return weight; }
-            public CatalogInput<?> getInput() { return input; }
-        }
-        private static final class InputsComparator implements Comparator<WeightedCatalogInput> {
-            @Override
-            public int compare(WeightedCatalogInput o1, WeightedCatalogInput o2) {
-                if (o1.getWeight() == o2.getWeight()) {
-                    return 0;
-                } else if (o1.getWeight() == null) {
-                    return 1;
-                } else if (o2.getWeight() == null) {
-                    return -1;
-                } else {
-                    return Double.compare(o1.getWeight(),  o2.getWeight());
-                }
-            }
-        }
-        private static final class InputsTransformer implements Function<WeightedCatalogInput, CatalogInput<?>> {
-            @Override
-            public CatalogInput<?> apply(WeightedCatalogInput input) {
-                return input.getInput();
-            }
-        }
-
-        public static List<CatalogInput<?>> parseInputs(Class<?> c) {
-            MutableList<WeightedCatalogInput> inputs = MutableList.<WeightedCatalogInput>of();
-            if (Entity.class.isAssignableFrom(c)) {
-                @SuppressWarnings("unchecked")
-                Class<? extends Entity> entityClass = (Class<? extends Entity>) c;
-                EntityDynamicType dynamicType = BrooklynTypes.getDefinedEntityType(entityClass);
-                EntityType type = dynamicType.getSnapshot();
-                for (ConfigKey<?> x: type.getConfigKeys()) {
-                    WeightedCatalogInput fieldConfig = getFieldConfig(x, dynamicType.getConfigKeyField(x.getName()));
-                    inputs.appendIfNotNull(fieldConfig);
-                }
-                Collections.sort(inputs, new InputsComparator());
-                return FluentIterable.from(inputs)
-                        .transform(new InputsTransformer()).toList();
-            } else {
-                return ImmutableList.<CatalogInput<?>>of();
-            }
-        }
-
-        public static WeightedCatalogInput getFieldConfig(ConfigKey<?> config, Field configKeyField) {
-            if (configKeyField == null) return null;
-            CatalogConfig catalogConfig = configKeyField.getAnnotation(CatalogConfig.class);
-            String label = config.getName();
-            Double priority = null;
-            if (catalogConfig != null) {
-                label = Maybe.fromNullable(catalogConfig.label()).or(config.getName());
-                priority = catalogConfig.priority();
-            }
-            @SuppressWarnings({ "unchecked", "rawtypes" })
-            CatalogInput<?> input = new CatalogInputDto(label, priority != null, config);
-            return new WeightedCatalogInput(priority, input);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
index f1e4711..1f9b9a2 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
@@ -23,7 +23,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
+import org.apache.brooklyn.api.objs.SpecParameter;
 
 import com.google.common.base.Preconditions;
 
@@ -106,8 +106,8 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
         return this;
     }
 
-    public CatalogItemBuilder<CatalogItemType> inputs(List<CatalogInput<?>> inputs) {
-        dto.setInputs(inputs);
+    public CatalogItemBuilder<CatalogItemType> parameters(List<SpecParameter<?>> inputs) {
+        dto.setParameters(inputs);
         return this;
     }
 
@@ -125,8 +125,8 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
         Preconditions.checkNotNull(dto.getSymbolicName());
         Preconditions.checkNotNull(dto.getVersion());
 
-        if (dto.getInputs() == null) {
-            dto.setInputs(Collections.<CatalogInput<?>>emptyList());
+        if (dto.getParameters() == null) {
+            dto.setParameters(Collections.<SpecParameter<?>>emptyList());
         }
         if (dto.getLibraries() == null) {
             dto.setLibraries(Collections.<CatalogBundle>emptyList());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
index e053374..4224cb9 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.core.relations.EmptyRelationSupport;
@@ -179,8 +180,8 @@ public class CatalogItemDo<T,SpecT> implements CatalogItem<T,SpecT>, BrooklynObj
     }
 
     @Override
-    public List<CatalogInput<?>> getInputs() {
-        return itemDto.getInputs();
+    public List<SpecParameter<?>> getParameters() {
+        return itemDto.getParameters();
     }
 
     @Nonnull  // but it is still null sometimes, see in CatalogDo.loadJavaClass

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
index e95b0dd..d891ae1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
@@ -18,6 +18,8 @@
  */
 package org.apache.brooklyn.core.catalog.internal;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -30,6 +32,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.mgmt.rebind.BasicCatalogItemRebindSupport;
 import org.apache.brooklyn.core.objs.AbstractBrooklynObject;
@@ -62,7 +65,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     private @Deprecated @SetFromFlag String type;
     private @SetFromFlag String planYaml;
 
-    private @SetFromFlag List<CatalogInput<?>> inputs;
+    private @SetFromFlag List<SpecParameter<?>> parameters = ImmutableList.of();
     private @SetFromFlag Collection<CatalogBundle> libraries;
     private @SetFromFlag Set<Object> tags = Sets.newLinkedHashSet();
     private @SetFromFlag boolean deprecated;
@@ -176,8 +179,13 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     }
     
     @Override
-    public List<CatalogInput<?>> getInputs() {
-        return inputs;
+    public List<SpecParameter<?>> getParameters() {
+        if (parameters != null) {
+            return parameters;
+        } else {
+            // Needed for the case when created by xstream
+            return ImmutableList.of();
+        }
     }
 
     @Nonnull
@@ -197,7 +205,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(symbolicName, planYaml, javaType, nullIfEmpty(inputs), nullIfEmpty(libraries), version, getCatalogItemId());
+        return Objects.hashCode(symbolicName, planYaml, javaType, nullIfEmpty(parameters), nullIfEmpty(libraries), version, getCatalogItemId());
     }
 
     @Override
@@ -209,7 +217,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         if (!Objects.equal(symbolicName, other.symbolicName)) return false;
         if (!Objects.equal(planYaml, other.planYaml)) return false;
         if (!Objects.equal(javaType, other.javaType)) return false;
-        if (!Objects.equal(nullIfEmpty(inputs), nullIfEmpty(other.inputs))) return false;
+        if (!Objects.equal(nullIfEmpty(parameters), nullIfEmpty(other.parameters))) return false;
         if (!Objects.equal(nullIfEmpty(libraries), nullIfEmpty(other.libraries))) return false;
         if (!Objects.equal(getCatalogItemId(), other.getCatalogItemId())) return false;
         if (!Objects.equal(version, other.version)) return false;
@@ -382,8 +390,8 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         this.planYaml = planYaml;
     }
 
-    protected void setInputs(List<CatalogInput<?>> inputs) {
-        this.inputs = inputs;
+    protected void setParameters(List<SpecParameter<?>> parameters) {
+        this.parameters = checkNotNull(parameters, "parameters");
     }
 
     protected void setLibraries(Collection<CatalogBundle> libraries) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java
index 7df9adf..519bb23 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.core.plan.PlanNotRecognizedException;
 import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
 import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -71,29 +72,32 @@ public class JavaCatalogToSpecTransformer implements PlanToSpecTransformer {
     @Override
     public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(
             CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws PlanNotRecognizedException {
-        if (item.getJavaType() != null) {
+        @SuppressWarnings("deprecation")
+        String javaType = item.getJavaType();
+        if (javaType != null) {
             log.warn("Deprecated functionality (since 0.9.0). Using old-style xml catalog items with java type attribute for " + item);
             Class<?> type;
             try {
                 // java types were deprecated before we added osgi support so this isn't necessary,
                 // but it doesn't hurt (and if we re-instate a class+bundle approach for RegisteredType 
                 // we will want to do this)
-                type = CatalogUtils.newClassLoadingContext(mgmt, item).loadClass(item.getJavaType());
+                type = CatalogUtils.newClassLoadingContext(mgmt, item).loadClass(javaType);
             } catch (Exception e) {
                 Exceptions.propagateIfFatal(e);
-                throw new IllegalStateException("Unable to load old-style java catalog item type " + item.getJavaType() + " for item " + item, e);
+                throw new IllegalStateException("Unable to load old-style java catalog item type " + javaType + " for item " + item, e);
             }
             AbstractBrooklynObjectSpec<?,?> spec;
             if (Entity.class.isAssignableFrom(type)) {
                 @SuppressWarnings("unchecked")
                 Class<Entity> entityType = (Class<Entity>)type;
-                spec = EntitySpec.create(entityType);
+                spec = EntitySpec.create(entityType)
+                        .parameters(BasicSpecParameter.fromClass(mgmt, entityType));
             } else if (Policy.class.isAssignableFrom(type)) {
                 @SuppressWarnings("unchecked")
                 Class<Policy> policyType = (Class<Policy>)type;
                 spec = PolicySpec.create(policyType);
             } else {
-                throw new IllegalStateException("Catalog item " + item + " java type " + item.getJavaType() + " is not a Brooklyn supported object.");
+                throw new IllegalStateException("Catalog item " + item + " java type " + javaType + " is not a Brooklyn supported object.");
             }
             spec.catalogItemId(item.getCatalogItemId());
             @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 09b362d..36b425f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -44,6 +44,7 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
@@ -95,6 +96,7 @@ import org.apache.brooklyn.util.core.flags.FlagUtils;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.task.DeferredSupplier;
 import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.guava.TypeTokens;
 import org.apache.brooklyn.util.javalang.Equals;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.commons.lang3.builder.EqualsBuilder;
@@ -152,8 +154,10 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     public static final BasicNotificationSensor<Location> LOCATION_REMOVED = new BasicNotificationSensor<Location>(
             Location.class, "entity.location.removed", "Location dynamically removed from entity");
 
+    @SuppressWarnings("rawtypes")
     public static final BasicNotificationSensor<Sensor> SENSOR_ADDED = new BasicNotificationSensor<Sensor>(Sensor.class,
             "entity.sensor.added", "Sensor dynamically added to entity");
+    @SuppressWarnings("rawtypes")
     public static final BasicNotificationSensor<Sensor> SENSOR_REMOVED = new BasicNotificationSensor<Sensor>(Sensor.class,
             "entity.sensor.removed", "Sensor dynamically removed from entity");
 
@@ -164,6 +168,13 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     public static final BasicNotificationSensor<String> EFFECTOR_CHANGED = new BasicNotificationSensor<String>(String.class,
             "entity.effector.changed", "Effector dynamically changed on entity");
 
+    @SuppressWarnings("rawtypes")
+    public static final BasicNotificationSensor<ConfigKey> CONFIG_KEY_ADDED = new BasicNotificationSensor<ConfigKey>(ConfigKey.class,
+            "entity.config_key.added", "ConfigKey dynamically added to entity");
+    @SuppressWarnings("rawtypes")
+    public static final BasicNotificationSensor<ConfigKey> CONFIG_KEY_REMOVED = new BasicNotificationSensor<ConfigKey>(ConfigKey.class,
+            "entity.config_key.removed", "ConfigKey dynamically removed from entity");
+
     public static final BasicNotificationSensor<PolicyDescriptor> POLICY_ADDED = new BasicNotificationSensor<PolicyDescriptor>(PolicyDescriptor.class,
             "entity.policy.added", "Policy dynamically added to entity");
     public static final BasicNotificationSensor<PolicyDescriptor> POLICY_REMOVED = new BasicNotificationSensor<PolicyDescriptor>(PolicyDescriptor.class,
@@ -387,6 +398,14 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
         return this;
     }
 
+    /**
+     * Adds the config keys to the entity dynamic type
+     * @since 0.9.0
+     */
+    public void configure(Iterable<ConfigKey<?>> configKeys) {
+        entityType.addConfigKeys(configKeys);
+    }
+
     @Override
     public int hashCode() {
         return getId().hashCode();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
index 3634f73..69e8caa 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
 import org.apache.brooklyn.core.effector.EffectorAndBody;
 import org.apache.brooklyn.core.effector.EffectorBody;
@@ -97,6 +98,7 @@ public class EntityDynamicType extends BrooklynDynamicType<Entity, AbstractEntit
         return super.getBrooklynClass();
     }
     
+    @Override
     public EntityType getSnapshot() {
         return (EntityType) super.getSnapshot();
     }
@@ -232,6 +234,41 @@ public class EntityDynamicType extends BrooklynDynamicType<Entity, AbstractEntit
     
     // --------------------------------------------------
     
+    /**
+     * Adds the given {@link ConfigKey} to this entity.
+     */
+    public void addConfigKey(ConfigKey<?> newKey) {
+        configKeys.put(newKey.getName(), new FieldAndValue<ConfigKey<?>>(null, newKey));
+        invalidateSnapshot();
+        instance.sensors().emit(AbstractEntity.CONFIG_KEY_ADDED, newKey);
+    }
+    
+    /**
+     * Adds the given {@link ConfigKey} to this entity.
+     */
+    public void addConfigKeys(Iterable<ConfigKey<?>> newKeys) {
+        for (ConfigKey<?> newKey : newKeys) {
+            addConfigKey(newKey);
+        }
+    }
+
+    /**
+     * Removes the named {@link ConfigKey} from this entity.
+     */
+    public boolean removeConfigKey(ConfigKey<?> key) {
+        FieldAndValue<ConfigKey<?>> result = configKeys.remove(key.getName());
+        if (result != null) {
+            invalidateSnapshot();
+            ConfigKey<?> removedKey = result.value;
+            instance.sensors().emit(AbstractEntity.CONFIG_KEY_REMOVED, removedKey);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    // --------------------------------------------------
+    
     @Override
     protected EntityTypeSnapshot newSnapshot() {
         return new EntityTypeSnapshot(name, value(configKeys), sensors, effectors.values());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index 9c4ebc1..4081177 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -59,6 +59,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Runnables;
 
 /** Utility methods for working with entities and applications */
 public class EntityManagementUtils {
@@ -215,7 +216,7 @@ public class EntityManagementUtils {
             } else {
                 // include a task, just to give feedback in the GUI
                 taskS.add(Tasks.builder().displayName("create").description("Skipping start (not a Startable Entity)")
-                    .body(new Runnable() { public void run() {} })
+                    .body(Runnables.doNothing())
                     .tag(BrooklynTaskTags.tagForTargetEntity(child))
                     .build());
             }
@@ -250,6 +251,9 @@ public class EntityManagementUtils {
             wrappedChild.displayName(wrapperParent.getDisplayName());
         if (!wrapperParent.getLocations().isEmpty())
             wrappedChild.locations(wrapperParent.getLocations());
+        if (!wrapperParent.getParameters().isEmpty()) {
+            wrappedChild.parameters(wrapperParent.getParameters());
+        }
 
         // NB: this clobbers child config; might prefer to deeply merge maps etc
         // (but this should not be surprising, as unwrapping is often parameterising the nested blueprint, so outer config should dominate) 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
new file mode 100644
index 0000000..d2703ff
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.objs;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.catalog.CatalogConfig;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.BrooklynType;
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.StringPredicates;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+
+public class BasicSpecParameter<T> implements SpecParameter<T>{
+    private static final long serialVersionUID = -4728186276307619778L;
+
+    private String label;
+    private boolean pinned;
+    private ConfigKey<T> type;
+
+    public BasicSpecParameter(String label, boolean pinned, ConfigKey<T> type) {
+        this.label = label;
+        this.pinned = pinned;
+        this.type = type;
+    }
+
+    @Override
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public boolean isPinned() {
+        return pinned;
+    }
+
+    @Override
+    public ConfigKey<T> getType() {
+        return type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(label, pinned, type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        BasicSpecParameter<?> other = (BasicSpecParameter<?>) obj;
+        return Objects.equal(label,  other.label) &&
+                pinned == other.pinned &&
+                Objects.equal(type, other.type);
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this)
+                .add("label", label)
+                .add("pinned", pinned)
+                .add("type", type)
+                .toString();
+    }
+
+    // Not CAMP specific since it's used to get the parameters from catalog items meta which are syntax independent.
+    public static List<SpecParameter<?>> fromConfigList(List<?> obj, BrooklynClassLoadingContext loader) {
+        return ParseYamlInputs.parseParameters(obj, loader);
+    }
+
+    public static List<SpecParameter<?>> fromClass(ManagementContext mgmt, Class<?> type) {
+        return ParseClassParameters.parseParameters(getImplementedBy(mgmt, type));
+    }
+
+    public static List<SpecParameter<?>> fromSpec(ManagementContext mgmt, AbstractBrooklynObjectSpec<?, ?> spec) {
+        if (!spec.getParameters().isEmpty()) {
+            return spec.getParameters();
+        }
+        Class<?> type = null;
+        if (spec instanceof EntitySpec) {
+            EntitySpec<?> entitySpec = (EntitySpec<?>)spec;
+            if (entitySpec.getImplementation() != null) {
+                type = entitySpec.getImplementation();
+            }
+        }
+        if (type == null) {
+            type = getImplementedBy(mgmt, spec.getType());
+        }
+        return ParseClassParameters.parseParameters(getImplementedBy(mgmt, type));
+    }
+
+    private static Class<?> getImplementedBy(ManagementContext mgmt, Class<?> type) {
+        if (Entity.class.isAssignableFrom(type) && type.isInterface()) {
+            try {
+                @SuppressWarnings("unchecked")
+                Class<? extends Entity> uncheckedType = ParseClassParameters.getEntityImplementedBy(mgmt, (Class<Entity>)type);
+                return uncheckedType;
+            } catch(IllegalArgumentException e) {
+                // NOP, no implementation for type, use whatever we have
+            }
+        }
+        return type;
+    }
+
+    private static final class ParseYamlInputs {
+        private static final String DEFAULT_TYPE = "string";
+        private static final Map<String, Class<?>> BUILT_IN_TYPES = ImmutableMap.<String, Class<?>>builder()
+                .put(DEFAULT_TYPE, String.class)
+                .put("integer", Integer.class)
+                .put("long", Long.class)
+                .put("float", Float.class)
+                .put("double", Double.class)
+                .put("timestamp", Date.class)
+                .build();
+
+        private static final Map<String, Predicate<?>> BUILT_IN_CONSTRAINTS = ImmutableMap.<String, Predicate<?>>of(
+                "required", StringPredicates.isNonBlank());
+
+        public static List<SpecParameter<?>> parseParameters(List<?> inputsRaw, BrooklynClassLoadingContext loader) {
+            if (inputsRaw == null) return ImmutableList.of();
+            List<SpecParameter<?>> inputs = new ArrayList<>(inputsRaw.size());
+            for (Object obj : inputsRaw) {
+                inputs.add(parseParameter(obj, loader));
+            }
+            return inputs;
+        }
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        private static SpecParameter<?> parseParameter(Object obj, BrooklynClassLoadingContext loader) {
+            Map inputDef;
+            if (obj instanceof String) {
+                inputDef = ImmutableMap.of("name", obj);
+            } else if (obj instanceof Map) {
+                inputDef = (Map) obj;
+            } else {
+                throw new IllegalArgumentException("Catalog input definition expected to be a map, but is " + obj.getClass() + " instead: " + obj);
+            }
+            String name = (String)inputDef.get("name");
+            String label = (String)inputDef.get("label");
+            String description = (String)inputDef.get("description");
+            String type = (String)inputDef.get("type");
+            Object defaultValue = inputDef.get("default");
+            Predicate<?> constraints = parseConstraints(inputDef.get("constraints"), loader);
+
+            if (name == null) {
+                throw new IllegalArgumentException("'name' value missing from input definition " + obj + " but is required. Check for typos.");
+            }
+
+            ConfigKey inputType = BasicConfigKey.builder(inferType(type, loader))
+                    .name(name)
+                    .description(description)
+                    .defaultValue(defaultValue)
+                    .constraint(constraints)
+                    .build();
+            return new BasicSpecParameter(Objects.firstNonNull(label, name), true, inputType);
+        }
+
+        @SuppressWarnings({ "rawtypes" })
+        private static TypeToken inferType(String typeRaw, BrooklynClassLoadingContext loader) {
+            if (typeRaw == null) return TypeToken.of(String.class);
+            String type = typeRaw.trim();
+            if (BUILT_IN_TYPES.containsKey(type)) {
+                return TypeToken.of(BUILT_IN_TYPES.get(type));
+            } else {
+                // Assume it's a Java type
+                Maybe<Class<?>> inputType = loader.tryLoadClass(type);
+                if (inputType.isPresent()) {
+                    return TypeToken.of(inputType.get());
+                } else {
+                    throw new IllegalArgumentException("The type '" + type + "' for a catalog input not recognised as a built-in (" + BUILT_IN_TYPES.keySet() + ") or a java type");
+                }
+            }
+        }
+    
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        private static Predicate parseConstraints(Object obj, BrooklynClassLoadingContext loader) {
+            List constraintsRaw;
+            if (obj == null) {
+                constraintsRaw = ImmutableList.of();
+            } else if (obj instanceof String) {
+                constraintsRaw = ImmutableList.of(obj);
+            } else if (obj instanceof List) {
+                constraintsRaw = (List) obj;
+            } else {
+                throw new IllegalArgumentException ("The constraint '" + obj + "' for a catalog input is invalid format - string or list supported");
+            }
+            List<Predicate> constraints = new ArrayList(constraintsRaw.size());
+            for (Object untypedConstraint : constraintsRaw) {
+                String constraint = (String)untypedConstraint;
+                if (BUILT_IN_CONSTRAINTS.containsKey(constraint)) {
+                    constraints.add(BUILT_IN_CONSTRAINTS.get(constraint));
+                } else {
+                    throw new IllegalArgumentException("The constraint '" + constraint + "' for a catalog input is not recognized as a built-in (" + BUILT_IN_CONSTRAINTS.keySet() + ")");
+                }
+            }
+            if (!constraints.isEmpty()) {
+                if (constraints.size() == 1) {
+                    return constraints.get(0);
+                } else {
+                    return Predicates.and((List<Predicate<Object>>)(List) constraints);
+                }
+            } else {
+                return Predicates.alwaysTrue();
+            }
+        }
+    }
+
+    private static final class ParseClassParameters {
+        private static final class WeightedParameter {
+            private Double weight;
+            private SpecParameter<?> input;
+            public WeightedParameter(Double weight, SpecParameter<?> input) {
+                this.weight = weight;
+                this.input = input;
+            }
+            public Double getWeight() {return weight; }
+            public SpecParameter<?> getInput() { return input; }
+        }
+        private static final class WeightedParameterComparator implements Comparator<WeightedParameter> {
+            @Override
+            public int compare(WeightedParameter o1, WeightedParameter o2) {
+                if (o1.getWeight() == o2.getWeight()) {
+                    return 0;
+                } else if (o1.getWeight() == null) {
+                    return 1;
+                } else if (o2.getWeight() == null) {
+                    return -1;
+                } else {
+                    return Double.compare(o1.getWeight(),  o2.getWeight());
+                }
+            }
+        }
+        private static final class SpecParameterTransformer implements Function<WeightedParameter, SpecParameter<?>> {
+            @Override
+            public SpecParameter<?> apply(WeightedParameter input) {
+                return input.getInput();
+            }
+        }
+
+        public static List<SpecParameter<?>> parseParameters(Class<?> c) {
+            MutableList<WeightedParameter> parameters = MutableList.<WeightedParameter>of();
+            if (BrooklynObject.class.isAssignableFrom(c)) {
+                @SuppressWarnings("unchecked")
+                Class<? extends BrooklynObject> brooklynClass = (Class<? extends BrooklynObject>) c;
+                BrooklynDynamicType<?, ?> dynamicType = BrooklynTypes.getDefinedBrooklynType(brooklynClass);
+                BrooklynType type = dynamicType.getSnapshot();
+                for (ConfigKey<?> x: type.getConfigKeys()) {
+                    WeightedParameter fieldConfig = getFieldConfig(x, dynamicType.getConfigKeyField(x.getName()));
+                    parameters.appendIfNotNull(fieldConfig);
+                }
+                Collections.sort(parameters, new WeightedParameterComparator());
+                return FluentIterable.from(parameters)
+                        .transform(new SpecParameterTransformer()).toList();
+            } else {
+                return ImmutableList.of();
+            }
+        }
+
+        public static WeightedParameter getFieldConfig(ConfigKey<?> config, Field configKeyField) {
+            if (configKeyField == null) return null;
+            CatalogConfig catalogConfig = configKeyField.getAnnotation(CatalogConfig.class);
+            String label = config.getName();
+            Double priority = null;
+            if (catalogConfig != null) {
+                label = Maybe.fromNullable(catalogConfig.label()).or(config.getName());
+                priority = catalogConfig.priority();
+            }
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            SpecParameter<?> param = new BasicSpecParameter(label, priority != null, config);
+            return new WeightedParameter(priority, param);
+        }
+
+        private static <T extends Entity> Class<? extends T> getEntityImplementedBy(ManagementContext mgmt, Class<T> type) {
+            return mgmt.getEntityManager().getEntityTypeRegistry().getImplementedBy(type);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
index 9552583..3b0795b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalEntityFactory.java
@@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkState;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Queue;
 import java.util.Set;
@@ -33,6 +34,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.entity.EntityTypeRegistry;
 import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.Enricher;
@@ -46,6 +48,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.flags.FlagUtils;
@@ -243,6 +246,7 @@ public class InternalEntityFactory extends InternalFactory {
             }
             
             entity.tags().addTags(spec.getTags());
+            ((AbstractEntity)entity).configure(getConfigKeysFromSpecParameters(spec));
             ((AbstractEntity)entity).configure(MutableMap.copyOf(spec.getFlags()));
             
             for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) {
@@ -262,6 +266,14 @@ public class InternalEntityFactory extends InternalFactory {
         }
     }
 
+    private <T extends Entity> List<ConfigKey<?>> getConfigKeysFromSpecParameters(EntitySpec<T> spec) {
+        List<ConfigKey<?>> configKeys = MutableList.of();
+        for (SpecParameter<?> param : spec.getParameters()) {
+            configKeys.add(param.getType());
+        }
+        return configKeys;
+    }
+
     /**
      * Calls {@link ConfigConstraints#assertValid(Entity)} on the given entity and all of
      * its descendants.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/main/java/org/apache/brooklyn/util/core/flags/FlagUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/FlagUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/FlagUtils.java
index f59814e..85c9537 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/FlagUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/FlagUtils.java
@@ -22,9 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
 import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.truth;
 
-import groovy.lang.Closure;
-import groovy.lang.GroovyObject;
-
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
@@ -36,6 +33,7 @@ import java.util.NoSuchElementException;
 import java.util.Set;
 
 import org.apache.brooklyn.api.objs.Configurable;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
 import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -53,6 +51,9 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+import groovy.lang.Closure;
+import groovy.lang.GroovyObject;
+
 
 /** class to help transfer values passed as named arguments to other well-known variables/fields/objects;
  * see the test case for example usage */
@@ -229,17 +230,30 @@ public class FlagUtils {
         return output;
     }
 
+    /** gets all the keys in the given config bag which are applicable to the given list of parameters */
+    public static List<FlagConfigKeyAndValueRecord> findAllParameterConfigKeys(List<SpecParameter<?>> parameters, ConfigBag input) {
+        List<FlagConfigKeyAndValueRecord> output = new ArrayList<FlagUtils.FlagConfigKeyAndValueRecord>();
+        for (SpecParameter<?> param : parameters) {
+            FlagConfigKeyAndValueRecord record = getFlagConfigKeyRecord(null, param.getType(), input);
+            if (record.isValuePresent())
+                output.add(record);
+        }
+        return output;
+    }
+
     /** returns the flag/config-key record for the given input */
     private static FlagConfigKeyAndValueRecord getFlagConfigKeyRecord(Field f, ConfigKey<?> key, ConfigBag input) {
         FlagConfigKeyAndValueRecord result = new FlagConfigKeyAndValueRecord(); 
         result.configKey = key;
         if (key!=null && input.containsKey(key))
             result.configKeyValue = Maybe.<Object>of(input.getStringKey(key.getName()));
-        SetFromFlag flag = f.getAnnotation(SetFromFlag.class);
-        if (flag!=null) {
-            result.flagName = flag.value();
-            if (input.containsKey(flag.value()))
-                result.flagValue = Maybe.of(input.getStringKey(flag.value()));
+        if (f != null) {
+            SetFromFlag flag = f.getAnnotation(SetFromFlag.class);
+            if (flag!=null) {
+                result.flagName = flag.value();
+                if (input.containsKey(flag.value()))
+                    result.flagValue = Maybe.of(input.getStringKey(flag.value()));
+            }
         }
         return result;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
deleted file mode 100644
index 7602c2a..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.catalog.CatalogConfig;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.reflect.TypeToken;
-
-public class CatalogInputDtoClassTest {
-    public interface CatalogInputTestEntity extends Entity {
-        @CatalogConfig(label="String Key", priority=3)
-        ConfigKey<String> STRING_KEY = ConfigKeys.newStringConfigKey("string_key");
-
-        @CatalogConfig(label="Integer Key", priority=2)
-        ConfigKey<Integer> INTEGER_KEY = ConfigKeys.newIntegerConfigKey("integer_key");
-
-        @SuppressWarnings("serial")
-        @CatalogConfig(label="Predicate Key", priority=1)
-        ConfigKey<Predicate<String>> PREDICATE_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "predicate_key");
-
-        ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key");
-    }
-
-    @Test
-    public void testFullDefinition() {
-        List<CatalogInput<?>> inputs = CatalogInputDto.ParseClassInputs.parseInputs(CatalogInputTestEntity.class);
-        assertInput(inputs.get(0), "Predicate Key", true, CatalogInputTestEntity.PREDICATE_KEY);
-        assertInput(inputs.get(1), "Integer Key", true, CatalogInputTestEntity.INTEGER_KEY);
-        assertInput(inputs.get(2), "String Key", true, CatalogInputTestEntity.STRING_KEY);
-        assertInput(inputs.get(3), "unpinned_key", false, CatalogInputTestEntity.UNPINNNED_KEY);
-    }
-
-    private void assertInput(CatalogInput<?> input, String label, boolean pinned, ConfigKey<?> type) {
-        assertEquals(input.getLabel(), label);
-        assertEquals(input.isPinned(), pinned);
-        assertEquals(input.getType(), type);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
deleted file mode 100644
index 6e65904..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.util.text.StringPredicates;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-public class CatalogInputDtoYamlTest {
-    private ManagementContext mgmt;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        mgmt = LocalManagementContextForTests.newInstance();
-    }
-
-    @Test
-    public void testInlineName() {
-        String name = "minRam";
-        CatalogInput<?> input = parse(name);
-        assertEquals(input.getLabel(), name);
-        assertTrue(input.isPinned());
-        ConfigKey<?> type = input.getType();
-        assertEquals(type.getName(), name);
-        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
-        assertNull(type.getDefaultValue());
-        assertNull(type.getDescription());
-        assertNull(type.getInheritance());
-        assertConstraint(type.getConstraint(), Predicates.alwaysTrue());
-    }
-
-    @Test
-    public void testOnlyName() {
-        String name = "minRam";
-        CatalogInput<?> input = parse(ImmutableMap.of("name", name));
-        assertEquals(input.getLabel(), name);
-        assertEquals(input.getType().getName(), name);
-        assertEquals(input.getType().getTypeToken(), TypeToken.of(String.class));
-    }
-
-    @Test
-    public void testUnusualName() {
-        parse(ImmutableMap.of("name", "name with spaces"));
-    }
-
-    @Test
-    public void testFullDefinition() {
-        String name = "minRam";
-        String label = "Minimum Ram";
-        String description = "Some description";
-        String inputType = "string";
-        String defaultValue = "VALUE";
-        String constraint = "required";
-        CatalogInput<?> input = parse(ImmutableMap.builder()
-                .put("name", name)
-                .put("label", label)
-                .put("description", description)
-                .put("type", inputType)
-                .put("default", defaultValue)
-                .put("constraints", constraint)
-                .build());
-
-        assertEquals(input.getLabel(), label);
-        assertTrue(input.isPinned());
-
-        ConfigKey<?> type = input.getType();
-        assertEquals(type.getName(), name);
-        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
-        assertEquals(type.getDefaultValue(), defaultValue);
-        assertEquals(type.getDescription(), description);
-        assertNull(type.getInheritance());
-        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
-    }
-
-    @Test
-    public void testUnexpectedType() {
-        String name = "1234";
-        String label = "1234";
-        String description = "5678.56";
-        String defaultValue = "444.12";
-        CatalogInput<?> input = parse(ImmutableMap.of(
-                "name", name,
-                "label", label,
-                "description", description,
-                "default", defaultValue));
-
-        assertEquals(input.getLabel(), name);
-        assertTrue(input.isPinned());
-
-        ConfigKey<?> type = input.getType();
-        assertEquals(type.getName(), name);
-        assertEquals(type.getDefaultValue(), defaultValue);
-        assertEquals(type.getDescription(), description);
-        assertNull(type.getInheritance());
-    }
-
-    @Test
-    public void testConstraintAsArray() {
-        String name = "minRam";
-        String constraint = "required";
-        CatalogInput<?> input = parse(ImmutableMap.of(
-                "name", name,
-                "constraints", ImmutableList.of(constraint)));
-        ConfigKey<?> type = input.getType();
-        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
-    }
-
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void testMissingName() {
-        parse(ImmutableMap.of(
-                "type", "string"));
-    }
-
-    @Test
-    public void testJavaType() {
-        String name = "minRam";
-        CatalogInput<?> input = parse(ImmutableMap.of(
-                "name", name,
-                "type", CatalogInputDtoYamlTest.class.getName()));
-        assertEquals(input.getType().getTypeToken(), TypeToken.of(CatalogInputDtoYamlTest.class));
-    }
-
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void testInvalidType() {
-        String name = "minRam";
-        parse(ImmutableMap.of(
-                "name", name,
-                "type", "missing_type"));
-    }
-
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void testInvalidConstraint() {
-        String name = "minRam";
-        parse(ImmutableMap.of(
-                "name", name,
-                "type", "missing_type"));
-    }
-
-    private CatalogInput<?> parse(Object def) {
-        BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
-        List<CatalogInput<?>> inputs = CatalogInputDto.ParseYamlInputs.parseInputs(ImmutableList.of(def), loader);
-        return Iterables.getOnlyElement(inputs);
-    }
-
-    private void assertConstraint(Predicate<?> actual, Predicate<?> expected) {
-        //How to compare predicates correctly, re-creating the same predicate doesn't work
-        assertEquals(actual.toString(), expected.toString());
-    }
-
-}


[11/21] incubator-brooklyn git commit: Improve UI handling of catalog item parameters.

Posted by he...@apache.org.
Improve UI handling of catalog item parameters.


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

Branch: refs/heads/master
Commit: f16cbe0b779af13e7522fdfcb1b2a05b53aee0ca
Parents: 5a69cd6
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Nov 4 13:48:47 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:39 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/core/objs/BasicSpecParameter.java  |  6 ++---
 .../objs/BasicSpecParameterFromClassTest.java   | 27 ++++++++++++++++----
 .../assets/js/view/application-add-wizard.js    | 14 ++++++----
 .../app-add-wizard/required-config-entry.html   |  2 +-
 .../rest/transform/CatalogTransformer.java      |  7 ++---
 5 files changed, 39 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f16cbe0b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
index 5707b8f..e882d79 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
@@ -264,14 +264,14 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
         private static final class WeightedParameterComparator implements Comparator<WeightedParameter> {
             @Override
             public int compare(WeightedParameter o1, WeightedParameter o2) {
-                if (o1.getWeight() == o2.getWeight()) {
-                    return 0;
+                if (o1.getWeight() == null && o2.getWeight() == null) {
+                    return o1.getInput().getLabel().compareTo(o2.getInput().getLabel());
                 } else if (o1.getWeight() == null) {
                     return 1;
                 } else if (o2.getWeight() == null) {
                     return -1;
                 } else {
-                    return Double.compare(o1.getWeight(),  o2.getWeight());
+                    return -Double.compare(o1.getWeight(),  o2.getWeight());
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f16cbe0b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
index b0f71a0..49cb2d6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
@@ -56,7 +56,16 @@ public class BasicSpecParameterFromClassTest {
         @CatalogConfig(label="Predicate Key", priority=1)
         ConfigKey<Predicate<String>> PREDICATE_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "predicate_key");
 
-        ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key");
+        @SuppressWarnings("serial")
+        @CatalogConfig(label="Hidden 1 Key", priority=-1)
+        ConfigKey<Predicate<String>> HIDDEN1_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "hidden1_key");
+
+        @SuppressWarnings("serial")
+        @CatalogConfig(label="Hidden 2 Key", priority=-2)
+        ConfigKey<Predicate<String>> HIDDEN2_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "hidden2_key");
+
+        ConfigKey<String> UNPINNNED2_KEY = ConfigKeys.newStringConfigKey("unpinned2_key");
+        ConfigKey<String> UNPINNNED1_KEY = ConfigKeys.newStringConfigKey("unpinned1_key");
     }
 
     @ImplementedBy(ConfigInImplParameterTestEntityImpl.class)
@@ -68,11 +77,19 @@ public class BasicSpecParameterFromClassTest {
     @Test
     public void testFullDefinition() {
         List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(mgmt, SpecParameterTestEntity.class);
-        assertEquals(inputs.size(), 4);
-        assertInput(inputs.get(0), "Predicate Key", true, SpecParameterTestEntity.PREDICATE_KEY);
+        assertEquals(inputs.size(), 7);
+        assertInput(inputs.get(0), "String Key", true, SpecParameterTestEntity.STRING_KEY);
         assertInput(inputs.get(1), "Integer Key", true, SpecParameterTestEntity.INTEGER_KEY);
-        assertInput(inputs.get(2), "String Key", true, SpecParameterTestEntity.STRING_KEY);
-        assertInput(inputs.get(3), "unpinned_key", false, SpecParameterTestEntity.UNPINNNED_KEY);
+        assertInput(inputs.get(2), "Predicate Key", true, SpecParameterTestEntity.PREDICATE_KEY);
+        assertInput(inputs.get(3), "Hidden 1 Key", true, SpecParameterTestEntity.HIDDEN1_KEY);
+        assertInput(inputs.get(4), "Hidden 2 Key", true, SpecParameterTestEntity.HIDDEN2_KEY);
+        assertInput(inputs.get(5), "unpinned1_key", false, SpecParameterTestEntity.UNPINNNED1_KEY);
+        assertInput(inputs.get(6), "unpinned2_key", false, SpecParameterTestEntity.UNPINNNED2_KEY);
+    }
+    
+    @Test
+    public void testDebug() throws ClassNotFoundException {
+        System.out.println(BasicSpecParameter.fromClass(mgmt,  Class.forName("org.apache.brooklyn.entity.stock.BasicApplication")));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f16cbe0b/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js b/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js
index 850ccf0..77710c2 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/application-add-wizard.js
@@ -517,7 +517,10 @@ define([
         getConfigMap:function (root) {
             var map = {}
             $('.app-add-wizard-config-entry',root).each( function (index,elt) {
-                map[$('#key',elt).val()] = getConvertedConfigValue($('#value',elt).val())
+                var value = getConvertedConfigValue($('#value',elt).val());
+                if (value !== null) {
+                    map[$('#key',elt).val()] = value;
+                }
             })
             return map;
         },
@@ -776,7 +779,6 @@ define([
                         // (others might be included in future with an "expand" option, or priority option)
                     })
                 }
-                configs = configs.sort( function(a,b) { return b.priority - a.priority } )
                 for (var c in configs) {
                     that.$('.config-table').append(configs[c].html)
                 }
@@ -786,9 +788,11 @@ define([
         getConfigMap:function() {
             var map = {};
             $('.app-add-wizard-config-entry').each( function (index,elt) {
-                map[$('#key',elt).val()] = 
-                    $('#checkboxValue',elt).length ? $('#checkboxValue',elt).is(':checked') :
-                    getConvertedConfigValue($('#value',elt).val())
+                var value = $('#checkboxValue',elt).length ? $('#checkboxValue',elt).is(':checked') :
+                    getConvertedConfigValue($('#value',elt).val());
+                if (value !== null) {
+                    map[$('#key',elt).val()] = value;
+                }
             })
             return map;
         },

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f16cbe0b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
index b802624..45c8770 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/app-add-wizard/required-config-entry.html
@@ -39,7 +39,7 @@ under the License.
       </select>
     <% } else { %>
      <input id="value" type="text" class="input-medium" name="value" value="<% 
-        if (typeof data.defaultValue !== "undefined") { %><%= data.defaultValue %><% } 
+        if (typeof data.defaultValue !== "undefined") { %><%- data.defaultValue %><% } 
         %>" style="width: 250px">
     <% } %>
     </td>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f16cbe0b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
index 4d72cf8..58bc473 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
@@ -59,18 +59,19 @@ public class CatalogTransformer {
     private static final org.slf4j.Logger log = LoggerFactory.getLogger(CatalogTransformer.class);
     
     public static <T extends Entity> CatalogEntitySummary catalogEntitySummary(BrooklynRestResourceUtils b, CatalogItem<T,EntitySpec<? extends T>> item) {
-        Set<EntityConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
+        Set<EntityConfigSummary> config = Sets.newLinkedHashSet();
         Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
         Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());
 
+        for (SpecParameter<?> input: item.getParameters())
+            config.add(EntityTransformer.entityConfigSummary(input));
+
         try {
             @SuppressWarnings({ "unchecked", "rawtypes" })
             EntitySpec<?> spec = (EntitySpec<?>) b.getCatalog().createSpec((CatalogItem) item);
             EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType());
             EntityType type = typeMap.getSnapshot();
 
-            for (SpecParameter<?> input: item.getParameters())
-                config.add(EntityTransformer.entityConfigSummary(input));
             for (Sensor<?> x: type.getSensors())
                 sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
             for (Effector<?> x: type.getEffectors())


[08/21] incubator-brooklyn git commit: Parameter aware specs

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
deleted file mode 100644
index 8b477b9..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.mgmt.osgi.OsgiTestResources;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.test.support.TestResourceUnavailableException;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-public class CatalogInputTest {
-    private ManagementContext mgmt;
-    private BrooklynCatalog catalog;
-    private String spec;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        mgmt = LocalManagementContextForTests.newInstanceWithOsgi();
-        catalog = mgmt.getCatalog();
-        spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class));
-    }
-
-    @Test
-    public void testYamlInputsParsed() {
-        CatalogItem<?, ?> item = add(
-                "brooklyn.catalog:",
-                "  id: test.inputs",
-                "  version: 0.0.1",
-                "  inputs:",
-                "  - simple",
-                "  - name: explicit_name",
-                "  - name: third_input",
-                "    type: integer",
-                "  item: " + spec);
-        List<CatalogInput<?>> inputs = item.getInputs();
-        assertEquals(inputs.size(), 3);
-        CatalogInput<?> firstInput = inputs.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
-        assertEquals(firstInput.isPinned(), true);
-        assertEquals(firstInput.getType().getName(), "simple");
-        assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class));
-        
-        CatalogInput<?> secondInput = inputs.get(1);
-        assertEquals(secondInput.getLabel(), "explicit_name");
-        assertEquals(secondInput.isPinned(), true);
-        assertEquals(secondInput.getType().getName(), "explicit_name");
-        assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class));
-        
-        CatalogInput<?> thirdInput = inputs.get(2);
-        assertEquals(thirdInput.getLabel(), "third_input");
-        assertEquals(thirdInput.isPinned(), true);
-        assertEquals(thirdInput.getType().getName(), "third_input");
-        assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class));
-    }
-
-    @Test
-    public void testOsgiType() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
-        CatalogItem<?, ?> item = add(
-                "brooklyn.catalog:",
-                "  id: test.inputs",
-                "  version: 0.0.1",
-                "  libraries:",
-                "  - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH,
-                "  inputs:",
-                "  - name: simple",
-                "    type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY,
-                "  item: " + spec);
-        List<CatalogInput<?>> inputs = item.getInputs();
-        assertEquals(inputs.size(), 1);
-        CatalogInput<?> firstInput = inputs.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
-        assertTrue(firstInput.isPinned());
-        assertEquals(firstInput.getType().getName(), "simple");
-        assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY);
-    }
-
-    @Test
-    public void testOsgiClassScanned() {
-        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        addMulti("brooklyn.catalog:",
-            "    items:",
-            "    - scanJavaAnnotations: true",
-            "      version: 2.0.test_java",
-            "      libraries:",
-            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
-        assertEquals(item.getVersion(), "2.0.test_java");
-        assertEquals(item.getLibraries().size(), 1);
-        CatalogInput<?> input = item.getInputs().get(0);
-        assertEquals(input.getLabel(), "more_config");
-        assertFalse(input.isPinned());
-        assertEquals(input.getType().getName(), "more_config");
-    }
-
-    private CatalogItem<?,?> add(String... def) {
-        return Iterables.getOnlyElement(addMulti(def));
-    }
-
-    private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) {
-        return catalog.addItems(Joiner.on('\n').join(def));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java
new file mode 100644
index 0000000..2f50c47
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/SpecParameterInMetaTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.apache.brooklyn.util.osgi.OsgiTestResources;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+public class SpecParameterInMetaTest {
+    private ManagementContext mgmt;
+    private BrooklynCatalog catalog;
+    private String spec;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstanceWithOsgi();
+        catalog = mgmt.getCatalog();
+        spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class));
+    }
+
+    @Test
+    public void testYamlInputsParsed() {
+        CatalogItem<?, ?> item = add(
+                "brooklyn.catalog:",
+                "  id: test.inputs",
+                "  version: 0.0.1",
+                "  parameters:",
+                "  - simple",
+                "  - name: explicit_name",
+                "  - name: third_input",
+                "    type: integer",
+                "  item: " + spec);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 3);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+        assertEquals(firstInput.isPinned(), true);
+        assertEquals(firstInput.getType().getName(), "simple");
+        assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class));
+        
+        SpecParameter<?> secondInput = inputs.get(1);
+        assertEquals(secondInput.getLabel(), "explicit_name");
+        assertEquals(secondInput.isPinned(), true);
+        assertEquals(secondInput.getType().getName(), "explicit_name");
+        assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class));
+        
+        SpecParameter<?> thirdInput = inputs.get(2);
+        assertEquals(thirdInput.getLabel(), "third_input");
+        assertEquals(thirdInput.isPinned(), true);
+        assertEquals(thirdInput.getType().getName(), "third_input");
+        assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class));
+    }
+
+    @Test
+    public void testOsgiType() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        CatalogItem<?, ?> item = add(
+                "brooklyn.catalog:",
+                "  id: test.inputs",
+                "  version: 0.0.1",
+                "  libraries:",
+                "  - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH,
+                "  parameters:",
+                "  - name: simple",
+                "    type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY,
+                "  item: " + spec);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 1);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+        assertTrue(firstInput.isPinned());
+        assertEquals(firstInput.getType().getName(), "simple");
+        assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY);
+    }
+
+    @Test
+    public void testOsgiClassScanned() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+
+        addMulti("brooklyn.catalog:",
+            "    items:",
+            "    - scanJavaAnnotations: true",
+            "      version: 2.0.test_java",
+            "      libraries:",
+            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
+        assertEquals(item.getVersion(), "2.0.test_java");
+        assertEquals(item.getLibraries().size(), 1);
+        SpecParameter<?> input = item.getParameters().get(0);
+        assertEquals(input.getLabel(), "more_config");
+        assertFalse(input.isPinned());
+        assertEquals(input.getType().getName(), "more_config");
+    }
+
+    private CatalogItem<?,?> add(String... def) {
+        return Iterables.getOnlyElement(addMulti(def));
+    }
+
+    private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) {
+        return catalog.addItems(Joiner.on('\n').join(def));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java
new file mode 100644
index 0000000..ca71d15
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTypeConfigTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.entity;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class DynamicEntityTypeConfigTest extends BrooklynAppUnitTestSupport {
+
+    @ImplementedBy(ConfigEntityForTestingImpl.class)
+    public static interface ConfigEntityForTesting extends Entity {
+        ConfigKey<String> SUGGESTED_VERSION = BrooklynConfigKeys.SUGGESTED_VERSION;
+        ConfigKey<String> INSTALL_UNIQUE_LABEL = BrooklynConfigKeys.INSTALL_UNIQUE_LABEL;
+    }
+    public static class ConfigEntityForTestingImpl extends AbstractEntity implements ConfigEntityForTesting {
+        public static final ConfigKey<String> PRE_INSTALL_COMMAND = BrooklynConfigKeys.PRE_INSTALL_COMMAND;
+        public static final ConfigKey<String> POST_INSTALL_COMMAND = BrooklynConfigKeys.POST_INSTALL_COMMAND;
+    }
+    private static final ConfigKey<?> NEW_CONFIG = ConfigKeys.newStringConfigKey("new.config");
+    private static final ConfigKey<?> SPEC_CONFIG = ConfigKeys.newStringConfigKey("spec.config");
+    
+    private EntityInternal entity;
+    @SuppressWarnings("rawtypes")
+    private RecordingSensorEventListener<ConfigKey> listener;
+
+    public final static Set<ConfigKey<?>> DEFAULT_CONFIG_KEYS = ImmutableSet.<ConfigKey<?>>of(
+            ConfigEntityForTesting.SUGGESTED_VERSION,
+            ConfigEntityForTesting.INSTALL_UNIQUE_LABEL,
+            ConfigEntityForTestingImpl.PRE_INSTALL_COMMAND,
+            ConfigEntityForTestingImpl.POST_INSTALL_COMMAND,
+            SPEC_CONFIG); 
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception{
+        super.setUp();
+        entity = (EntityInternal) app.createAndManageChild(EntitySpec.create(ConfigEntityForTesting.class)
+                .parameters(ImmutableList.of(new BasicSpecParameter<>("spec config", true, SPEC_CONFIG))));
+        listener = new RecordingSensorEventListener<>();
+        app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_ADDED, listener);
+        app.subscriptions().subscribe(entity, AbstractEntity.CONFIG_KEY_REMOVED, listener);
+    }
+
+    private void assertEventuallyListenerEventsEqual(@SuppressWarnings("rawtypes") final List<SensorEvent<ConfigKey>> sensorEvents) {
+        EntityTypeTest.assertEventuallyListenerEventsEqual(listener, sensorEvents);
+    }
+
+    @Test
+    public void testGetConfigKeys() throws Exception{
+        assertEquals(entity.getEntityType().getConfigKeys(), DEFAULT_CONFIG_KEYS);
+    }
+
+    @Test
+    public void testAddConfigKey() throws Exception{
+        entity.getMutableEntityType().addConfigKey(NEW_CONFIG);
+        assertEquals(entity.getEntityType().getConfigKeys(), 
+                ImmutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).add(NEW_CONFIG).build());
+        
+        assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_ADDED, entity, NEW_CONFIG)));
+    }
+
+    @Test
+    public void testAddConfigKeyThroughEntity() throws Exception{
+        ((AbstractEntity)Entities.deproxy(entity)).configure(ImmutableList.<ConfigKey<?>>of(NEW_CONFIG));
+        assertEquals(entity.getEntityType().getConfigKeys(), 
+                ImmutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).add(NEW_CONFIG).build());
+        
+        assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_ADDED, entity, NEW_CONFIG)));
+    }
+
+    @Test
+    public void testRemoveConfigKey() throws Exception {
+        entity.getMutableEntityType().removeConfigKey(ConfigEntityForTesting.INSTALL_UNIQUE_LABEL);
+        assertEquals(entity.getEntityType().getConfigKeys(), 
+                MutableSet.builder().addAll(DEFAULT_CONFIG_KEYS).remove(ConfigEntityForTesting.INSTALL_UNIQUE_LABEL).build().asUnmodifiable());
+        
+        assertEventuallyListenerEventsEqual(ImmutableList.of(
+            BasicSensorEvent.ofUnchecked(AbstractEntity.CONFIG_KEY_REMOVED, entity, ConfigEntityForTesting.INSTALL_UNIQUE_LABEL)));
+    }
+
+    @Test
+    public void testGetConfigKey() throws Exception {
+        ConfigKey<?> expected = ConfigEntityForTesting.INSTALL_UNIQUE_LABEL;
+        ConfigKey<?> configKey = entity.getEntityType().getConfigKey(expected.getName());
+        assertEquals(configKey.getDescription(), expected.getDescription());
+        assertEquals(configKey.getName(), expected.getName());
+        
+        assertNull(entity.getEntityType().getConfigKey("does.not.exist"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
index 6f31b6e..641f97b2 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
@@ -20,6 +20,8 @@ package org.apache.brooklyn.core.entity;
 
 import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_ADDED;
 import static org.apache.brooklyn.core.entity.AbstractEntity.CHILD_REMOVED;
+import static org.apache.brooklyn.core.entity.AbstractEntity.CONFIG_KEY_ADDED;
+import static org.apache.brooklyn.core.entity.AbstractEntity.CONFIG_KEY_REMOVED;
 import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_ADDED;
 import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_CHANGED;
 import static org.apache.brooklyn.core.entity.AbstractEntity.EFFECTOR_REMOVED;
@@ -47,10 +49,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.core.effector.MethodEffector;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.sensor.BasicSensorEvent;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
@@ -69,10 +69,12 @@ import com.google.common.collect.Iterables;
 public class EntityTypeTest extends BrooklynAppUnitTestSupport {
     private static final AttributeSensor<String> TEST_SENSOR = Sensors.newStringSensor("test.sensor");
     private EntityInternal entity;
+    @SuppressWarnings("rawtypes")
     private RecordingSensorEventListener<Sensor> listener;
 
     public final static Set<Sensor<?>> DEFAULT_SENSORS = ImmutableSet.<Sensor<?>>of(
             SENSOR_ADDED, SENSOR_REMOVED,
+            CONFIG_KEY_ADDED, CONFIG_KEY_REMOVED,
             EFFECTOR_ADDED, EFFECTOR_REMOVED, EFFECTOR_CHANGED,
             POLICY_ADDED, POLICY_REMOVED,
             CHILD_ADDED, CHILD_REMOVED,
@@ -175,8 +177,11 @@ public class EntityTypeTest extends BrooklynAppUnitTestSupport {
         assertEquals(entity.getEntityType().getSensors(), DEFAULT_SENSORS);
     }
 
-    protected <T> void assertEventuallyListenerEventsEqual(final List<T> sensorEvents) {
-        final RecordingSensorEventListener listener = this.listener;
+    private void assertEventuallyListenerEventsEqual(@SuppressWarnings("rawtypes") final List<SensorEvent<Sensor>> sensorEvents) {
+        assertEventuallyListenerEventsEqual(listener, sensorEvents);
+    }
+
+    protected static <T> void assertEventuallyListenerEventsEqual(final RecordingSensorEventListener<T> listener, final List<SensorEvent<T>> sensorEvents) {
         Asserts.succeedsEventually(new Runnable() {
             @Override
             public void run() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
new file mode 100644
index 0000000..2009c98
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.objs;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogConfig;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.reflect.TypeToken;
+
+public class BasicSpecParameterFromClassTest {
+    public interface SpecParameterTestEntity extends Entity {
+        @CatalogConfig(label="String Key", priority=3)
+        ConfigKey<String> STRING_KEY = ConfigKeys.newStringConfigKey("string_key");
+
+        @CatalogConfig(label="Integer Key", priority=2)
+        ConfigKey<Integer> INTEGER_KEY = ConfigKeys.newIntegerConfigKey("integer_key");
+
+        @SuppressWarnings("serial")
+        @CatalogConfig(label="Predicate Key", priority=1)
+        ConfigKey<Predicate<String>> PREDICATE_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "predicate_key");
+
+        ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key");
+    }
+
+    @Test
+    public void testFullDefinition() {
+        List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(SpecParameterTestEntity.class);
+        assertInput(inputs.get(0), "Predicate Key", true, SpecParameterTestEntity.PREDICATE_KEY);
+        assertInput(inputs.get(1), "Integer Key", true, SpecParameterTestEntity.INTEGER_KEY);
+        assertInput(inputs.get(2), "String Key", true, SpecParameterTestEntity.STRING_KEY);
+        assertInput(inputs.get(3), "unpinned_key", false, SpecParameterTestEntity.UNPINNNED_KEY);
+    }
+
+    private void assertInput(SpecParameter<?> input, String label, boolean pinned, ConfigKey<?> type) {
+        assertEquals(input.getLabel(), label);
+        assertEquals(input.isPinned(), pinned);
+        assertEquals(input.getType(), type);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
new file mode 100644
index 0000000..0f48dad
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.objs;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+public class BasicSpecParameterFromListTest {
+    private ManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstance();
+    }
+
+    @Test
+    public void testInlineName() {
+        String name = "minRam";
+        SpecParameter<?> input = parse(name);
+        assertEquals(input.getLabel(), name);
+        assertTrue(input.isPinned());
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
+        assertNull(type.getDefaultValue());
+        assertNull(type.getDescription());
+        assertNull(type.getInheritance());
+        assertConstraint(type.getConstraint(), Predicates.alwaysTrue());
+    }
+
+    @Test
+    public void testOnlyName() {
+        String name = "minRam";
+        SpecParameter<?> input = parse(ImmutableMap.of("name", name));
+        assertEquals(input.getLabel(), name);
+        assertEquals(input.getType().getName(), name);
+        assertEquals(input.getType().getTypeToken(), TypeToken.of(String.class));
+    }
+
+    @Test
+    public void testUnusualName() {
+        parse(ImmutableMap.of("name", "name with spaces"));
+    }
+
+    @Test
+    public void testFullDefinition() {
+        String name = "minRam";
+        String label = "Minimum Ram";
+        String description = "Some description";
+        String inputType = "string";
+        String defaultValue = "VALUE";
+        String constraint = "required";
+        SpecParameter<?> input = parse(ImmutableMap.builder()
+                .put("name", name)
+                .put("label", label)
+                .put("description", description)
+                .put("type", inputType)
+                .put("default", defaultValue)
+                .put("constraints", constraint)
+                .build());
+
+        assertEquals(input.getLabel(), label);
+        assertTrue(input.isPinned());
+
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
+        assertEquals(type.getDefaultValue(), defaultValue);
+        assertEquals(type.getDescription(), description);
+        assertNull(type.getInheritance());
+        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+    }
+
+    @Test
+    public void testUnexpectedType() {
+        String name = "1234";
+        String label = "1234";
+        String description = "5678.56";
+        String defaultValue = "444.12";
+        SpecParameter<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "label", label,
+                "description", description,
+                "default", defaultValue));
+
+        assertEquals(input.getLabel(), name);
+        assertTrue(input.isPinned());
+
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getDefaultValue(), defaultValue);
+        assertEquals(type.getDescription(), description);
+        assertNull(type.getInheritance());
+    }
+
+    @Test
+    public void testConstraintAsArray() {
+        String name = "minRam";
+        String constraint = "required";
+        SpecParameter<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "constraints", ImmutableList.of(constraint)));
+        ConfigKey<?> type = input.getType();
+        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testMissingName() {
+        parse(ImmutableMap.of(
+                "type", "string"));
+    }
+
+    @Test
+    public void testJavaType() {
+        String name = "minRam";
+        SpecParameter<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "type", BasicSpecParameterFromListTest.class.getName()));
+        assertEquals(input.getType().getTypeToken(), TypeToken.of(BasicSpecParameterFromListTest.class));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testInvalidType() {
+        String name = "minRam";
+        parse(ImmutableMap.of(
+                "name", name,
+                "type", "missing_type"));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testInvalidConstraint() {
+        String name = "minRam";
+        parse(ImmutableMap.of(
+                "name", name,
+                "type", "missing_type"));
+    }
+
+    private SpecParameter<?> parse(Object def) {
+        BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
+        List<SpecParameter<?>> inputs = BasicSpecParameter.fromConfigList(ImmutableList.of(def), loader);
+        return Iterables.getOnlyElement(inputs);
+    }
+
+    private void assertConstraint(Predicate<?> actual, Predicate<?> expected) {
+        //How to compare predicates correctly, re-creating the same predicate doesn't work
+        assertEquals(actual.toString(), expected.toString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index bc6a9fd..14a7c59 100644
--- 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
@@ -55,6 +55,7 @@ public class BrooklynCampPlatform extends AggregatingCampPlatform implements Has
 
     // --- brooklyn setup
     
+    @Override
     public ManagementContext getBrooklynManagementContext() {
         return bmc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index bbfe2ab..be2488b 100644
--- 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
@@ -25,6 +25,7 @@ import com.google.common.annotations.Beta;
 @Beta
 public class BrooklynCampPlatformLauncherNoServer extends BrooklynCampPlatformLauncherAbstract {
 
+    @Override
     public void stopServers() {
         // nothing to do
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index 7fe6030..52f52e9 100644
--- 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
@@ -25,5 +25,6 @@ public interface BrooklynCampReservedKeys {
     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_PARAMETERS = "brooklyn.parameters";
     public static final String BROOKLYN_CATALOG = "brooklyn.catalog";
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index 3368df2..a400758 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.camp.brooklyn.spi.creation;
 
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Application;
@@ -29,7 +28,6 @@ import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
 import org.apache.brooklyn.camp.spi.Assembly;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate;
-import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder;
 import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
 import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
@@ -37,12 +35,10 @@ import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
 import org.apache.brooklyn.core.mgmt.HasBrooklynManagementContext;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
-import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
@@ -86,9 +82,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
 
         // AssemblyTemplates created via PDP, _specifying_ then entities to put in
 
-        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
-            loader, buildWrapperAppTemplate(template));
-        EntitySpec<? extends Application> app = resolver.resolveSpec(ImmutableSet.<String>of());
+        EntitySpec<? extends Application> app = CampUtils.createWrapperApp(template, loader);
         app.configure(EntityManagementUtils.WRAPPER_APP_MARKER, Boolean.TRUE);
 
         // first build the children into an empty shell app
@@ -104,20 +98,6 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
         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;
-    }
-
     private boolean shouldUnwrap(AssemblyTemplate template, EntitySpec<? extends Application> app) {
         if (Boolean.TRUE.equals(TypeCoercions.coerce(template.getCustomAttributes().get(NEVER_UNWRAP_APPS_PROPERTY), Boolean.class)))
             return false;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index a273c50..c150ddc 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -233,6 +233,7 @@ public class BrooklynComponentTemplateResolver {
         new BrooklynEntityDecorationResolver.PolicySpecResolver(yamlLoader).decorate(spec, attrs);
         new BrooklynEntityDecorationResolver.EnricherSpecResolver(yamlLoader).decorate(spec, attrs);
         new BrooklynEntityDecorationResolver.InitializerResolver(yamlLoader).decorate(spec, attrs);
+        new BrooklynEntityDecorationResolver.SpecParameterResolver(yamlLoader).decorate(spec, attrs);
 
         configureEntityConfig(spec);
     }
@@ -299,6 +300,7 @@ public class BrooklynComponentTemplateResolver {
         for (Class<?> iface : spec.getAdditionalInterfaces()) {
             allKeys.addAll(FlagUtils.findAllFlagsAndConfigKeys(null, iface, bagFlags));
         }
+        allKeys.addAll(FlagUtils.findAllParameterConfigKeys(spec.getParameters(), bagFlags));
         return allKeys;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index b1d5dce..efe2d9d 100644
--- 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
@@ -24,19 +24,21 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.Enricher;
 import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynYamlTypeInstantiator.InstantiatorFromKey;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.core.typereg.RegisteredTypeConstraints;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Pattern for resolving "decorations" on service specs / entity specs, such as policies, enrichers, etc.
@@ -53,21 +55,18 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
     
     public abstract void decorate(EntitySpec<?> entitySpec, ConfigBag attrs);
 
-    protected Iterable<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) {
+    protected List<? extends DT> buildListOfTheseDecorationsFromEntityAttributes(ConfigBag attrs) {
         Object value = getDecorationAttributeJsonValue(attrs); 
-        List<DT> decorations = MutableList.of();
-        if (value==null) return decorations;
+        if (value==null) return MutableList.of();
         if (value instanceof Iterable) {
-            for (Object decorationJson: (Iterable<?>)value)
-                addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
+            return buildListOfTheseDecorationsFromIterable((Iterable<?>)value);
         } 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 " + 
@@ -75,6 +74,13 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
         return (Map<?,?>) decorationJson;
     }
 
+    protected List<DT> buildListOfTheseDecorationsFromIterable(Iterable<?> value) {
+        List<DT> decorations = MutableList.of();
+        for (Object decorationJson: value)
+            addDecorationFromJsonMap(checkIsMap(decorationJson), decorations);
+        return decorations;
+    }
+
     protected abstract String getDecorationKind();
     protected abstract Object getDecorationAttributeJsonValue(ConfigBag attrs);
     
@@ -102,7 +108,6 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<PolicySpec<?>> decorations) {
             InstantiatorFromKey decoLoader = instantiator.from(decorationJson).prefix("policy");
 
@@ -110,9 +115,14 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
             ManagementContext mgmt = instantiator.loader.getManagementContext();
             
             RegisteredType item = mgmt.getTypeRegistry().get(policyType, RegisteredTypeConstraints.spec(Policy.class));
-            PolicySpec<? extends Policy> spec;
-            if (item!=null) spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class);
-            else spec = PolicySpec.create(decoLoader.getType(Policy.class));
+            PolicySpec<?> spec;
+            if (item!=null) {
+                spec = mgmt.getTypeRegistry().createSpec(item, null, PolicySpec.class);
+            } else {
+                Class<? extends Policy> type = decoLoader.getType(Policy.class);
+                spec = PolicySpec.create(type)
+                        .parameters(BasicSpecParameter.fromClass(mgmt, type));
+            }
             spec.configure( decoLoader.getConfigMap() );
             decorations.add(spec);
         }
@@ -136,8 +146,10 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
         @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() ));
+            Class<? extends Enricher> type = decoLoader.getType(Enricher.class);
+            decorations.add(EnricherSpec.create(type)
+                .configure(decoLoader.getConfigMap())
+                .parameters(BasicSpecParameter.fromClass(instantiator.loader.getManagementContext(), type)));
         }
     }
     
@@ -161,6 +173,38 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
             decorations.add(instantiator.from(decorationJson).prefix("initializer").newInstance(EntityInitializer.class));
         }
     }
-    
+
+    // Not much value from extending from BrooklynEntityDecorationResolver, but let's not break the convention
+    public static class SpecParameterResolver extends BrooklynEntityDecorationResolver<SpecParameter<?>> {
+
+        protected SpecParameterResolver(BrooklynYamlTypeInstantiator.Factory instantiator) { super(instantiator); }
+        @Override protected String getDecorationKind() { return "Spec Parameter initializer"; }
+
+        @Override
+        public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
+            List<? extends SpecParameter<?>> explicitParams = buildListOfTheseDecorationsFromEntityAttributes(attrs);
+            if (!explicitParams.isEmpty()) {
+                entitySpec.parameters(explicitParams);
+            }
+            if (entitySpec.getParameters().isEmpty()) {
+                entitySpec.parameters(BasicSpecParameter.fromSpec(instantiator.loader.getManagementContext(), entitySpec));
+            }
+        }
+
+        @Override
+        protected List<SpecParameter<?>> buildListOfTheseDecorationsFromIterable(Iterable<?> value) {
+            return BasicSpecParameter.fromConfigList(ImmutableList.copyOf(value), instantiator.loader);
+        }
+
+        @Override
+        protected Object getDecorationAttributeJsonValue(ConfigBag attrs) {
+            return attrs.getStringKey(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
+        }
+
+        @Override
+        protected void addDecorationFromJsonMap(Map<?, ?> decorationJson, List<SpecParameter<?>> decorations) {
+            throw new IllegalStateException("Not called");
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index 96e8c4e..07a8267 100644
--- 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
@@ -126,6 +126,7 @@ public class BrooklynEntityMatcher implements PdpMatcher {
         addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_ENRICHERS);
         addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_INITIALIZERS);
         addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CHILDREN);
+        addCustomListAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
         addCustomMapAttributeIfNonNull(builder, attrs, BrooklynCampReservedKeys.BROOKLYN_CATALOG);
 
         brooklynFlags.putAll(attrs);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index 55f9603..b1b5876 100644
--- 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
@@ -89,6 +89,7 @@ public abstract class BrooklynYamlTypeInstantiator {
             return this;
         }
 
+        @Override
         public Maybe<String> getTypeName() {
             Maybe<Object> result = data.getStringKeyMaybe(getPreferredKeyName());
             if (result.isAbsent() && typeKeyPrefix!=null) {
@@ -174,6 +175,7 @@ public abstract class BrooklynYamlTypeInstantiator {
             this.typeName = typeName;
         }
         
+        @Override
         public Maybe<String> getTypeName() {
             return Maybe.fromNullable(typeName);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
index 29791dd..d4c5142 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampCatalogUtils.java
@@ -18,11 +18,9 @@
  */
 package org.apache.brooklyn.camp.brooklyn.spi.creation;
 
-import java.util.List;
 import java.util.Set;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.camp.CampPlatform;
@@ -59,7 +57,7 @@ public class CampCatalogUtils {
         switch (item.getCatalogItemType()) {
             case TEMPLATE:
             case ENTITY:
-                spec = createEntitySpec(item.getPlanYaml(), loader, encounteredTypes);
+                spec = CampUtils.createRootServiceSpec(item.getPlanYaml(), loader, encounteredTypes);
                 break;
             case LOCATION: 
                 spec = CampUtils.createLocationSpec(item.getPlanYaml(), loader, encounteredTypes);
@@ -78,14 +76,6 @@ public class CampCatalogUtils {
 
         return spec;
     }
-    
-    private static EntitySpec<?> createEntitySpec(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
-        List<EntitySpec<?>> serviceEntitySpecs = CampUtils.createServiceSpecs(plan, loader, encounteredTypes);
-        if (serviceEntitySpecs.size() > 1) {
-            throw new UnsupportedOperationException("Only supporting single service in catalog item currently: got "+serviceEntitySpecs);
-        }
-        return serviceEntitySpecs.get(0);
-    }
 
     public static CampPlatform getCampPlatform(ManagementContext mgmt) {
         return CampUtils.getCampPlatform(mgmt);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
index bcb18df..b396f37 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
@@ -23,48 +23,94 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.io.StringReader;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
 import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate;
+import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder;
 import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
+import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.yaml.Yamls;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 
 //TODO-type-registry
 public class CampUtils {
 
-    public static List<EntitySpec<?>> createServiceSpecs(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
+    public static EntitySpec<?> createRootServiceSpec(String plan, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
         CampPlatform camp = getCampPlatform(loader.getManagementContext());
 
         AssemblyTemplate at = registerDeploymentPlan(plan, loader, camp);
         AssemblyTemplateInstantiator instantiator = getInstantiator(at);
         if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-            return ((AssemblyTemplateSpecInstantiator)instantiator).createServiceSpecs(at, camp, loader, encounteredTypes);
+            List<EntitySpec<?>> serviceSpecs = ((AssemblyTemplateSpecInstantiator)instantiator).createServiceSpecs(at, camp, loader, encounteredTypes);
+            if (serviceSpecs.size() > 1) {
+                throw new UnsupportedOperationException("Single service expected, but got "+serviceSpecs);
+            }
+            EntitySpec<?> rootSpec = serviceSpecs.get(0);
+            EntitySpec<? extends Application> wrapperApp = createWrapperApp(at, loader);
+            EntityManagementUtils.mergeWrapperParentSpecToChildEntity(wrapperApp, rootSpec);
+            return rootSpec;
         } else {
             throw new IllegalStateException("Unable to instantiate YAML; incompatible instantiator "+instantiator+" for "+at);
         }
     }
 
+    public static EntitySpec<? extends Application> createWrapperApp(AssemblyTemplate template, BrooklynClassLoadingContext loader) {
+        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
+            loader, buildWrapperAppTemplate(template));
+        EntitySpec<Application> wrapperSpec = resolver.resolveSpec(ImmutableSet.<String>of());
+        if (!hasExplicitParams(template)) {
+            wrapperSpec.parameters(ImmutableList.<SpecParameter<?>>of());
+        }
+        return wrapperSpec;
+    }
+
+    private static boolean hasExplicitParams(AssemblyTemplate at) {
+        return at.getCustomAttributes().containsKey(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
+    }
+
+    private static 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;
+    }
+
     public static AssemblyTemplateInstantiator getInstantiator(AssemblyTemplate at) {
         try {
             return at.getInstantiator().newInstance();
@@ -109,11 +155,13 @@ public class CampUtils {
         }
 
         String versionedId = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "policy_type", "policyType", "type"), "policy type");
-        PolicySpec<? extends Policy> spec = resolveSpec(versionedId, loader, encounteredCatalogTypes);
-        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
+        PolicySpec<? extends Policy> spec = resolvePolicySpec(versionedId, loader, encounteredCatalogTypes);
+        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
         if (brooklynConfig != null) {
             spec.configure(brooklynConfig);
         }
+        List<?> parameters = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
+        initParameters(parameters, spec, loader);
         return spec;
     }
 
@@ -125,8 +173,7 @@ public class CampUtils {
         }
 
         Object location = Iterables.getOnlyElement((Iterable<?>)locations);
-
-        return createLocationSpec(loader, location); 
+        return createLocationSpec(loader, location);
     }
 
     @SuppressWarnings("unchecked")
@@ -142,7 +189,18 @@ public class CampUtils {
 
         String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type");
         Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
-        return resolveLocationSpec(type, brooklynConfig, loader);
+        LocationSpec<?> locationSpec = resolveLocationSpec(type, brooklynConfig, loader);
+        List<?> explicitParams = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
+        initParameters(explicitParams, locationSpec, loader);
+        return locationSpec;
+    }
+
+    private static void initParameters(List<?> explicitParams, AbstractBrooklynObjectSpec<?, ?> spec, BrooklynClassLoadingContext loader) {
+        if (explicitParams != null) {
+            spec.parameters(BasicSpecParameter.fromConfigList(explicitParams, loader));
+        } else {
+            spec.parameters(BasicSpecParameter.fromSpec(loader.getManagementContext(), spec));
+        }
     }
 
     public static DeploymentPlan makePlanFromYaml(ManagementContext mgmt, String yaml) {
@@ -160,7 +218,7 @@ public class CampUtils {
     }
 
     @SuppressWarnings("unchecked")
-    private static PolicySpec<? extends Policy> resolveSpec(
+    private static PolicySpec<? extends Policy> resolvePolicySpec(
             String versionedId,
             BrooklynClassLoadingContext loader,
             Set<String> encounteredCatalogTypes) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
index ab058c7..387212c 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.camp.brooklyn.spi.creation.service;
 
-import java.util.List;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.EntitySpec;
@@ -58,11 +57,7 @@ public class UrlServiceSpecResolver implements EntitySpecResolver {
             return null;
         }
         // Referenced specs are expected to be CAMP format as well.
-        List<EntitySpec<?>> serviceSpecs = CampUtils.createServiceSpecs(yaml, loader, encounteredTypes);
-        if (serviceSpecs.size() > 1) {
-            throw new UnsupportedOperationException("Only supporting single service in remotely referenced plans: got "+serviceSpecs);
-        }
-        return serviceSpecs.get(0);
+        return CampUtils.createRootServiceSpec(yaml, loader, encounteredTypes);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/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
index 0d874bf..7135480 100644
--- 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
@@ -63,6 +63,7 @@ public class BrooklynImmutableCampPlatform extends CampPlatform implements HasBr
 
     // --- brooklyn setup
     
+    @Override
     public ManagementContext getBrooklynManagementContext() {
         return bmc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
index fdc21fe..4d72cf8 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
@@ -23,7 +23,6 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
@@ -31,6 +30,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.Sensor;
@@ -69,7 +69,7 @@ public class CatalogTransformer {
             EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType());
             EntityType type = typeMap.getSnapshot();
 
-            for (CatalogInput<?> input: item.getInputs())
+            for (SpecParameter<?> input: item.getParameters())
                 config.add(EntityTransformer.entityConfigSummary(input));
             for (Sensor<?> x: type.getSensors())
                 sensors.add(SensorTransformer.sensorSummaryForCatalog(x));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0149bf09/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
index 9637e75..803acd9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
@@ -26,9 +26,9 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.catalog.CatalogConfig;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.render.RendererHints;
 import org.apache.brooklyn.rest.domain.EntityConfigSummary;
@@ -153,7 +153,7 @@ public class EntityTransformer {
         return entityConfigSummary(config, label, priority, null);
     }
 
-    public static EntityConfigSummary entityConfigSummary(CatalogInput<?> input) {
+    public static EntityConfigSummary entityConfigSummary(SpecParameter<?> input) {
         Double priority = input.isPinned() ? Double.valueOf(1d) : null;
         return entityConfigSummary(input.getType(), input.getLabel(), priority, null);
     }


[02/21] incubator-brooklyn git commit: Deprecate java type based items in favor of parser dependent plans

Posted by he...@apache.org.
Deprecate java type based items in favor of parser dependent plans


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

Branch: refs/heads/master
Commit: 5c5e087fe7a578bbe9c84539833910f062ad8ab0
Parents: 54b4b3c
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Mon Oct 26 17:56:47 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 14:23:24 2015 +0200

----------------------------------------------------------------------
 .../java/org/apache/brooklyn/api/catalog/CatalogItem.java    | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5c5e087f/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
index d27436e..de07640 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
@@ -70,8 +70,12 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
     /** @return The type of the spec e.g. EntitySpec corresponding to {@link #getCatalogItemJavaType()} */
     public Class<SpecT> getSpecType();
     
-    /** @return The underlying java type of the item represented, if not described via a YAML spec.
-     * Normally null (and the type comes from yaml). */
+    /**
+     * @return The underlying java type of the item represented, if not described via a YAML spec.
+     * Normally null (and the type comes from yaml).
+     * @deprecated since 0.9.0. Use plan based items instead ({@link #getPlanYaml()})
+     */
+    @Deprecated
     @Nullable public String getJavaType();
 
     /** @deprecated since 0.7.0. Use {@link #getDisplayName} */


[05/21] incubator-brooklyn git commit: Parameters rebind support

Posted by he...@apache.org.
Parameters rebind support


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

Branch: refs/heads/master
Commit: 39656383992dfddb8cf5db1a59e8f60dbb7e63a0
Parents: f035200
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Nov 3 17:30:13 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:38 2015 +0200

----------------------------------------------------------------------
 .../rebind/mementos/CatalogItemMemento.java     |  4 ++++
 .../rebind/BasicCatalogItemRebindSupport.java   |  1 +
 .../rebind/dto/BasicCatalogItemMemento.java     | 24 +++++++++++++++++++-
 3 files changed, 28 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/39656383/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
index ad16b4a..57fbb8d 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
@@ -19,8 +19,10 @@
 package org.apache.brooklyn.api.mgmt.rebind.mementos;
 
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.objs.SpecParameter;
 
 public interface CatalogItemMemento extends Memento {
 
@@ -36,6 +38,8 @@ public interface CatalogItemMemento extends Memento {
 
     String getJavaType();
 
+    List<SpecParameter<?>> getParameters();
+
     Collection<CatalogItem.CatalogBundle> getLibraries();
 
     CatalogItem.CatalogItemType getCatalogItemType();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/39656383/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
index c8f2dfc..614b085 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
@@ -48,6 +48,7 @@ public class BasicCatalogItemRebindSupport extends AbstractBrooklynObjectRebindS
                 .put("description", memento.getDescription())
                 .put("iconUrl", memento.getIconUrl())
                 .put("version", memento.getVersion())
+                .put("parameters", memento.getParameters())
                 .put("libraries", memento.getLibraries())
                 .put("planYaml", memento.getPlanYaml())
                 .put("deprecated", memento.isDeprecated())

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/39656383/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
index be21dde..bf252e0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
@@ -21,16 +21,19 @@ package org.apache.brooklyn.core.mgmt.rebind.dto;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
-import org.codehaus.jackson.annotate.JsonAutoDetect;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
+import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
 
 @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)
 public class BasicCatalogItemMemento extends AbstractMemento implements CatalogItemMemento, Serializable {
@@ -48,6 +51,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
         protected String javaType;
         protected String version;
         protected String planYaml;
+        protected List<SpecParameter<?>> parameters;
         protected Collection<CatalogItem.CatalogBundle> libraries;
         protected CatalogItem.CatalogItemType catalogItemType;
         protected Class<?> catalogItemJavaType;
@@ -85,6 +89,11 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
             return self();
         }
 
+        public Builder parameters(List<SpecParameter<?>> params) {
+            this.parameters = params;
+            return self();
+        }
+
         public Builder libraries(Collection<CatalogItem.CatalogBundle> libraries) {
             this.libraries = libraries;
             return self();
@@ -123,6 +132,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
             javaType = other.getJavaType();
             version = other.getVersion();
             planYaml = other.getPlanYaml();
+            parameters = other.getParameters();
             libraries = other.getLibraries();
             catalogItemType = other.getCatalogItemType();
             catalogItemJavaType = other.getCatalogItemJavaType();
@@ -143,6 +153,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
     private String javaType;
     private String version;
     private String planYaml;
+    private List<SpecParameter<?>> parameters;
     private Collection<CatalogItem.CatalogBundle> libraries;
     private CatalogItem.CatalogItemType catalogItemType;
     private Class<?> catalogItemJavaType;
@@ -160,6 +171,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
         this.iconUrl = builder.iconUrl;
         this.version = builder.version;
         this.planYaml = builder.planYaml;
+        this.parameters = builder.parameters;
         this.libraries = builder.libraries;
         this.catalogItemJavaType = builder.catalogItemJavaType;
         this.catalogItemType = builder.catalogItemType;
@@ -209,6 +221,15 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
     }
 
     @Override
+    public List<SpecParameter<?>> getParameters() {
+        if (parameters != null) {
+            return parameters;
+        } else {
+            return ImmutableList.of();
+        }
+    }
+
+    @Override
     public Collection<CatalogItem.CatalogBundle> getLibraries() {
         return libraries;
     }
@@ -259,6 +280,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
                 .add("iconUrl", getIconUrl())
                 .add("version", getVersion())
                 .add("planYaml", getPlanYaml())
+                .add("parameters", getParameters())
                 .add("libraries", getLibraries())
                 .add("catalogItemJavaType", getCatalogItemJavaType())
                 .add("catalogItemType", getCatalogItemType())


[03/21] incubator-brooklyn git commit: Catalog items configuration support

Posted by he...@apache.org.
Catalog items configuration support

Functionality to let catalog items document what configuration they accept as input. Useful for YAML plans to let users know what configuration they support and for UIs to list available inputs and validate them.


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

Branch: refs/heads/master
Commit: 5fb47710f7e6a6b3d460e65affc1b7472413a4eb
Parents: 92d8560
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Oct 28 19:13:17 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:33 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/api/catalog/CatalogItem.java       |  16 +-
 .../catalog/internal/BasicBrooklynCatalog.java  |   5 +
 .../catalog/internal/CatalogClasspathDo.java    |  13 +-
 .../core/catalog/internal/CatalogInputDto.java  | 240 +++++++++++++++++++
 .../catalog/internal/CatalogItemBuilder.java    |  10 +
 .../core/catalog/internal/CatalogItemDo.java    |   7 +
 .../internal/CatalogItemDtoAbstract.java        |  17 +-
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |   1 +
 .../apache/brooklyn/util/core/osgi/Osgis.java   |   1 +
 .../internal/CatalogInputDtoClassTest.java      |  65 +++++
 .../internal/CatalogInputDtoYamlTest.java       | 185 ++++++++++++++
 .../core/catalog/internal/CatalogInputTest.java | 139 +++++++++++
 .../core/catalog/internal/CatalogLoadTest.java  |   2 +-
 .../catalog/internal/TestToSpecTransformer.java | 118 +++++++++
 ...che.brooklyn.core.plan.PlanToSpecTransformer |  19 ++
 .../rest/transform/CatalogTransformer.java      |  12 +-
 .../rest/transform/EntityTransformer.java       |   7 +
 .../brooklyn-test-osgi-more-entities_0.2.0.jar  | Bin 15622 -> 15745 bytes
 .../test/osgi/entities/more/MoreEntity.java     |   3 +
 19 files changed, 848 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
index de07640..e5a2636 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.api.catalog;
 
 import java.util.Collection;
+import java.util.List;
 
 import javax.annotation.Nullable;
 
@@ -27,6 +28,7 @@ import org.apache.brooklyn.api.mgmt.rebind.Rebindable;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
+import org.apache.brooklyn.config.ConfigKey;
 
 import com.google.common.annotations.Beta;
 
@@ -45,6 +47,15 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
         public boolean isNamed();
     }
 
+    public static interface CatalogInput<T> {
+        /** Short name, to be used in UI */
+        String getLabel();
+        /** Visible by default in UI, not all inputs may be visible at once */
+        boolean isPinned();
+        /** Type information for the input */
+        ConfigKey<T> getType();
+    }
+
     /**
      * @throws UnsupportedOperationException; config not supported for catalog items
      */
@@ -56,7 +67,8 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
      */
     @Override
     SubscriptionSupport subscriptions();
-    
+
+    /** @deprecated since 0.7.0 in favour of {@link CatalogBundle}, kept for rebind compatibility */
     @Deprecated
     public static interface CatalogItemLibraries {
         Collection<String> getBundles();
@@ -94,6 +106,8 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
 
     public String getVersion();
 
+    public List<CatalogInput<?>> getInputs();
+
     public Collection<CatalogBundle> getLibraries();
 
     public String toXmlString();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index c176a42..e9f8d34 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.location.Location;
@@ -420,6 +421,9 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         // (this load is required for the scan below and I think also for yaml resolution)
         CatalogUtils.installLibraries(mgmt, libraryBundlesNew);
 
+        List<?> inputsRaw = MutableList.copyOf(getFirstAs(itemMetadata, List.class, "brooklyn.inputs", "inputs").orNull());
+        List<CatalogInput<?>> inputs = CatalogInputDto.ParseYamlInputs.parseInputs(inputsRaw, CatalogUtils.newClassLoadingContext(mgmt, "<catalog_input_parser>", libraryBundles));
+
         Boolean scanJavaAnnotations = getFirstAs(itemMetadata, Boolean.class, "scanJavaAnnotations", "scan_java_annotations").orNull();
         if (scanJavaAnnotations==null || !scanJavaAnnotations) {
             // don't scan
@@ -567,6 +571,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         String sourcePlanYaml = planInterpreter.getPlanYaml();
         
         CatalogItemDtoAbstract<?, ?> dto = createItemBuilder(itemType, symbolicName, version)
+            .inputs(inputs)
             .libraries(libraryBundles)
             .displayName(displayName)
             .description(description)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
index a8b7bbe..7b2fb53 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
@@ -24,15 +24,14 @@ import java.io.InputStream;
 import java.lang.reflect.Modifier;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Nullable;
 
-import org.reflections.util.ClasspathHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ImplementedBy;
@@ -49,6 +48,9 @@ import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Time;
+import org.reflections.util.ClasspathHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
@@ -310,6 +312,7 @@ public class CatalogClasspathDo {
         }
         if (log.isTraceEnabled())
             log.trace("adding to catalog: "+c+" (from catalog "+catalog+")");
+        item.setInputs(getJavaTypeInputs(c));
         catalog.addEntry(item);
         return item;
     }
@@ -349,4 +352,8 @@ public class CatalogClasspathDo {
         classloader.addFirst(loader);
     }
 
+    private List<CatalogInput<?>> getJavaTypeInputs(Class<?> c) {
+        return CatalogInputDto.ParseClassInputs.parseInputs(c);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
new file mode 100644
index 0000000..c549137
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDto.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.catalog.CatalogConfig;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityType;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.entity.EntityDynamicType;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.objs.BrooklynTypes;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.StringPredicates;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+
+public class CatalogInputDto<T> implements CatalogInput<T> {
+    private static final String DEFAULT_TYPE = "string";
+    private static final Map<String, Class<?>> BUILT_IN_TYPES = ImmutableMap.<String, Class<?>>builder()
+            .put(DEFAULT_TYPE, String.class)
+            .put("integer", Integer.class)
+            .put("long", Long.class)
+            .put("float", Float.class)
+            .put("double", Double.class)
+            .put("timestamp", Date.class)
+            .build();
+
+    private static final Map<String, Predicate<?>> BUILT_IN_CONSTRAINTS = ImmutableMap.<String, Predicate<?>>of(
+            "required", StringPredicates.isNonBlank());
+
+    private String label;
+    private boolean pinned;
+    private ConfigKey<T> type;
+
+    public CatalogInputDto(String label, boolean pinned, ConfigKey<T> type) {
+        this.label = label;
+        this.pinned = pinned;
+        this.type = type;
+    }
+
+    @Override
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public boolean isPinned() {
+        return pinned;
+    }
+
+    @Override
+    public ConfigKey<T> getType() {
+        return type;
+    }
+
+    public static final class ParseYamlInputs {
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        public static List<CatalogInput<?>> parseInputs(List<?> inputsRaw, BrooklynClassLoadingContext loader) {
+            List<CatalogInput<?>> inputs = new ArrayList<>(inputsRaw.size());
+            for (Object obj : inputsRaw) {
+                Map inputDef;
+                if (obj instanceof String) {
+                    inputDef = ImmutableMap.of("name", obj);
+                } else if (obj instanceof Map) {
+                    inputDef = (Map) obj;
+                } else {
+                    throw new IllegalArgumentException("Catalog input definition expected to be a map, but is " + obj.getClass() + " instead: " + obj);
+                }
+                String name = (String)inputDef.get("name");
+                String label = (String)inputDef.get("label");
+                String description = (String)inputDef.get("description");
+                String type = (String)inputDef.get("type");
+                Object defaultValue = inputDef.get("default");
+                Predicate<?> constraints = parseConstraints(inputDef.get("constraints"), loader);
+
+                if (name == null) {
+                    throw new IllegalArgumentException("'name' value missing from input definition " + obj + " but is required. Check for typos.");
+                }
+
+                ConfigKey inputType = BasicConfigKey.builder(inferType(type, loader))
+                        .name(name)
+                        .description(description)
+                        .defaultValue(defaultValue)
+                        .constraint(constraints)
+                        .build();
+                inputs.add(new CatalogInputDto(Maybe.fromNullable(label).or(name), true, inputType));
+            }
+            return inputs;
+        }
+
+        @SuppressWarnings({ "rawtypes" })
+        private static TypeToken inferType(String typeRaw, BrooklynClassLoadingContext loader) {
+            if (typeRaw == null) return TypeToken.of(String.class);
+            String type = typeRaw.trim();
+            if (BUILT_IN_TYPES.containsKey(type)) {
+                return TypeToken.of(BUILT_IN_TYPES.get(type));
+            } else {
+                // Assume it's a Java type
+                Maybe<Class<?>> inputType = loader.tryLoadClass(type);
+                if (inputType.isPresent()) {
+                    return TypeToken.of(inputType.get());
+                } else {
+                    throw new IllegalArgumentException("The type '" + type + "' for a catalog input not recognised as a built-in (" + BUILT_IN_TYPES.keySet() + ") or a java type");
+                }
+            }
+        }
+    
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        private static Predicate parseConstraints(Object obj, BrooklynClassLoadingContext loader) {
+            List constraintsRaw;
+            if (obj == null) {
+                constraintsRaw = ImmutableList.of();
+            } else if (obj instanceof String) {
+                constraintsRaw = ImmutableList.of(obj);
+            } else if (obj instanceof List) {
+                constraintsRaw = (List) obj;
+            } else {
+                throw new IllegalArgumentException ("The constraint '" + obj + "' for a catalog input is invalid format - string or list supported");
+            }
+            List<Predicate> constraints = new ArrayList(constraintsRaw.size());
+            for (Object untypedConstraint : constraintsRaw) {
+                String constraint = (String)untypedConstraint;
+                if (BUILT_IN_CONSTRAINTS.containsKey(constraint)) {
+                    constraints.add(BUILT_IN_CONSTRAINTS.get(constraint));
+                } else {
+                    throw new IllegalArgumentException("The constraint '" + constraint + "' for a catalog input is not recognized as a built-in (" + BUILT_IN_CONSTRAINTS.keySet() + ")");
+                }
+            }
+            if (!constraints.isEmpty()) {
+                if (constraints.size() == 1) {
+                    return constraints.get(0);
+                } else {
+                    return Predicates.and((List<Predicate<Object>>)(List) constraints);
+                }
+            } else {
+                return Predicates.alwaysTrue();
+            }
+        }
+    }
+
+    public static final class ParseClassInputs {
+        private static final class WeightedCatalogInput {
+            private Double weight;
+            private CatalogInput<?> input;
+            public WeightedCatalogInput(Double weight, CatalogInput<?> input) {
+                this.weight = weight;
+                this.input = input;
+            }
+            public Double getWeight() {return weight; }
+            public CatalogInput<?> getInput() { return input; }
+        }
+        private static final class InputsComparator implements Comparator<WeightedCatalogInput> {
+            @Override
+            public int compare(WeightedCatalogInput o1, WeightedCatalogInput o2) {
+                if (o1.getWeight() == o2.getWeight()) {
+                    return 0;
+                } else if (o1.getWeight() == null) {
+                    return 1;
+                } else if (o2.getWeight() == null) {
+                    return -1;
+                } else {
+                    return Double.compare(o1.getWeight(),  o2.getWeight());
+                }
+            }
+        }
+        private static final class InputsTransformer implements Function<WeightedCatalogInput, CatalogInput<?>> {
+            @Override
+            public CatalogInput<?> apply(WeightedCatalogInput input) {
+                return input.getInput();
+            }
+        }
+
+        public static List<CatalogInput<?>> parseInputs(Class<?> c) {
+            MutableList<WeightedCatalogInput> inputs = MutableList.<WeightedCatalogInput>of();
+            if (Entity.class.isAssignableFrom(c)) {
+                @SuppressWarnings("unchecked")
+                Class<? extends Entity> entityClass = (Class<? extends Entity>) c;
+                EntityDynamicType dynamicType = BrooklynTypes.getDefinedEntityType(entityClass);
+                EntityType type = dynamicType.getSnapshot();
+                for (ConfigKey<?> x: type.getConfigKeys()) {
+                    WeightedCatalogInput fieldConfig = getFieldConfig(x, dynamicType.getConfigKeyField(x.getName()));
+                    inputs.appendIfNotNull(fieldConfig);
+                }
+                Collections.sort(inputs, new InputsComparator());
+                return FluentIterable.from(inputs)
+                        .transform(new InputsTransformer()).toList();
+            } else {
+                return ImmutableList.<CatalogInput<?>>of();
+            }
+        }
+
+        public static WeightedCatalogInput getFieldConfig(ConfigKey<?> config, Field configKeyField) {
+            if (configKeyField == null) return null;
+            CatalogConfig catalogConfig = configKeyField.getAnnotation(CatalogConfig.class);
+            String label = config.getName();
+            Double priority = null;
+            if (catalogConfig != null) {
+                label = Maybe.fromNullable(catalogConfig.label()).or(config.getName());
+                priority = catalogConfig.priority();
+            }
+            @SuppressWarnings({ "unchecked", "rawtypes" })
+            CatalogInput<?> input = new CatalogInputDto(label, priority != null, config);
+            return new WeightedCatalogInput(priority, input);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
index 8918a74..f1e4711 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
@@ -20,8 +20,10 @@ package org.apache.brooklyn.core.catalog.internal;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 
 import com.google.common.base.Preconditions;
 
@@ -104,6 +106,11 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
         return this;
     }
 
+    public CatalogItemBuilder<CatalogItemType> inputs(List<CatalogInput<?>> inputs) {
+        dto.setInputs(inputs);
+        return this;
+    }
+
     public CatalogItemBuilder<CatalogItemType> libraries(Collection<CatalogBundle> libraries) {
         dto.setLibraries(libraries);
         return this;
@@ -118,6 +125,9 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
         Preconditions.checkNotNull(dto.getSymbolicName());
         Preconditions.checkNotNull(dto.getVersion());
 
+        if (dto.getInputs() == null) {
+            dto.setInputs(Collections.<CatalogInput<?>>emptyList());
+        }
         if (dto.getLibraries() == null) {
             dto.setLibraries(Collections.<CatalogBundle>emptyList());
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
index 2aa8479..e053374 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.core.catalog.internal;
 
 import java.util.Collection;
+import java.util.List;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -177,6 +178,11 @@ public class CatalogItemDo<T,SpecT> implements CatalogItem<T,SpecT>, BrooklynObj
         return itemDto.getVersion();
     }
 
+    @Override
+    public List<CatalogInput<?>> getInputs() {
+        return itemDto.getInputs();
+    }
+
     @Nonnull  // but it is still null sometimes, see in CatalogDo.loadJavaClass
     @Override
     public Collection<CatalogBundle> getLibraries() {
@@ -192,6 +198,7 @@ public class CatalogItemDo<T,SpecT> implements CatalogItem<T,SpecT>, BrooklynObj
     }
     
     @SuppressWarnings("unchecked")
+    @Deprecated
     Class<? extends T> loadJavaClass(final ManagementContext mgmt) {
         if (javaClass!=null) return javaClass;
         javaClass = (Class<T>)CatalogUtils.newClassLoadingContext(mgmt, getId(), getLibraries(), catalog.getRootClassLoader()).loadClass(getJavaType());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
index 414b3e6..e95b0dd 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.core.catalog.internal;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -61,6 +62,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     private @Deprecated @SetFromFlag String type;
     private @SetFromFlag String planYaml;
 
+    private @SetFromFlag List<CatalogInput<?>> inputs;
     private @SetFromFlag Collection<CatalogBundle> libraries;
     private @SetFromFlag Set<Object> tags = Sets.newLinkedHashSet();
     private @SetFromFlag boolean deprecated;
@@ -108,11 +110,13 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         return type;
     }
 
+    @Override
     @Deprecated
     public String getName() {
         return getDisplayName();
     }
 
+    @Override
     @Deprecated
     public String getRegisteredTypeName() {
         return getSymbolicName();
@@ -170,6 +174,11 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     public void setDisabled(boolean disabled) {
         this.disabled = disabled;
     }
+    
+    @Override
+    public List<CatalogInput<?>> getInputs() {
+        return inputs;
+    }
 
     @Nonnull
     @Override
@@ -188,7 +197,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(symbolicName, planYaml, javaType, nullIfEmpty(libraries), version, getCatalogItemId());
+        return Objects.hashCode(symbolicName, planYaml, javaType, nullIfEmpty(inputs), nullIfEmpty(libraries), version, getCatalogItemId());
     }
 
     @Override
@@ -200,6 +209,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         if (!Objects.equal(symbolicName, other.symbolicName)) return false;
         if (!Objects.equal(planYaml, other.planYaml)) return false;
         if (!Objects.equal(javaType, other.javaType)) return false;
+        if (!Objects.equal(nullIfEmpty(inputs), nullIfEmpty(other.inputs))) return false;
         if (!Objects.equal(nullIfEmpty(libraries), nullIfEmpty(other.libraries))) return false;
         if (!Objects.equal(getCatalogItemId(), other.getCatalogItemId())) return false;
         if (!Objects.equal(version, other.version)) return false;
@@ -224,6 +234,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         return getClass().getSimpleName()+"["+getId()+"/"+getDisplayName()+"]";
     }
 
+    @Override
     public abstract Class<SpecT> getSpecType();
 
     transient CatalogXmlSerializer serializer;
@@ -371,6 +382,10 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         this.planYaml = planYaml;
     }
 
+    protected void setInputs(List<CatalogInput<?>> inputs) {
+        this.inputs = inputs;
+    }
+
     protected void setLibraries(Collection<CatalogBundle> libraries) {
         this.libraries = libraries;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 0e941bd..306a05d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -91,6 +91,7 @@ public class OsgiManager {
             final AtomicReference<DeletionResult> deletionResult = new AtomicReference<DeletionResult>();
             Repeater.create("Delete OSGi cache dir")
                     .until(new Callable<Boolean>() {
+                        @Override
                         public Boolean call() {
                             deletionResult.set(Os.deleteRecursively(osgiCacheDir));
                             return deletionResult.get().wasSuccessful();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
index 6d5dc91..42cebc5 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
@@ -246,6 +246,7 @@ public class Osgis {
             return Joiner.on(";").join(parts);
         }
         
+        @Override
         public String toString() {
             return getClass().getCanonicalName()+"["+getConstraintsDescription()+"]";
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
new file mode 100644
index 0000000..7602c2a
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoClassTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogConfig;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.reflect.TypeToken;
+
+public class CatalogInputDtoClassTest {
+    public interface CatalogInputTestEntity extends Entity {
+        @CatalogConfig(label="String Key", priority=3)
+        ConfigKey<String> STRING_KEY = ConfigKeys.newStringConfigKey("string_key");
+
+        @CatalogConfig(label="Integer Key", priority=2)
+        ConfigKey<Integer> INTEGER_KEY = ConfigKeys.newIntegerConfigKey("integer_key");
+
+        @SuppressWarnings("serial")
+        @CatalogConfig(label="Predicate Key", priority=1)
+        ConfigKey<Predicate<String>> PREDICATE_KEY = ConfigKeys.newConfigKey(new TypeToken<Predicate<String>>() {}, "predicate_key");
+
+        ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key");
+    }
+
+    @Test
+    public void testFullDefinition() {
+        List<CatalogInput<?>> inputs = CatalogInputDto.ParseClassInputs.parseInputs(CatalogInputTestEntity.class);
+        assertInput(inputs.get(0), "Predicate Key", true, CatalogInputTestEntity.PREDICATE_KEY);
+        assertInput(inputs.get(1), "Integer Key", true, CatalogInputTestEntity.INTEGER_KEY);
+        assertInput(inputs.get(2), "String Key", true, CatalogInputTestEntity.STRING_KEY);
+        assertInput(inputs.get(3), "unpinned_key", false, CatalogInputTestEntity.UNPINNNED_KEY);
+    }
+
+    private void assertInput(CatalogInput<?> input, String label, boolean pinned, ConfigKey<?> type) {
+        assertEquals(input.getLabel(), label);
+        assertEquals(input.isPinned(), pinned);
+        assertEquals(input.getType(), type);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
new file mode 100644
index 0000000..6e65904
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputDtoYamlTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+public class CatalogInputDtoYamlTest {
+    private ManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstance();
+    }
+
+    @Test
+    public void testInlineName() {
+        String name = "minRam";
+        CatalogInput<?> input = parse(name);
+        assertEquals(input.getLabel(), name);
+        assertTrue(input.isPinned());
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
+        assertNull(type.getDefaultValue());
+        assertNull(type.getDescription());
+        assertNull(type.getInheritance());
+        assertConstraint(type.getConstraint(), Predicates.alwaysTrue());
+    }
+
+    @Test
+    public void testOnlyName() {
+        String name = "minRam";
+        CatalogInput<?> input = parse(ImmutableMap.of("name", name));
+        assertEquals(input.getLabel(), name);
+        assertEquals(input.getType().getName(), name);
+        assertEquals(input.getType().getTypeToken(), TypeToken.of(String.class));
+    }
+
+    @Test
+    public void testUnusualName() {
+        parse(ImmutableMap.of("name", "name with spaces"));
+    }
+
+    @Test
+    public void testFullDefinition() {
+        String name = "minRam";
+        String label = "Minimum Ram";
+        String description = "Some description";
+        String inputType = "string";
+        String defaultValue = "VALUE";
+        String constraint = "required";
+        CatalogInput<?> input = parse(ImmutableMap.builder()
+                .put("name", name)
+                .put("label", label)
+                .put("description", description)
+                .put("type", inputType)
+                .put("default", defaultValue)
+                .put("constraints", constraint)
+                .build());
+
+        assertEquals(input.getLabel(), label);
+        assertTrue(input.isPinned());
+
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getTypeToken(), TypeToken.of(String.class));
+        assertEquals(type.getDefaultValue(), defaultValue);
+        assertEquals(type.getDescription(), description);
+        assertNull(type.getInheritance());
+        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+    }
+
+    @Test
+    public void testUnexpectedType() {
+        String name = "1234";
+        String label = "1234";
+        String description = "5678.56";
+        String defaultValue = "444.12";
+        CatalogInput<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "label", label,
+                "description", description,
+                "default", defaultValue));
+
+        assertEquals(input.getLabel(), name);
+        assertTrue(input.isPinned());
+
+        ConfigKey<?> type = input.getType();
+        assertEquals(type.getName(), name);
+        assertEquals(type.getDefaultValue(), defaultValue);
+        assertEquals(type.getDescription(), description);
+        assertNull(type.getInheritance());
+    }
+
+    @Test
+    public void testConstraintAsArray() {
+        String name = "minRam";
+        String constraint = "required";
+        CatalogInput<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "constraints", ImmutableList.of(constraint)));
+        ConfigKey<?> type = input.getType();
+        assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testMissingName() {
+        parse(ImmutableMap.of(
+                "type", "string"));
+    }
+
+    @Test
+    public void testJavaType() {
+        String name = "minRam";
+        CatalogInput<?> input = parse(ImmutableMap.of(
+                "name", name,
+                "type", CatalogInputDtoYamlTest.class.getName()));
+        assertEquals(input.getType().getTypeToken(), TypeToken.of(CatalogInputDtoYamlTest.class));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testInvalidType() {
+        String name = "minRam";
+        parse(ImmutableMap.of(
+                "name", name,
+                "type", "missing_type"));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testInvalidConstraint() {
+        String name = "minRam";
+        parse(ImmutableMap.of(
+                "name", name,
+                "type", "missing_type"));
+    }
+
+    private CatalogInput<?> parse(Object def) {
+        BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
+        List<CatalogInput<?>> inputs = CatalogInputDto.ParseYamlInputs.parseInputs(ImmutableList.of(def), loader);
+        return Iterables.getOnlyElement(inputs);
+    }
+
+    private void assertConstraint(Predicate<?> actual, Predicate<?> expected) {
+        //How to compare predicates correctly, re-creating the same predicate doesn't work
+        assertEquals(actual.toString(), expected.toString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
new file mode 100644
index 0000000..8b477b9
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogInputTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.mgmt.osgi.OsgiTestResources;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+public class CatalogInputTest {
+    private ManagementContext mgmt;
+    private BrooklynCatalog catalog;
+    private String spec;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstanceWithOsgi();
+        catalog = mgmt.getCatalog();
+        spec = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class));
+    }
+
+    @Test
+    public void testYamlInputsParsed() {
+        CatalogItem<?, ?> item = add(
+                "brooklyn.catalog:",
+                "  id: test.inputs",
+                "  version: 0.0.1",
+                "  inputs:",
+                "  - simple",
+                "  - name: explicit_name",
+                "  - name: third_input",
+                "    type: integer",
+                "  item: " + spec);
+        List<CatalogInput<?>> inputs = item.getInputs();
+        assertEquals(inputs.size(), 3);
+        CatalogInput<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+        assertEquals(firstInput.isPinned(), true);
+        assertEquals(firstInput.getType().getName(), "simple");
+        assertEquals(firstInput.getType().getTypeToken(), TypeToken.of(String.class));
+        
+        CatalogInput<?> secondInput = inputs.get(1);
+        assertEquals(secondInput.getLabel(), "explicit_name");
+        assertEquals(secondInput.isPinned(), true);
+        assertEquals(secondInput.getType().getName(), "explicit_name");
+        assertEquals(secondInput.getType().getTypeToken(), TypeToken.of(String.class));
+        
+        CatalogInput<?> thirdInput = inputs.get(2);
+        assertEquals(thirdInput.getLabel(), "third_input");
+        assertEquals(thirdInput.isPinned(), true);
+        assertEquals(thirdInput.getType().getName(), "third_input");
+        assertEquals(thirdInput.getType().getTypeToken(), TypeToken.of(Integer.class));
+    }
+
+    @Test
+    public void testOsgiType() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        CatalogItem<?, ?> item = add(
+                "brooklyn.catalog:",
+                "  id: test.inputs",
+                "  version: 0.0.1",
+                "  libraries:",
+                "  - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH,
+                "  inputs:",
+                "  - name: simple",
+                "    type: " + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY,
+                "  item: " + spec);
+        List<CatalogInput<?>> inputs = item.getInputs();
+        assertEquals(inputs.size(), 1);
+        CatalogInput<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+        assertTrue(firstInput.isPinned());
+        assertEquals(firstInput.getType().getName(), "simple");
+        assertEquals(firstInput.getType().getTypeToken().getRawType().getName(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY);
+    }
+
+    @Test
+    public void testOsgiClassScanned() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+
+        addMulti("brooklyn.catalog:",
+            "    items:",
+            "    - scanJavaAnnotations: true",
+            "      version: 2.0.test_java",
+            "      libraries:",
+            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
+        assertEquals(item.getVersion(), "2.0.test_java");
+        assertEquals(item.getLibraries().size(), 1);
+        CatalogInput<?> input = item.getInputs().get(0);
+        assertEquals(input.getLabel(), "more_config");
+        assertFalse(input.isPinned());
+        assertEquals(input.getType().getName(), "more_config");
+    }
+
+    private CatalogItem<?,?> add(String... def) {
+        return Iterables.getOnlyElement(addMulti(def));
+    }
+
+    private Iterable<? extends CatalogItem<?, ?>> addMulti(String... def) {
+        return catalog.addItems(Joiner.on('\n').join(def));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogLoadTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogLoadTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogLoadTest.java
index ba38ac1..d1862a6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogLoadTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogLoadTest.java
@@ -46,7 +46,7 @@ public class CatalogLoadTest {
         return ResourceUtils.create(this).getResourceAsString(file);
     }
 
-    // CAMP YAML parsing not available in core, so YAML catalog tests are in camp, e.g. CatalogYamlEntitiesTest 
+    // CAMP YAML parsing not available in core, so YAML catalog tests are in camp, e.g. CatalogYamlEntityTest 
     
     @Test
     public void testLoadXmlCatalog() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java
new file mode 100644
index 0000000..0dfe291
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/TestToSpecTransformer.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.catalog.internal;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.plan.PlanNotRecognizedException;
+import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
+import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.yaml.Yamls;
+
+/**
+ * Resolves previously registered specs by id.
+ * First create a spec and register it, keeping the returned ID:
+ * <pre> {@code
+ * String specId = TestToSpecTransformer.registerSpec(EntitySpec.create(BasicEntity.class));
+ * }</pre>
+ *
+ * Then build a plan to be resolved such as:
+ * <pre> {@code
+ *  brooklyn.catalog:
+ *    id: test.inputs
+ *    version: 0.0.1
+ *    item: <specId>
+ * } </pre>
+ */
+public class TestToSpecTransformer implements PlanToSpecTransformer {
+    private static final Map<String, AbstractBrooklynObjectSpec<?, ?>> REGISTERED_SPECS = new ConcurrentHashMap<>();
+    public static String registerSpec(AbstractBrooklynObjectSpec<?, ?> spec) {
+        String id = Identifiers.makeRandomId(10);
+        REGISTERED_SPECS.put(id, spec);
+        return id;
+    }
+
+    @Override
+    public void injectManagementContext(ManagementContext managementContext) {
+    }
+
+    @Override
+    public String getShortDescription() {
+        return "test";
+    }
+
+    @Override
+    public boolean accepts(String planType) {
+        return "test".equals(planType);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public EntitySpec<? extends Application> createApplicationSpec(String plan) throws PlanNotRecognizedException {
+        return (EntitySpec<? extends Application>) getSpec(plan);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) 
+            throws PlanNotRecognizedException {
+        return (SpecT) getSpecFromPlan(item.getPlanYaml());
+    }
+
+    private AbstractBrooklynObjectSpec<?,?> getSpecFromPlan(String plan) {
+        if (plan != null) {
+            Object planRaw = Yamls.parseAll(plan).iterator().next();
+            if (planRaw instanceof String) {
+                return getSpec((String)planRaw);
+            } else if (planRaw instanceof Map) {
+                // The catalog parser assumes it's dealing with CAMP specs so will helpfully
+                // prepend "type: " if it's an inline item.
+                return getSpec((String)((Map<?, ?>)planRaw).get("type"));
+            } else {
+                throw notRecognized();
+            }
+        } else {
+            throw notRecognized();
+        }
+    }
+
+    private AbstractBrooklynObjectSpec<?,?> getSpec(String plan) {
+        if (plan == null) {
+            throw notRecognized();
+        }
+        AbstractBrooklynObjectSpec<?, ?> spec = REGISTERED_SPECS.get(plan);
+        if (spec != null) {
+            return spec;
+        } else {
+            throw notRecognized();
+        }
+    }
+
+    private PlanNotRecognizedException notRecognized() {
+        return new PlanNotRecognizedException("Not recognized as registered spec");
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
index 4e9895f..fdc21fe 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
@@ -22,11 +22,8 @@ import java.net.URI;
 import java.util.Map;
 import java.util.Set;
 
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.EntityDynamicType;
-import org.apache.brooklyn.core.objs.BrooklynTypes;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
@@ -37,6 +34,8 @@ import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.core.entity.EntityDynamicType;
+import org.apache.brooklyn.core.objs.BrooklynTypes;
 import org.apache.brooklyn.rest.domain.CatalogEntitySummary;
 import org.apache.brooklyn.rest.domain.CatalogItemSummary;
 import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
@@ -50,6 +49,7 @@ import org.apache.brooklyn.rest.domain.SummaryComparators;
 import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
@@ -69,8 +69,8 @@ public class CatalogTransformer {
             EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType());
             EntityType type = typeMap.getSnapshot();
 
-            for (ConfigKey<?> x: type.getConfigKeys())
-                config.add(EntityTransformer.entityConfigSummary(x, typeMap.getConfigKeyField(x.getName())));
+            for (CatalogInput<?> input: item.getInputs())
+                config.add(EntityTransformer.entityConfigSummary(input));
             for (Sensor<?> x: type.getSensors())
                 sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
             for (Effector<?> x: type.getEffectors())

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
index 4e6e15b..9637e75 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.catalog.CatalogConfig;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogInput;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.config.ConfigKey;
@@ -151,4 +152,10 @@ public class EntityTransformer {
         Double priority = catalogConfig==null ? null : catalogConfig.priority();
         return entityConfigSummary(config, label, priority, null);
     }
+
+    public static EntityConfigSummary entityConfigSummary(CatalogInput<?> input) {
+        Double priority = input.isPinned() ? Double.valueOf(1d) : null;
+        return entityConfigSummary(input.getType(), input.getLabel(), priority, null);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/utils/rt-osgi/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
----------------------------------------------------------------------
diff --git a/utils/rt-osgi/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar b/utils/rt-osgi/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
index 5587e25..c03ad4a 100644
Binary files a/utils/rt-osgi/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar and b/utils/rt-osgi/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar differ

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5fb47710/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
----------------------------------------------------------------------
diff --git a/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java b/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
index 2124f86..9d4d840 100644
--- a/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
+++ b/utils/rt-osgi/src/test/resources/dependencies/osgi/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
@@ -22,12 +22,15 @@ import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.effector.Effectors;
 
 @Catalog(name="More Entity v2")
 @ImplementedBy(MoreEntityImpl.class)
 public interface MoreEntity extends Entity {
 
+    public static final ConfigKey<String> MORE_CONFIG = ConfigKeys.newStringConfigKey("more_config");
     public static final Effector<String> SAY_HI = Effectors.effector(String.class, "sayHI")
         .description("says HI to an uppercased name")
         .parameter(String.class, "name")


[19/21] incubator-brooklyn git commit: This closes #1007

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


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

Branch: refs/heads/master
Commit: f84121771e7bf32430d3d4d02729cf97de74fbcd
Parents: 703354d 51ca806
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Nov 9 12:51:00 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Nov 9 12:51:00 2015 +0000

----------------------------------------------------------------------
 .../core/mgmt/EntityManagementUtils.java        |  35 +---
 .../brooklyn/camp/brooklyn/AppYamlTest.java     |   9 +-
 .../camp/brooklyn/ApplicationsYamlTest.java     | 189 ++++++++++++++++---
 3 files changed, 179 insertions(+), 54 deletions(-)
----------------------------------------------------------------------



[06/21] incubator-brooklyn git commit: Add PortRange support for the parameter types

Posted by he...@apache.org.
Add PortRange support for the parameter types

Won't be set as an attribute though.


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

Branch: refs/heads/master
Commit: f0352000dbdf8b704f15edbb4b41bedb8aab4d2f
Parents: 0149bf0
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Oct 30 18:24:46 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:38 2015 +0200

----------------------------------------------------------------------
 .../java/org/apache/brooklyn/core/objs/BasicSpecParameter.java     | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f0352000/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
index d2703ff..5707b8f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.catalog.CatalogConfig;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.BrooklynType;
@@ -154,6 +155,7 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
                 .put("float", Float.class)
                 .put("double", Double.class)
                 .put("timestamp", Date.class)
+                .put("port", PortRange.class)
                 .build();
 
         private static final Map<String, Predicate<?>> BUILT_IN_CONSTRAINTS = ImmutableMap.<String, Predicate<?>>of(


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

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


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

Branch: refs/heads/master
Commit: 1eb1519b4526fd140c630177df7da214e0919180
Parents: f841217 76d480f
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Nov 9 12:54:34 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Nov 9 12:54:34 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |   3 +-
 .../apache/brooklyn/util/core/osgi/Osgis.java   |  39 ++-
 .../core/mgmt/osgi/OsgiStandaloneTest.java      |   8 +-
 parent/pom.xml                                  |  10 +-
 pom.xml                                         |   2 +-
 .../BrooklynNodeIntegrationTest.java            |  49 +++-
 .../mysql/MySqlClusterIntegrationTest.java      |   5 +-
 .../database/mysql/MySqlClusterTestHelper.java  |  36 ++-
 .../mysql/MySqlRestartIntegrationTest.java      |   9 +
 .../rubyrep/RubyRepIntegrationTest.java         | 285 ++++++++++++++++++-
 .../nosql/riak/RiakNodeIntegrationTest.java     | 168 ++++++++++-
 .../dns/geoscaling/GeoscalingWebClientTest.java |  62 ++++
 .../proxy/nginx/NginxRebindIntegrationTest.java |  83 +++++-
 ...namicWebAppClusterRebindIntegrationTest.java |  41 ++-
 ...namicWebAppClusterRebindIntegrationTest.java |  41 ++-
 .../NodeJsWebAppFixtureIntegrationTest.java     |   9 +-
 .../apache/brooklyn/cli/CliIntegrationTest.java |  98 ++++++-
 .../BrooklynPropertiesSecurityFilterTest.java   |  43 ++-
 .../brooklyn/util/maven/MavenArtifactTest.java  |  80 +++++-
 .../rt/felix/EmbeddedFelixFramework.java        |  12 +
 20 files changed, 1026 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1eb1519b/parent/pom.xml
----------------------------------------------------------------------


[21/21] incubator-brooklyn git commit: This closes #1001

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


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

Branch: refs/heads/master
Commit: be46512ac9dff5dc76fb1e101503540dccbcd651
Parents: 1eb1519 b1b82f9
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Nov 9 12:54:52 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Nov 9 12:54:52 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/api/catalog/CatalogItem.java       |  15 +-
 .../apache/brooklyn/api/entity/EntitySpec.java  |  50 +--
 .../internal/AbstractBrooklynObjectSpec.java    |  24 ++
 .../rebind/mementos/CatalogItemMemento.java     |   4 +
 .../apache/brooklyn/api/objs/SpecParameter.java |  32 ++
 .../catalog/internal/BasicBrooklynCatalog.java  |  41 ++-
 .../catalog/internal/CatalogClasspathDo.java    |  14 +-
 .../catalog/internal/CatalogItemBuilder.java    |  10 +
 .../core/catalog/internal/CatalogItemDo.java    |   8 +
 .../internal/CatalogItemDtoAbstract.java        |  25 +-
 .../internal/JavaCatalogToSpecTransformer.java  |  14 +-
 .../brooklyn/core/entity/AbstractEntity.java    |  19 ++
 .../apache/brooklyn/core/entity/Entities.java   |  11 +
 .../brooklyn/core/entity/EntityDynamicType.java |  37 +++
 .../core/mgmt/EntityManagementUtils.java        |   6 +-
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |   1 +
 .../rebind/BasicCatalogItemRebindSupport.java   |   1 +
 .../rebind/dto/BasicCatalogItemMemento.java     |  24 +-
 .../brooklyn/core/objs/BasicSpecParameter.java  | 324 +++++++++++++++++++
 .../core/objs/proxy/InternalEntityFactory.java  |  12 +
 .../brooklyn/util/core/flags/FlagUtils.java     |  30 +-
 .../core/catalog/internal/CatalogLoadTest.java  |   2 +-
 .../internal/SpecParameterInMetaTest.java       | 139 ++++++++
 .../catalog/internal/TestToSpecTransformer.java | 118 +++++++
 .../entity/DynamicEntityTypeConfigTest.java     | 126 ++++++++
 .../brooklyn/core/entity/EntityTypeTest.java    |  15 +-
 .../objs/BasicSpecParameterFromClassTest.java   | 109 +++++++
 .../objs/BasicSpecParameterFromListTest.java    | 186 +++++++++++
 ...che.brooklyn.core.plan.PlanToSpecTransformer |  19 ++
 docs/guide/ops/catalog/index.md                 |  25 ++
 docs/guide/yaml/yaml-reference.md               |   4 +
 .../camp/brooklyn/BrooklynCampPlatform.java     |   1 +
 .../BrooklynCampPlatformLauncherNoServer.java   |   1 +
 .../camp/brooklyn/BrooklynCampReservedKeys.java |   1 +
 .../BrooklynAssemblyTemplateInstantiator.java   |  22 +-
 .../BrooklynComponentTemplateResolver.java      |   2 +
 .../BrooklynEntityDecorationResolver.java       |  74 ++++-
 .../spi/creation/BrooklynEntityMatcher.java     |   1 +
 .../creation/BrooklynYamlTypeInstantiator.java  |   2 +
 .../brooklyn/spi/creation/CampCatalogUtils.java |  12 +-
 .../camp/brooklyn/spi/creation/CampUtils.java   |  74 ++++-
 .../service/UrlServiceSpecResolver.java         |   7 +-
 .../spi/dsl/methods/BrooklynDslCommon.java      |   6 +
 .../brooklyn/spi/dsl/methods/DslComponent.java  |  14 +-
 .../platform/BrooklynImmutableCampPlatform.java |   1 +
 .../camp/brooklyn/AbstractYamlTest.java         |   7 +-
 .../camp/brooklyn/EntitiesYamlTest.java         |  74 ++++-
 .../brooklyn/ReferencingYamlTestEntity.java     |   8 +
 .../brooklyn/catalog/CatalogParametersTest.java | 318 ++++++++++++++++++
 .../resources/test-referencing-entities.yaml    |  14 +
 .../assets/js/view/application-add-wizard.js    |  14 +-
 .../app-add-wizard/required-config-entry.html   |   2 +-
 .../rest/transform/CatalogTransformer.java      |  15 +-
 .../rest/transform/EntityTransformer.java       |   7 +
 .../brooklyn-test-osgi-more-entities_0.2.0.jar  | Bin 15622 -> 15745 bytes
 .../osgi/more-entities-v2-evil-twin/pom.xml     |   2 +-
 .../test/osgi/entities/more/MoreEntity.java     |   3 +
 57 files changed, 1994 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/be46512a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/be46512a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------


[13/21] incubator-brooklyn git commit: Fix apache rat version

Posted by he...@apache.org.
Fix apache rat version

Set explicit version in the pluginManagement section to the currently use one, don't override elsewhere.


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

Branch: refs/heads/master
Commit: 5389739338991024042e5cac663bfa7a5b231474
Parents: a8f8c57
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Nov 5 22:08:00 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 22:08:00 2015 +0200

----------------------------------------------------------------------
 parent/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/53897393/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 2c6d7bd..2c18672 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -676,6 +676,7 @@
                 <plugin>
                     <groupId>org.apache.rat</groupId>
                     <artifactId>apache-rat-plugin</artifactId>
+                    <version>0.11</version>
                     <configuration>
                         <excludes combine.children="append">
                             <!-- Exclude sandbox because not part of distribution: not in tgz, and not uploaded to maven-central -->
@@ -985,7 +986,6 @@
             <plugin>
               <groupId>org.apache.rat</groupId>
               <artifactId>apache-rat-plugin</artifactId>
-              <version>0.10</version>
               <executions>
                 <execution>
                   <phase>verify</phase>


[12/21] incubator-brooklyn git commit: Add scopeRoot scope in CAMP DSL

Posted by he...@apache.org.
Add scopeRoot scope in CAMP DSL


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

Branch: refs/heads/master
Commit: b1b82f9b756ae02467dab39f311bc3680f33229a
Parents: 1da725f
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Nov 4 15:59:24 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 19:10:36 2015 +0200

----------------------------------------------------------------------
 .../apache/brooklyn/core/entity/Entities.java   | 11 ++++
 docs/guide/yaml/yaml-reference.md               |  4 ++
 .../spi/dsl/methods/BrooklynDslCommon.java      |  3 +
 .../brooklyn/spi/dsl/methods/DslComponent.java  |  8 ++-
 .../camp/brooklyn/EntitiesYamlTest.java         | 65 ++++++++++++++++++++
 .../brooklyn/ReferencingYamlTestEntity.java     |  4 ++
 .../resources/test-referencing-entities.yaml    |  7 +++
 7 files changed, 101 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
index 8b10676..59e3ec1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
@@ -100,6 +100,7 @@ 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;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
@@ -1172,4 +1173,14 @@ public class Entities {
         return t;
     }
 
+    public static Entity catalogItemScopeRoot(Entity entity) {
+        Entity root = entity;
+        while (root.getParent() != null &&
+                root != root.getParent() &&
+                Objects.equal(root.getParent().getCatalogItemId(), root.getCatalogItemId())) {
+            root = root.getParent();
+        }
+        return root;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/docs/guide/yaml/yaml-reference.md
----------------------------------------------------------------------
diff --git a/docs/guide/yaml/yaml-reference.md b/docs/guide/yaml/yaml-reference.md
index 221e71e..fc37ba8 100644
--- a/docs/guide/yaml/yaml-reference.md
+++ b/docs/guide/yaml/yaml-reference.md
@@ -165,6 +165,10 @@ concise DSL defined here:
   * `sibling`: looks for the `ID` anywhere among children of the parent entity
   * `parent`: returns the parent entity (ignores the `ID`)
   * `this`: returns this entity (ignores the `ID`)
+* `$brooklyn:root()` will return the topmost entity (the application)
+* `$broopklyn:scopeRoot()` will return the root entity in the current plan scope.
+  For catalog items it's the topmost entity in the plan, for application plans it is the same as
+  `$brooklyn:root()`.
 * `$brooklyn:formatString("pattern e.g. %s %s", "field 1", "field 2")` returns a future which creates the formatted string
   with the given parameters, where parameters may be strings *or* other tasks such as `attributeWhenReady`
 * `$brooklyn:literal("string")` returns the given string as a literal (suppressing any `$brooklyn:` expansion)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/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
index 422dac3..88a1f1d 100644
--- 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
@@ -87,6 +87,9 @@ public class BrooklynDslCommon {
     public static DslComponent root() {
         return new DslComponent(Scope.ROOT, null);
     }
+    public static DslComponent scopeRoot() {
+        return new DslComponent(Scope.SCOPE_ROOT, null);
+    }
     // prefer the syntax above to the below now, but not deprecating the below
     public static DslComponent component(String id) {
         return component("global", id);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/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
index d5f3078..40fd757 100644
--- 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
@@ -110,6 +110,8 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
                     break;
                 case ROOT:
                     return getEntity().getApplication();
+                case SCOPE_ROOT:
+                    return Entities.catalogItemScopeRoot(getEntity());
                 case DESCENDANT:
                     entitiesToSearch = Entities.descendants(getEntity());
                     break;
@@ -160,6 +162,9 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
     public DslComponent root() {
         return new DslComponent(this, Scope.ROOT, "");
     }
+    public DslComponent scopeRoot() {
+        return new DslComponent(this, Scope.SCOPE_ROOT, "");
+    }
     
     @Deprecated /** @deprecated since 0.7.0 */
     public DslComponent component(String scopeOrId) {
@@ -283,9 +288,10 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
         DESCENDANT ("descendant"),
         ANCESTOR("ancestor"),
         ROOT("root"),
+        SCOPE_ROOT("scopeRoot"),
         THIS ("this");
         
-        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, ROOT, THIS);
+        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, ROOT, SCOPE_ROOT, THIS);
         
         private final String name;
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/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
index 266772b..a997904 100644
--- 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
@@ -467,6 +467,7 @@ public class EntitiesYamlTest extends AbstractYamlTest {
 
         Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT, app)
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT, app)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1_ALT, entity1)
@@ -494,6 +495,70 @@ public class EntitiesYamlTest extends AbstractYamlTest {
             }
         }
     }
+    
+    @Test
+    public void testScopeReferences() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  items:",
+                "  -  id: ref_child",
+                "     item:",
+                "      type: " + ReferencingYamlTestEntity.class.getName(),
+                "      test.reference.root: $brooklyn:root()",
+                "      test.reference.scope_root: $brooklyn:scopeRoot()",
+                "      brooklyn.children:",
+                "      - type: " + ReferencingYamlTestEntity.class.getName(),
+                "        test.reference.root: $brooklyn:root()",
+                "        test.reference.scope_root: $brooklyn:scopeRoot()",
+
+                "  -  id: ref_parent",
+                "     item:",
+                "      type: " + ReferencingYamlTestEntity.class.getName(),
+                "      test.reference.root: $brooklyn:root()",
+                "      test.reference.scope_root: $brooklyn:scopeRoot()",
+                "      brooklyn.children:",
+                "      - type: " + ReferencingYamlTestEntity.class.getName(),
+                "        test.reference.root: $brooklyn:root()",
+                "        test.reference.scope_root: $brooklyn:scopeRoot()",
+                "        brooklyn.children:",
+                "        - type: ref_child");
+        Entity app = createAndStartApplication(
+                "brooklyn.config:",
+                "  test.reference.root: $brooklyn:root()",
+                "  test.reference.scope_root: $brooklyn:scopeRoot()",
+                "services:",
+                "- type: " + ReferencingYamlTestEntity.class.getName(),
+                "  test.reference.root: $brooklyn:root()",
+                "  test.reference.scope_root: $brooklyn:scopeRoot()",
+                "  brooklyn.children:",
+                "  - type: " + ReferencingYamlTestEntity.class.getName(),
+                "    test.reference.root: $brooklyn:root()",
+                "    test.reference.scope_root: $brooklyn:scopeRoot()",
+                "    brooklyn.children:",
+                "    - type: ref_parent");
+        
+        assertScopes(app, app, app);
+        Entity e1 = nextChild(app);
+        assertScopes(e1, app, app);
+        Entity e2 = nextChild(e1);
+        assertScopes(e2, app, app);
+        Entity e3 = nextChild(e2);
+        assertScopes(e3, app, e3);
+        Entity e4 = nextChild(e3);
+        assertScopes(e4, app, e3);
+        Entity e5 = nextChild(e4);
+        assertScopes(e5, app, e5);
+        Entity e6 = nextChild(e5);
+        assertScopes(e6, app, e5);
+    }
+    
+    private static Entity nextChild(Entity entity) {
+        return Iterables.getOnlyElement(entity.getChildren());
+    }
+    private static void assertScopes(Entity entity, Entity root, Entity scopeRoot) {
+        assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT), root);
+        assertEquals(entity.config().get(ReferencingYamlTestEntity.TEST_REFERENCE_SCOPE_ROOT), scopeRoot);
+    }
 
     private void checkReferences(final Entity entity, Map<ConfigKey<Entity>, Entity> keyToEntity) throws Exception {
         for (final ConfigKey<Entity> key : keyToEntity.keySet()) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/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
index 089343c..7a8ac59 100644
--- 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
@@ -32,6 +32,10 @@ public interface ReferencingYamlTestEntity extends Entity {
             .name("test.reference.root")
             .build();
     @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_SCOPE_ROOT = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.scope_root")
+            .build();
+    @SuppressWarnings("serial")
     public static final ConfigKey<Entity> TEST_REFERENCE_APP = BasicConfigKey.builder(new TypeToken<Entity>(){})
             .name("test.reference.app")
             .build();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b1b82f9b/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 ebe4662..c87a8de 100644
--- a/usage/camp/src/test/resources/test-referencing-entities.yaml
+++ b/usage/camp/src/test/resources/test-referencing-entities.yaml
@@ -38,6 +38,7 @@ origin: https://github.com/apache/incubator-brooklyn
 id: app1
 brooklyn.config:
   test.reference.root: $brooklyn:root()
+  test.reference.scope_root: $brooklyn:scopeRoot()
   test.reference.app: $brooklyn:component("app1")
   test.reference.entity1: $brooklyn:entity("e1")
   test.reference.entity1a: $brooklyn:config("test.reference.entity1")
@@ -53,6 +54,7 @@ services:
   name: entity 1
   brooklyn.config:
     test.reference.root: $brooklyn:root()
+    test.reference.scope_root: $brooklyn:scopeRoot()
     test.reference.app: $brooklyn:component("parent", "ignored")
     test.reference.entity1: $brooklyn:component("this", "ignored")
     test.reference.entity1a: $brooklyn:ancestor("app1").child("e1")
@@ -69,6 +71,7 @@ services:
       brooklyn.config:
         self: $brooklyn:entity("c1")
         test.reference.root: $brooklyn:root()
+        test.reference.scope_root: $brooklyn:scopeRoot()
         test.reference.app: $brooklyn:parent().parent()
         test.reference.entity1: $brooklyn:parent()
         test.reference.entity1a: $brooklyn:entity("e1").parent().child("e1")
@@ -84,6 +87,7 @@ services:
         name: grandchild 1
         brooklyn.config:
           test.reference.root: $brooklyn:root()
+          test.reference.scope_root: $brooklyn:scopeRoot()
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
           test.reference.entity2: $brooklyn:component("e2")
@@ -96,6 +100,7 @@ services:
         name: grandchild 2
         brooklyn.config:
           test.reference.root: $brooklyn:root()
+          test.reference.scope_root: $brooklyn:scopeRoot()
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
           test.reference.entity2: $brooklyn:component("e2")
@@ -108,6 +113,7 @@ services:
       name: child 2
       brooklyn.config:
         test.reference.root: $brooklyn:root()
+        test.reference.scope_root: $brooklyn:scopeRoot()
         test.reference.app: $brooklyn:parent().parent().descendant("app1")
         test.reference.entity1: $brooklyn:component("e1")
         test.reference.entity2: $brooklyn:component("e2")
@@ -120,6 +126,7 @@ services:
   name: entity 2
   brooklyn.config:
     test.reference.root: $brooklyn:root()
+    test.reference.scope_root: $brooklyn:scopeRoot()
     test.reference.app: $brooklyn:component("app1")
     test.reference.entity1: $brooklyn:component("e1")
     test.reference.entity2: $brooklyn:component("e2")


[10/21] incubator-brooklyn git commit: Add root scope in CAMP DSL - the application

Posted by he...@apache.org.
Add root scope in CAMP DSL - the application


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

Branch: refs/heads/master
Commit: 1da725f4a4809d655b77a1cdfaae20a2ab3e18be
Parents: f16cbe0
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Nov 4 14:57:58 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:39 2015 +0200

----------------------------------------------------------------------
 .../camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java    | 3 +++
 .../camp/brooklyn/spi/dsl/methods/DslComponent.java         | 8 +++++++-
 .../org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java | 9 ++++++++-
 .../brooklyn/camp/brooklyn/ReferencingYamlTestEntity.java   | 4 ++++
 .../camp/src/test/resources/test-referencing-entities.yaml  | 7 +++++++
 5 files changed, 29 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1da725f4/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
index cb41f20..422dac3 100644
--- 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
@@ -84,6 +84,9 @@ public class BrooklynDslCommon {
     public static DslComponent ancestor(String id) {
         return new DslComponent(Scope.ANCESTOR, id);
     }
+    public static DslComponent root() {
+        return new DslComponent(Scope.ROOT, null);
+    }
     // prefer the syntax above to the below now, but not deprecating the below
     public static DslComponent component(String id) {
         return component("global", id);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1da725f4/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
index 149a88a..d5f3078 100644
--- 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
@@ -108,6 +108,8 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
                     entitiesToSearch = ((EntityManagerInternal)getEntity().getManagementContext().getEntityManager())
                         .getAllEntitiesInApplication( entity().getApplication() );
                     break;
+                case ROOT:
+                    return getEntity().getApplication();
                 case DESCENDANT:
                     entitiesToSearch = Entities.descendants(getEntity());
                     break;
@@ -155,6 +157,9 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
     public DslComponent ancestor(String scopeOrId) {
         return new DslComponent(this, Scope.ANCESTOR, scopeOrId);
     }
+    public DslComponent root() {
+        return new DslComponent(this, Scope.ROOT, "");
+    }
     
     @Deprecated /** @deprecated since 0.7.0 */
     public DslComponent component(String scopeOrId) {
@@ -277,9 +282,10 @@ public class DslComponent extends BrooklynDslDeferredSupplier<Entity> {
         SIBLING ("sibling"),
         DESCENDANT ("descendant"),
         ANCESTOR("ancestor"),
+        ROOT("root"),
         THIS ("this");
         
-        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, THIS);
+        public static final Set<Scope> VALUES = ImmutableSet.of(GLOBAL, CHILD, PARENT, SIBLING, DESCENDANT, ANCESTOR, ROOT, THIS);
         
         private final String name;
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1da725f4/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
index 6dd636d..266772b 100644
--- 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
@@ -402,12 +402,18 @@ public class EntitiesYamlTest extends AbstractYamlTest {
         final Entity app = createAndStartApplication(loadYaml("test-referencing-entities.yaml"));
         waitForApplicationTasks(app);
         
+        Entity root1 = Tasks.resolving(new DslComponent(Scope.ROOT, "xxx").newTask(), Entity.class).context( ((EntityInternal)app).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(root1, 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 root2 = Tasks.resolving(new DslComponent(Scope.ROOT, "xxx").newTask(), Entity.class).context( ((EntityInternal)c1).getExecutionContext() ).embedResolutionInTask(true).get();
+        Assert.assertEquals(root2, app);
+        
         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();
@@ -460,6 +466,7 @@ public class EntitiesYamlTest extends AbstractYamlTest {
         Assert.assertNotNull(grandchild2);
 
         Map<ConfigKey<Entity>, Entity> keyToEntity = new ImmutableMap.Builder<ConfigKey<Entity>, Entity>()
+            .put(ReferencingYamlTestEntity.TEST_REFERENCE_ROOT, app)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_APP, app)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1, entity1)
             .put(ReferencingYamlTestEntity.TEST_REFERENCE_ENTITY1_ALT, entity1)
@@ -491,7 +498,7 @@ public class EntitiesYamlTest extends AbstractYamlTest {
     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));
+                Assert.assertEquals(getResolvedConfigInTask(entity, key).get(), keyToEntity.get(key), "For entity " + entity.toString() + ":");
             } catch (Throwable t) {
                 Exceptions.propagateIfFatal(t);
                 Assert.fail("Wrong value for "+entity+":"+key+", "+((EntityInternal)entity).config().getLocalRaw(key)+": "+t, t);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1da725f4/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
index 8cbd780..089343c 100644
--- 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
@@ -28,6 +28,10 @@ import com.google.common.reflect.TypeToken;
 @ImplementedBy(ReferencingYamlTestEntityImpl.class)
 public interface ReferencingYamlTestEntity extends Entity {
     @SuppressWarnings("serial")
+    public static final ConfigKey<Entity> TEST_REFERENCE_ROOT = BasicConfigKey.builder(new TypeToken<Entity>(){})
+            .name("test.reference.root")
+            .build();
+    @SuppressWarnings("serial")
     public static final ConfigKey<Entity> TEST_REFERENCE_APP = BasicConfigKey.builder(new TypeToken<Entity>(){})
             .name("test.reference.app")
             .build();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1da725f4/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 19944c3..ebe4662 100644
--- a/usage/camp/src/test/resources/test-referencing-entities.yaml
+++ b/usage/camp/src/test/resources/test-referencing-entities.yaml
@@ -37,6 +37,7 @@ description: Test multi-layer application with each entity referencing all other
 origin: https://github.com/apache/incubator-brooklyn
 id: app1
 brooklyn.config:
+  test.reference.root: $brooklyn:root()
   test.reference.app: $brooklyn:component("app1")
   test.reference.entity1: $brooklyn:entity("e1")
   test.reference.entity1a: $brooklyn:config("test.reference.entity1")
@@ -51,6 +52,7 @@ services:
   id: e1
   name: entity 1
   brooklyn.config:
+    test.reference.root: $brooklyn:root()
     test.reference.app: $brooklyn:component("parent", "ignored")
     test.reference.entity1: $brooklyn:component("this", "ignored")
     test.reference.entity1a: $brooklyn:ancestor("app1").child("e1")
@@ -66,6 +68,7 @@ services:
       name: child 1
       brooklyn.config:
         self: $brooklyn:entity("c1")
+        test.reference.root: $brooklyn:root()
         test.reference.app: $brooklyn:parent().parent()
         test.reference.entity1: $brooklyn:parent()
         test.reference.entity1a: $brooklyn:entity("e1").parent().child("e1")
@@ -80,6 +83,7 @@ services:
         id: gc1
         name: grandchild 1
         brooklyn.config:
+          test.reference.root: $brooklyn:root()
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
           test.reference.entity2: $brooklyn:component("e2")
@@ -91,6 +95,7 @@ services:
         id: gc2
         name: grandchild 2
         brooklyn.config:
+          test.reference.root: $brooklyn:root()
           test.reference.app: $brooklyn:component("app1")
           test.reference.entity1: $brooklyn:component("e1")
           test.reference.entity2: $brooklyn:component("e2")
@@ -102,6 +107,7 @@ services:
       id: c2
       name: child 2
       brooklyn.config:
+        test.reference.root: $brooklyn:root()
         test.reference.app: $brooklyn:parent().parent().descendant("app1")
         test.reference.entity1: $brooklyn:component("e1")
         test.reference.entity2: $brooklyn:component("e2")
@@ -113,6 +119,7 @@ services:
   id: e2
   name: entity 2
   brooklyn.config:
+    test.reference.root: $brooklyn:root()
     test.reference.app: $brooklyn:component("app1")
     test.reference.entity1: $brooklyn:component("e1")
     test.reference.entity2: $brooklyn:component("e2")


[17/21] incubator-brooklyn git commit: Unwrap camp plan with parent overriding child displayName

Posted by he...@apache.org.
Unwrap camp plan with parent overriding child displayName

Don't prevent unwrapping in case displayName is different, override the child's name instead


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

Branch: refs/heads/master
Commit: 94263c60ca54f37dab8855b48cc38f47bd11d23e
Parents: ae30539
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Nov 6 18:48:05 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Mon Nov 9 12:49:38 2015 +0200

----------------------------------------------------------------------
 .../core/mgmt/EntityManagementUtils.java        |  31 +---
 .../brooklyn/camp/brooklyn/AppYamlTest.java     |   9 +-
 .../camp/brooklyn/ApplicationsYamlTest.java     | 163 ++++++++++++++++---
 3 files changed, 149 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/94263c60/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index 9c4ebc1..59bcc87 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -246,7 +246,7 @@ public class EntityManagementUtils {
      * See {@link #WRAPPER_APP_MARKER}. */
     @Beta //where should this live long-term?
     public static void mergeWrapperParentSpecToChildEntity(EntitySpec<? extends Application> wrapperParent, EntitySpec<?> wrappedChild) {
-        if (Strings.isEmpty(wrappedChild.getDisplayName()))
+        if (Strings.isNonEmpty(wrapperParent.getDisplayName()))
             wrappedChild.displayName(wrapperParent.getDisplayName());
         if (!wrapperParent.getLocations().isEmpty())
             wrappedChild.locations(wrapperParent.getLocations());
@@ -270,7 +270,7 @@ public class EntityManagementUtils {
      * for use when adding from a plan specifying an application which was wrapped because it had to be.
      * @see #WRAPPER_APP_MARKER */
     public static boolean canPromoteWrappedApplication(EntitySpec<? extends Application> app) {
-        if (app.getChildren().size()!=1)
+        if (!hasSingleChild(app))
             return false;
 
         EntitySpec<?> childSpec = Iterables.getOnlyElement(app.getChildren());
@@ -283,9 +283,8 @@ public class EntityManagementUtils {
     /** returns true if the spec is for an empty-ish wrapper app, 
      * for use when adding from a plan specifying multiple entities but nothing significant at the application level.
      * @see #WRAPPER_APP_MARKER */
-    public static boolean canPromoteChildrenInWrappedApplication(EntitySpec<?> spec) {
-        return canPromoteBasedOnName(spec) &&
-                isWrapperApp(spec) &&
+    public static boolean canPromoteChildrenInWrappedApplication(EntitySpec<? extends Application> spec) {
+        return isWrapperApp(spec) && hasSingleChild(spec) &&
                 //equivalent to no keys starting with "brooklyn."
                 spec.getEnrichers().isEmpty() &&
                 spec.getInitializers().isEmpty() &&
@@ -296,26 +295,8 @@ public class EntityManagementUtils {
         return Boolean.TRUE.equals(spec.getConfig().get(EntityManagementUtils.WRAPPER_APP_MARKER));
     }
 
-    private static boolean canPromoteBasedOnName(EntitySpec<?> spec) {
-        if (!Strings.isEmpty(spec.getDisplayName())) {
-            if (spec.getChildren().size()==1) {
-                String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName();
-                if (Strings.isEmpty(childName) || childName.equals(spec.getDisplayName())) {
-                    // if child has no name, or it's the same, could still promote
-                    return true;
-                } else {
-                    return false;
-                }
-            } else {
-                // if name set at root and promoting children would be ambiguous, do not promote 
-                return false;
-            }
-        } else if (spec.getChildren().size()>1) {
-            // don't allow multiple children if a name is specified as a root
-            return false;
-        } else {
-            return true;
-        }
+    private static boolean hasSingleChild(EntitySpec<?> spec) {
+        return spec.getChildren().size() == 1;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/94263c60/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
index c4e1d7d..c462889 100644
--- 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
@@ -19,10 +19,13 @@
 package org.apache.brooklyn.camp.brooklyn;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 import java.io.StringReader;
 
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.entity.stock.BasicApplication;
@@ -66,10 +69,10 @@ public class AppYamlTest extends AbstractYamlTest {
                 "- serviceType: org.apache.brooklyn.core.test.entity.TestApplication",
                 "  name: myEntityName");
         
-        BasicApplication app = (BasicApplication) createStartWaitAndLogApplication(new StringReader(yaml));
-        TestApplication entity = (TestApplication) Iterables.getOnlyElement(app.getChildren());
+        Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
+        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
         assertEquals(app.getDisplayName(), "myTopLevelName");
-        assertEquals(entity.getDisplayName(), "myEntityName");
+        assertEquals(app.getChildren().size(), 0);
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/94263c60/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
index 01d90f5..b58e5ca 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
@@ -22,8 +22,14 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
+import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.camp.brooklyn.TestSensorAndEffectorInitializer.TestConfigurableInitializer;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.policy.TestEnricher;
+import org.apache.brooklyn.core.test.policy.TestPolicy;
 import org.apache.brooklyn.entity.stock.BasicApplication;
 import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.slf4j.Logger;
@@ -36,24 +42,31 @@ import com.google.common.collect.Iterables;
 public class ApplicationsYamlTest extends AbstractYamlTest {
     private static final Logger log = LoggerFactory.getLogger(ApplicationsYamlTest.class);
 
+    @Override
+    protected LocalManagementContext newTestManagementContext() {
+        // Don't need osgi
+        return LocalManagementContextForTests.newInstance();
+    }
+
     @Test
     public void testWrapsEntity() throws Exception {
         Entity app = createAndStartApplication(
                 "services:",
                 "- type: " + BasicEntity.class.getName());
-        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-        assertTrue(app instanceof BasicApplication);
-        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicEntity);
+        assertWrapped(app, BasicEntity.class);
     }
 
     @Test
-    public void testDoesNotWrapApp() throws Exception {
+    public void testWrapsMultipleApps() throws Exception {
         Entity app = createAndStartApplication(
                 "services:",
+                "- type: " + BasicApplication.class.getName(),
                 "- type: " + BasicApplication.class.getName());
-        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
         assertTrue(app instanceof BasicApplication);
-        assertTrue(app.getChildren().isEmpty());
+        assertEquals(app.getChildren().size(), 2);
+    }
+
     }
 
     @Test
@@ -62,10 +75,15 @@ public class ApplicationsYamlTest extends AbstractYamlTest {
                 "wrappedApp: true",
                 "services:",
                 "- type: " + BasicApplication.class.getName());
-        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-        assertTrue(app instanceof BasicApplication);
-        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicApplication);
-        assertTrue(Iterables.getOnlyElement(app.getChildren()).getChildren().isEmpty());
+        assertWrapped(app, BasicApplication.class);
+    }
+
+    @Test
+    public void testDoesNotWrapApp() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertDoesNotWrap(app, BasicApplication.class, null);
     }
 
     @Test
@@ -74,41 +92,134 @@ public class ApplicationsYamlTest extends AbstractYamlTest {
                 "wrappedApp: false",
                 "services:",
                 "- type: " + BasicApplication.class.getName());
-        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-        assertTrue(app instanceof BasicApplication);
-        assertTrue(app.getChildren().isEmpty());
+        assertDoesNotWrap(app, BasicApplication.class, null);
     }
     
     @Test
-    public void testWrapsEntityIfDifferentTopLevelName() throws Exception {
+    public void testDoesNotWrapEntityIfDifferentTopLevelName() throws Exception {
         Entity app = createAndStartApplication(
                 "name: topLevel",
                 "services:",
                 "- type: " + BasicApplication.class.getName(),
                 "  name: bottomLevel");
-        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-        assertTrue(app instanceof BasicApplication);
-        assertEquals(app.getDisplayName(), "topLevel");
-        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicApplication);
-        assertTrue(Iterables.getOnlyElement(app.getChildren()).getChildren().isEmpty());
-        assertEquals(Iterables.getOnlyElement(app.getChildren()).getDisplayName(), "bottomLevel");
+        assertDoesNotWrap(app, BasicApplication.class, "topLevel");
     }
-    
+
     @Test
     public void testDoesNotWrapsEntityIfNoNameOnService() throws Exception {
         Entity app = createAndStartApplication(
                 "name: topLevel",
                 "services:",
                 "- type: " + BasicApplication.class.getName());
-        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-        assertTrue(app instanceof BasicApplication);
-        assertTrue(app.getChildren().isEmpty());
-        assertEquals(app.getDisplayName(), "topLevel");
+        assertDoesNotWrap(app, BasicApplication.class, "topLevel");
     }
-    
+
+    @Test
+    public void testDoesNotWrapCatalogItemWithDisplayName() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple",
+                "  version: " + TEST_VERSION,
+                "  displayName: catalogLevel",
+                "  item:",
+                "    services:",
+                "    - type: " + BasicApplication.class.getName());
+        Entity app = createAndStartApplication(
+                "name: topLevel",
+                "services:",
+                "- type: simple:" + TEST_VERSION);
+        assertDoesNotWrap(app, BasicApplication.class, "topLevel");
+    }
+
+    @Test
+    public void testDoesNotWrapCatalogItemWithServiceName() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple",
+                "  version: " + TEST_VERSION,
+                "  displayName: catalogLevel",
+                "  item:",
+                "    services:",
+                "    - type: " + BasicApplication.class.getName(),
+                "      defaultDisplayName: defaultServiceName",
+                "      displayName: explicitServiceName");
+        Entity app = createAndStartApplication(
+                "name: topLevel",
+                "services:",
+                "- type: simple:" + TEST_VERSION);
+        assertDoesNotWrap(app, BasicApplication.class, "topLevel");
+    }
+
+    @Test
+    public void testDoesNotWrapCatalogItemAndOverridesName() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple",
+                "  version: " + TEST_VERSION,
+                "  displayName: catalogLevel",
+                "  item:",
+                "    services:",
+                "    - type: " + BasicApplication.class.getName());
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: simple:" + TEST_VERSION,
+                "  name: serviceLevel");
+        assertDoesNotWrap(app, BasicApplication.class, "serviceLevel");
+    }
+
+    @Test
+    public void testDoesNotWrapCatalogItemAndUsesCatalogName() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple",
+                "  version: " + TEST_VERSION,
+                "  displayName: catalogLevel",
+                "  item:",
+                "    services:",
+                "    - type: " + BasicApplication.class.getName());
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: simple:" + TEST_VERSION);
+        assertDoesNotWrap(app, BasicApplication.class, "catalogLevel");
+    }
+
+    @Test
+    public void testDoesNotWrapCatalogItemAndUsesCatalogServiceName() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple",
+                "  version: " + TEST_VERSION,
+                "  displayName: catalogLevel",
+                "  item:",
+                "    services:",
+                "    - type: " + BasicApplication.class.getName(),
+                "      name: catalogServiceLevel");
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: simple:" + TEST_VERSION);
+        assertDoesNotWrap(app, BasicApplication.class, "catalogServiceLevel");
+    }
+
     @Override
     protected Logger getLogger() {
         return log;
     }
 
+    private void assertWrapped(Entity app, Class<? extends Entity> wrappedEntityType) {
+        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        Entity child = Iterables.getOnlyElement(app.getChildren());
+        assertTrue(wrappedEntityType.isInstance(child));
+        assertTrue(child.getChildren().isEmpty());
+    }
+
+    private void assertDoesNotWrap(Entity app, Class<? extends Application> entityType, String displayName) {
+        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(entityType.isInstance(app));
+        if (displayName != null) {
+            assertEquals(app.getDisplayName(), displayName);
+        }
+        assertEquals(app.getChildren().size(), 0);
+    }
+    
 }


[15/21] incubator-brooklyn git commit: Disable consistently failing integration tests

Posted by he...@apache.org.
Disable consistently failing integration tests


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

Branch: refs/heads/master
Commit: 35a227f0bc4902854328b974340db4fbcaec4f76
Parents: 5389739
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Nov 5 22:12:37 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Fri Nov 6 16:20:16 2015 +0200

----------------------------------------------------------------------
 parent/pom.xml                                  |   8 +-
 pom.xml                                         |   2 +-
 .../BrooklynNodeIntegrationTest.java            |  49 +++-
 .../mysql/MySqlRestartIntegrationTest.java      |   9 +
 .../rubyrep/RubyRepIntegrationTest.java         | 285 ++++++++++++++++++-
 .../nosql/riak/RiakNodeIntegrationTest.java     | 168 ++++++++++-
 .../dns/geoscaling/GeoscalingWebClientTest.java |  62 ++++
 .../proxy/nginx/NginxRebindIntegrationTest.java |  83 +++++-
 ...namicWebAppClusterRebindIntegrationTest.java |  41 ++-
 ...namicWebAppClusterRebindIntegrationTest.java |  41 ++-
 .../NodeJsWebAppFixtureIntegrationTest.java     |   9 +-
 .../apache/brooklyn/cli/CliIntegrationTest.java |  98 ++++++-
 .../BrooklynPropertiesSecurityFilterTest.java   |  43 ++-
 .../brooklyn/util/maven/MavenArtifactTest.java  |  80 +++++-
 14 files changed, 954 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 2c18672..c626bc9 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1332,7 +1332,7 @@
             <id>Integration</id>
             <properties>
                 <includedTestGroups>Integration</includedTestGroups>
-                <excludedTestGroups>Acceptance,Live,WIP</excludedTestGroups>
+                <excludedTestGroups>Acceptance,Live,WIP,Broken</excludedTestGroups>
             </properties>
             <build>
                 <plugins>
@@ -1367,7 +1367,7 @@
             <id>Acceptance</id>
             <properties>
                 <includedTestGroups>Acceptance</includedTestGroups>
-                <excludedTestGroups>Integration,Live,WIP</excludedTestGroups>
+                <excludedTestGroups>Integration,Live,WIP,Broken</excludedTestGroups>
             </properties>
             <build>
                 <plugins>
@@ -1402,7 +1402,7 @@
             <id>Live</id>
             <properties>
                 <includedTestGroups>Live</includedTestGroups>
-                <excludedTestGroups>Acceptance,WIP</excludedTestGroups>
+                <excludedTestGroups>Acceptance,WIP,Broken</excludedTestGroups>
             </properties>
             <build>
                 <plugins>
@@ -1425,7 +1425,7 @@
             <id>Live-sanity</id>
             <properties>
                 <includedTestGroups>Live-sanity</includedTestGroups>
-                <excludedTestGroups>Acceptance,WIP</excludedTestGroups>
+                <excludedTestGroups>Acceptance,WIP,Broken</excludedTestGroups>
             </properties>
             <build>
                 <plugins>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5624c80..a414b6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,7 +85,7 @@
         <plantuml.version>6121</plantuml.version>
         <ant.version>1.8.4</ant.version>
         <includedTestGroups />
-        <excludedTestGroups>Integration,Acceptance,Live,WIP</excludedTestGroups>
+        <excludedTestGroups>Integration,Acceptance,Live,WIP,Broken</excludedTestGroups>
         <surefire.failIfNoSpecifiedTests>false</surefire.failIfNoSpecifiedTests>
 
         <!-- Dependencies -->

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index 16c1e9c..3e898b0 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -329,7 +329,54 @@ services:
         }
     }
 
-    @Test(groups="Integration")
+    /*
+        Exception java.io.FileNotFoundException
+        
+        Message: /tmp/1445824492556-0/lib/first4759470075693094333.properties (No such file or directory)
+        Stacktrace:
+        
+        
+        at java.io.FileInputStream.open(Native Method)
+        at java.io.FileInputStream.<init>(FileInputStream.java:146)
+        at com.google.common.io.Files$FileByteSource.openStream(Files.java:126)
+        at com.google.common.io.Files$FileByteSource.openStream(Files.java:116)
+        at com.google.common.io.ByteSource$AsCharSource.openStream(ByteSource.java:435)
+        at com.google.common.io.CharSource.getInput(CharSource.java:94)
+        at com.google.common.io.CharSource.getInput(CharSource.java:65)
+        at com.google.common.io.CharStreams.readLines(CharStreams.java:344)
+        at com.google.common.io.Files.readLines(Files.java:741)
+        at com.google.common.io.Files.readLines(Files.java:712)
+        at org.apache.brooklyn.entity.brooklynnode.BrooklynNodeIntegrationTest.testCopiesClasspathEntriesInBrooklynProperties(BrooklynNodeIntegrationTest.java:358)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+    */
+    @Test(groups={"Integration","Broken"})
     public void testCopiesClasspathEntriesInBrooklynProperties() throws Exception {
         String content = "abc=def";
         File classpathEntry1 = File.createTempFile("first", ".properties");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlRestartIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlRestartIntegrationTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlRestartIntegrationTest.java
index f7913f0..1e2aa91 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlRestartIntegrationTest.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/mysql/MySqlRestartIntegrationTest.java
@@ -38,4 +38,13 @@ public class MySqlRestartIntegrationTest extends AbstractSoftwareProcessRestartI
     protected EntitySpec<? extends SoftwareProcess> newEntitySpec() {
         return EntitySpec.create(MySqlNode.class);
     }
+
+    //Fails setting the password on second start (because already changed from first launch)
+    @Override
+    @Test(groups={"Integration","Broken"})
+    public void testStopProcessAndStart() throws Exception {
+        super.testStopProcessAndStart();
+    }
+    
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/database/src/test/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
index 76f84ec..7127334 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
@@ -64,7 +64,149 @@ public class RubyRepIntegrationTest {
         Entities.destroyAllCatching(managementContext);
     }
 
-    @Test(groups = "Integration")
+    /*
+        Exception org.apache.brooklyn.util.exceptions.PropagatedRuntimeException
+        
+        Message: (none)
+        Stacktrace:
+        
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicTasks$TaskQueueingResult.andWaitForSuccess(DynamicTasks.java:159)
+        at org.apache.brooklyn.core.objs.proxy.EntityProxyImpl.invoke(EntityProxyImpl.java:211)
+        at com.sun.proxy.$Proxy49.start(Unknown Source)
+        at org.apache.brooklyn.entity.database.rubyrep.RubyRepIntegrationTest.startInLocation(RubyRepIntegrationTest.java:139)
+        at org.apache.brooklyn.entity.database.rubyrep.RubyRepIntegrationTest.startInLocation(RubyRepIntegrationTest.java:119)
+        at org.apache.brooklyn.entity.database.rubyrep.RubyRepIntegrationTest.test_localhost_mysql(RubyRepIntegrationTest.java:80)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[r1CKCG7x]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 34 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[r1CKCG7x]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:255)
+        at org.apache.brooklyn.core.effector.MethodEffector.call(MethodEffector.java:149)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:56)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:50)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicExecutionManager$SubmissionCallable.call(BasicExecutionManager.java:468)
+        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
+        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
+        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
+        at java.lang.Thread.run(Thread.java:745)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:332)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:250)
+        ... 10 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.core.entity.trait.StartableMethods.start(StartableMethods.java:53)
+        at org.apache.brooklyn.core.entity.AbstractApplication.doStart(AbstractApplication.java:178)
+        at org.apache.brooklyn.core.entity.AbstractApplication.start(AbstractApplication.java:155)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
+        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
+        at groovy.lang.DelegatingMetaClass.invokeMethod(DelegatingMetaClass.java:149)
+        at groovy.lang.MetaObjectProtocol$invokeMethod.call(Unknown Source)
+        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
+        at groovy.lang.MetaObjectProtocol$invokeMethod.call(Unknown Source)
+        at org.apache.brooklyn.util.groovy.GroovyJavaMethods.invokeMethodOnMetaClass(GroovyJavaMethods.java:191)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodLocal(AbstractManagementContext.java:304)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:328)
+        ... 11 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 29 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 3 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.create(Exceptions.java:299)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:287)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:81)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:81)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:79)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:63)
+        ... 7 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=pePPOzBw}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$2.handleException(EffectorTasks.java:90)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.handleException(DynamicSequentialTask.java:452)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:400)
+        ... 5 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.drain(DynamicSequentialTask.java:475)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.drain(DynamicTasks.java:313)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.waitForLast(DynamicTasks.java:302)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks.start(MachineLifecycleEffectorTasks.java:314)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:214)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:201)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 13 more
+        Caused by: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=pePPOzBw} did not pass is-running check within the required 2m limit (2m 2s elapsed)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessImpl.waitForEntityStart(SoftwareProcessImpl.java:592)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessImpl.postDriverStart(SoftwareProcessImpl.java:266)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessDriverLifecycleEffectorTasks.postStartCustom(SoftwareProcessDriverLifecycleEffectorTasks.java:169)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$PostStartTask.run(MachineLifecycleEffectorTasks.java:572)
+        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
+        ... 6 more
+     */
+    @Test(groups = {"Integration","Broken"})
     public void test_localhost_mysql() throws Exception {
         MySqlNode db1 = tapp.createAndManageChild(EntitySpec.create(MySqlNode.class)
                 .configure(DatastoreCommon.CREATION_SCRIPT_CONTENTS, MySqlIntegrationTest.CREATION_SCRIPT)
@@ -81,10 +223,149 @@ public class RubyRepIntegrationTest {
         testReplication(db1, db2);
     }
 
+    /*
+        Exception org.apache.brooklyn.util.exceptions.PropagatedRuntimeException
+        
+        Message: (none)
+        Stacktrace:
+        
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicTasks$TaskQueueingResult.andWaitForSuccess(DynamicTasks.java:159)
+        at org.apache.brooklyn.core.objs.proxy.EntityProxyImpl.invoke(EntityProxyImpl.java:211)
+        at com.sun.proxy.$Proxy53.start(Unknown Source)
+        at org.apache.brooklyn.entity.database.rubyrep.RubyRepIntegrationTest.startInLocation(RubyRepIntegrationTest.java:139)
+        at org.apache.brooklyn.entity.database.rubyrep.RubyRepIntegrationTest.test_localhost_postgres(RubyRepIntegrationTest.java:98)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[OTSda29h]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 33 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[OTSda29h]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:255)
+        at org.apache.brooklyn.core.effector.MethodEffector.call(MethodEffector.java:149)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:56)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:50)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicExecutionManager$SubmissionCallable.call(BasicExecutionManager.java:468)
+        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
+        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
+        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
+        at java.lang.Thread.run(Thread.java:745)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:332)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:250)
+        ... 10 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.core.entity.trait.StartableMethods.start(StartableMethods.java:53)
+        at org.apache.brooklyn.core.entity.AbstractApplication.doStart(AbstractApplication.java:178)
+        at org.apache.brooklyn.core.entity.AbstractApplication.start(AbstractApplication.java:155)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
+        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
+        at groovy.lang.DelegatingMetaClass.invokeMethod(DelegatingMetaClass.java:149)
+        at groovy.lang.MetaObjectProtocol$invokeMethod.call(Unknown Source)
+        at org.apache.brooklyn.util.groovy.GroovyJavaMethods.invokeMethodOnMetaClass(GroovyJavaMethods.java:191)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodLocal(AbstractManagementContext.java:304)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:328)
+        ... 11 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 27 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: 1 of 2 parallel child tasks failed: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.create(Exceptions.java:299)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:287)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:81)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:81)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:79)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:63)
+        ... 7 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RubyRepNodeImpl{id=VhsCCM9k}: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$2.handleException(EffectorTasks.java:90)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.handleException(DynamicSequentialTask.java:452)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:400)
+        ... 5 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.drain(DynamicSequentialTask.java:475)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.drain(DynamicTasks.java:313)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.waitForLast(DynamicTasks.java:302)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks.start(MachineLifecycleEffectorTasks.java:314)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:214)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:201)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 13 more
+        Caused by: java.lang.IllegalStateException: Software process entity RubyRepNodeImpl{id=VhsCCM9k} did not pass is-running check within the required 2m limit (2m 1s elapsed)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessImpl.waitForEntityStart(SoftwareProcessImpl.java:592)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessImpl.postDriverStart(SoftwareProcessImpl.java:266)
+        at org.apache.brooklyn.entity.software.base.SoftwareProcessDriverLifecycleEffectorTasks.postStartCustom(SoftwareProcessDriverLifecycleEffectorTasks.java:169)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$PostStartTask.run(MachineLifecycleEffectorTasks.java:572)
+        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
+        ... 6 more
+     */
     /**
      * Altered to use a single postgresql server to avoid issues with shared memory limits
      */
-    @Test(groups = {"Integration"})
+    @Test(groups = {"Integration","Broken"})
     public void test_localhost_postgres() throws Exception {
         String createTwoDbsScript = PostgreSqlIntegrationTest.CREATION_SCRIPT +
                 PostgreSqlIntegrationTest.CREATION_SCRIPT.replaceAll("CREATE USER.*", "").replaceAll(" feedback", " feedback1");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
index cf69bcd..0b2a924 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
@@ -50,7 +50,173 @@ public class RiakNodeIntegrationTest {
     }
 
 
-    @Test(groups = "Integration")
+    /*
+        Exception org.apache.brooklyn.util.exceptions.PropagatedRuntimeException
+        
+        Message: (none)
+        Stacktrace:
+        
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicTasks$TaskQueueingResult.andWaitForSuccess(DynamicTasks.java:159)
+        at org.apache.brooklyn.core.objs.proxy.EntityProxyImpl.invoke(EntityProxyImpl.java:211)
+        at com.sun.proxy.$Proxy267.start(Unknown Source)
+        at org.apache.brooklyn.entity.nosql.riak.RiakNodeIntegrationTest.testCanStartAndStop(RiakNodeIntegrationTest.java:57)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[bHAUtUrk]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 32 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at Application[bHAUtUrk]: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:255)
+        at org.apache.brooklyn.core.effector.MethodEffector.call(MethodEffector.java:149)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:56)
+        at org.apache.brooklyn.core.entity.trait.Startable$StartEffectorBody.call(Startable.java:50)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicExecutionManager$SubmissionCallable.call(BasicExecutionManager.java:468)
+        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
+        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
+        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
+        at java.lang.Thread.run(Thread.java:745)
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:332)
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.invokeMethodEffector(EffectorUtils.java:250)
+        ... 10 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.core.entity.trait.StartableMethods.start(StartableMethods.java:53)
+        at org.apache.brooklyn.core.entity.AbstractApplication.doStart(AbstractApplication.java:178)
+        at org.apache.brooklyn.core.entity.AbstractApplication.start(AbstractApplication.java:155)
+        at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
+        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1085)
+        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
+        at groovy.lang.DelegatingMetaClass.invokeMethod(DelegatingMetaClass.java:149)
+        at groovy.lang.MetaObjectProtocol$invokeMethod.call(Unknown Source)
+        at org.apache.brooklyn.util.groovy.GroovyJavaMethods.invokeMethodOnMetaClass(GroovyJavaMethods.java:191)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodLocal(AbstractManagementContext.java:304)
+        at org.apache.brooklyn.core.mgmt.internal.AbstractManagementContext.invokeEffectorMethodSync(AbstractManagementContext.java:328)
+        ... 11 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 26 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:80)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:81)
+        at org.apache.brooklyn.util.core.task.CompoundTask$1.call(CompoundTask.java:79)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.ParallelTask.runJobs(ParallelTask.java:63)
+        ... 7 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: Error invoking start at RiakNodeImpl{id=EA5VTSqO}: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.core.mgmt.internal.EffectorUtils.handleEffectorException(EffectorUtils.java:270)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$2.handleException(EffectorTasks.java:90)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.handleException(DynamicSequentialTask.java:452)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:400)
+        ... 5 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.drain(DynamicSequentialTask.java:475)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.drain(DynamicTasks.java:313)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.waitForLast(DynamicTasks.java:302)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks.start(MachineLifecycleEffectorTasks.java:314)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:214)
+        at org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks$StartEffectorBody.call(MachineLifecycleEffectorTasks.java:201)
+        at org.apache.brooklyn.core.effector.EffectorTasks$EffectorBodyTaskFactory$1.call(EffectorTasks.java:82)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 13 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask.drain(DynamicSequentialTask.java:475)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.drain(DynamicTasks.java:313)
+        at org.apache.brooklyn.util.core.task.DynamicTasks.waitForLast(DynamicTasks.java:302)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:383)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 9 more
+        Caused by: org.apache.brooklyn.util.exceptions.PropagatedRuntimeException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.util.exceptions.Exceptions.propagate(Exceptions.java:103)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:353)
+        at org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper.execute(ScriptHelper.java:337)
+        at org.apache.brooklyn.entity.nosql.riak.RiakNodeSshDriver.launch(RiakNodeSshDriver.java:335)
+        at org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessDriver$11.run(AbstractSoftwareProcessDriver.java:163)
+        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
+        at org.apache.brooklyn.util.core.task.DynamicSequentialTask$DstJob.call(DynamicSequentialTask.java:342)
+        ... 5 more
+        Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
+        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
+        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:63)
+        at org.apache.brooklyn.util.core.task.BasicTask.get(BasicTask.java:342)
+        at org.apache.brooklyn.util.core.task.BasicTask.getUnchecked(BasicTask.java:351)
+        ... 10 more
+        Caused by: java.lang.IllegalStateException: Execution failed, invalid result 1 for launching RiakNodeImpl{id=EA5VTSqO}
+        at org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper.logWithDetailsAndThrow(ScriptHelper.java:388)
+        at org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper.executeInternal(ScriptHelper.java:377)
+        at org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper$8.call(ScriptHelper.java:287)
+        at org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper$8.call(ScriptHelper.java:285)
+        ... 6 more
+     */
+    @Test(groups = {"Integration","Broken"})
     public void testCanStartAndStop() throws Exception {
         RiakNode entity = app.createAndManageChild(EntitySpec.create(RiakNode.class)
                 .configure(RiakNode.SUGGESTED_VERSION, "2.1.1"));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
index 8dc566b..d29ae5b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
@@ -38,6 +38,68 @@ import org.testng.annotations.Test;
 /**
  * {@link GeoscalingWebClient} unit tests.
  */
+/*
+Exception java.lang.RuntimeException
+
+Message: Failed to log-in to GeoScaling service: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
+Stacktrace:
+
+
+at org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.login(GeoscalingWebClient.java:208)
+at org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClientTest.setUp(GeoscalingWebClientTest.java:64)
+at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+at java.lang.reflect.Method.invoke(Method.java:606)
+at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
+at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
+at org.testng.internal.Invoker.invokeMethod(Invoker.java:653)
+at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+at org.testng.TestRunner.privateRun(TestRunner.java:767)
+at org.testng.TestRunner.run(TestRunner.java:617)
+at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+at org.testng.TestNG.run(TestNG.java:1057)
+at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
+at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
+at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
+at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1991)
+at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1098)
+at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
+at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
+at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
+at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:543)
+at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:409)
+at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177)
+at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:304)
+at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:611)
+at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:446)
+at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:882)
+at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
+at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
+at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
+at org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.sendRequest(GeoscalingWebClient.java:438)
+at org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.login(GeoscalingWebClient.java:205)
+... 31 more
+ */
+@Test(groups="Broken", enabled=false)
 public class GeoscalingWebClientTest {
     
     private final static String GEOSCALING_URL = "https://www.geoscaling.com";

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
index e9bc684..1992134 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
@@ -153,10 +153,49 @@ public class NginxRebindIntegrationTest extends RebindTestFixtureWithApp {
         assertEquals(monitor.getFailures(), 0);
     }
     
+    /*
+        Exception java.lang.NoClassDefFoundError
+        
+        Message: org/apache/brooklyn/test/HttpTestUtils$3
+        Stacktrace:
+        
+        
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:208)
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:204)
+        at org.apache.brooklyn.entity.proxy.nginx.NginxRebindIntegrationTest.testRebindsWithoutLosingServerPool(NginxRebindIntegrationTest.java:178)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
     /**
      * Test can rebind with an active server pool.
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testRebindsWithoutLosingServerPool() throws Exception {
         
         // Set up nginx with a server pool
@@ -221,12 +260,50 @@ public class NginxRebindIntegrationTest extends RebindTestFixtureWithApp {
         assertEquals(monitor.getFailures(), 0);
     }
     
-    
+    /*
+        Exception java.lang.NoClassDefFoundError
+        
+        Message: org/apache/brooklyn/test/HttpTestUtils$3
+        Stacktrace:
+        
+        
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:208)
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:204)
+        at org.apache.brooklyn.entity.proxy.nginx.NginxRebindIntegrationTest.testRebindsWithoutLosingUrlMappings(NginxRebindIntegrationTest.java:254)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
     /**
      * Test can rebind to the with server pool and URL remappings.
      * NOTE: This requires a redirection from localhost1 to 127.0.0.1 in your /etc/hosts file
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testRebindsWithoutLosingUrlMappings() throws Exception {
         
         // Set up nginx with a url-mapping

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
index 517c756..41780d6 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
@@ -112,7 +112,46 @@ public class ControlledDynamicWebAppClusterRebindIntegrationTest {
         return monitor;
     }
     
-    @Test(groups = {"Integration"})
+    /*
+        Exception java.lang.NoClassDefFoundError
+        
+        Message: org/apache/brooklyn/test/HttpTestUtils$3
+        Stacktrace:
+        
+        
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:208)
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:204)
+        at org.apache.brooklyn.entity.webapp.jboss.ControlledDynamicWebAppClusterRebindIntegrationTest.testRebindsToRunningCluster(ControlledDynamicWebAppClusterRebindIntegrationTest.java:127)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
+    @Test(groups = {"Integration","Broken"})
     public void testRebindsToRunningCluster() throws Exception {
         NginxController origNginx = origApp.createAndManageChild(EntitySpec.create(NginxController.class).configure("domain", "localhost"));
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
index 3334480..89a14fa 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
@@ -109,7 +109,46 @@ public class DynamicWebAppClusterRebindIntegrationTest {
         return monitor;
     }
     
-    @Test(groups = "Integration")
+    /*
+        Exception java.lang.NoClassDefFoundError
+        
+        Message: org/apache/brooklyn/test/HttpTestUtils$3
+        Stacktrace:
+        
+        
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:208)
+        at org.apache.brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals(HttpTestUtils.java:204)
+        at org.apache.brooklyn.entity.webapp.jboss.DynamicWebAppClusterRebindIntegrationTest.testRebindsToRunningCluster(DynamicWebAppClusterRebindIntegrationTest.java:122)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
+    @Test(groups = {"Integration","Broken"})
     public void testRebindsToRunningCluster() throws Exception {
         DynamicWebAppCluster origCluster = origApp.createAndManageChild(EntitySpec.create(DynamicWebAppCluster.class)
                 .configure("memberSpec", EntitySpec.create(JBoss7Server.class).configure("war", getTestWar()))

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
index c51acaa..680c553 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
@@ -111,7 +111,8 @@ public class NodeJsWebAppFixtureIntegrationTest {
     /**
      * Checks an entity can start, set SERVICE_UP to true and shutdown again.
      */
-    @Test(groups = "Integration")
+    // Broken on Ubuntu 15.04 Vivid, no packages from ppa:chris-lea/node.js available
+    @Test(groups = {"Integration","Broken"})
     public void testCanStartAndStop() {
         LOG.info("test=canStartAndStop; entity="+entity+"; app="+entity.getApplication());
 
@@ -128,7 +129,8 @@ public class NodeJsWebAppFixtureIntegrationTest {
     /**
      * Checks an entity can start, set SERVICE_UP to true and shutdown again.
      */
-    @Test(groups = "Integration")
+    // Broken on Ubuntu 15.04 Vivid, no packages from ppa:chris-lea/node.js available
+    @Test(groups = {"Integration","Broken"})
     public void testReportsServiceDownWhenKilled() throws Exception {
         LOG.info("test=testReportsServiceDownWithKilled; entity="+entity+"; app="+entity.getApplication());
         
@@ -153,7 +155,8 @@ public class NodeJsWebAppFixtureIntegrationTest {
         // but TODO we should have some rebind tests for these!
     }
 
-    @Test(groups = "Integration")
+    // Broken on Ubuntu 15.04 Vivid, no packages from ppa:chris-lea/node.js available
+    @Test(groups = {"Integration","Broken"})
     public void testInitialNamedDeployments() {
         final String urlSubPathToWebApp = APP_NAME;
         final String urlSubPathToPageToQuery = "";


[14/21] incubator-brooklyn git commit: Disable consistently failing integration tests

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/usage/dist/src/test/java/org/apache/brooklyn/cli/CliIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/dist/src/test/java/org/apache/brooklyn/cli/CliIntegrationTest.java b/usage/dist/src/test/java/org/apache/brooklyn/cli/CliIntegrationTest.java
index ec56d47..adf9559 100644
--- a/usage/dist/src/test/java/org/apache/brooklyn/cli/CliIntegrationTest.java
+++ b/usage/dist/src/test/java/org/apache/brooklyn/cli/CliIntegrationTest.java
@@ -28,7 +28,7 @@ public class CliIntegrationTest extends BaseCliIntegrationTest {
     /**
      * Checks if running {@code brooklyn help} produces the expected output.
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testLaunchCliHelp() throws Throwable {
         final Process brooklyn = startBrooklyn("help");
 
@@ -48,10 +48,55 @@ public class CliIntegrationTest extends BaseCliIntegrationTest {
         testBrooklyn(brooklyn, test, 0);
     }
 
+    /*
+        Exception java.io.IOException
+        
+        Message: Cannot run program "./target/brooklyn-dist/bin/brooklyn": error=2, No such file or directory
+        Stacktrace:
+        
+        
+        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
+        at org.apache.brooklyn.cli.BaseCliIntegrationTest.startBrooklyn(BaseCliIntegrationTest.java:75)
+        at org.apache.brooklyn.cli.CliIntegrationTest.testLaunchCliApp(CliIntegrationTest.java:56)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+        Caused by: java.io.IOException: error=2, No such file or directory
+        at java.lang.UNIXProcess.forkAndExec(Native Method)
+        at java.lang.UNIXProcess.<init>(UNIXProcess.java:186)
+        at java.lang.ProcessImpl.start(ProcessImpl.java:130)
+        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1028)
+        ... 30 more
+     */
     /**
      * Checks if launching an application using {@code brooklyn launch} produces the expected output.
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testLaunchCliApp() throws Throwable {
         final Process brooklyn = startBrooklyn("--verbose", "launch", "--stopOnKeyPress", "--app", "org.apache.brooklyn.cli.BaseCliIntegrationTest$TestApplication", "--location", "localhost", "--noConsole");
 
@@ -72,7 +117,7 @@ public class CliIntegrationTest extends BaseCliIntegrationTest {
     /**
      * Checks if a correct error and help message is given if using incorrect param.
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testLaunchCliAppParamError() throws Throwable {
         final Process brooklyn = startBrooklyn("launch", "nothing", "--app");
 
@@ -88,6 +133,51 @@ public class CliIntegrationTest extends BaseCliIntegrationTest {
         testBrooklyn(brooklyn, test, 1);
     }
 
+    /*
+        Exception java.io.IOException
+        
+        Message: Cannot run program "./target/brooklyn-dist/bin/brooklyn": error=2, No such file or directory
+        Stacktrace:
+        
+        
+        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
+        at org.apache.brooklyn.cli.BaseCliIntegrationTest.startBrooklyn(BaseCliIntegrationTest.java:75)
+        at org.apache.brooklyn.cli.CliIntegrationTest.testLaunchCliAppCommandError(CliIntegrationTest.java:96)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+        Caused by: java.io.IOException: error=2, No such file or directory
+        at java.lang.UNIXProcess.forkAndExec(Native Method)
+        at java.lang.UNIXProcess.<init>(UNIXProcess.java:186)
+        at java.lang.ProcessImpl.start(ProcessImpl.java:130)
+        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1028)
+        ... 30 more
+     */
     /**
      * Checks if a correct error and help message is given if using incorrect command.
      */
@@ -110,7 +200,7 @@ public class CliIntegrationTest extends BaseCliIntegrationTest {
     /**
      * Checks if a correct error and help message is given if using incorrect application.
      */
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testLaunchCliAppLaunchError() throws Throwable {
         final String app = "org.eample.DoesNotExist";
         final Process brooklyn = startBrooklyn("launch", "--app", app, "--location", "nowhere");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
index 312d240..e855841 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
@@ -51,8 +51,49 @@ public class BrooklynPropertiesSecurityFilterTest extends BrooklynRestApiLaunche
 
     private static final Logger LOG = LoggerFactory.getLogger(BrooklynPropertiesSecurityFilterTest.class);
 
+    /*
+        Exception java.lang.AssertionError
+        
+        Message: error creating app. response code=400 expected [true] but found [false]
+        Stacktrace:
+        
+        
+        at org.testng.Assert.fail(Assert.java:94)
+        at org.testng.Assert.failNotEquals(Assert.java:494)
+        at org.testng.Assert.assertTrue(Assert.java:42)
+        at org.apache.brooklyn.rest.BrooklynPropertiesSecurityFilterTest.startAppAtNode(BrooklynPropertiesSecurityFilterTest.java:94)
+        at org.apache.brooklyn.rest.BrooklynPropertiesSecurityFilterTest.testInteractionOfSecurityFilterAndFormMapProvider(BrooklynPropertiesSecurityFilterTest.java:64)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
     // Would be great for this to be a unit test but it takes almost ten seconds.
-    @Test(groups = "Integration")
+    @Test(groups = {"Integration","Broken"})
     public void testInteractionOfSecurityFilterAndFormMapProvider() throws Exception {
         Stopwatch stopwatch = Stopwatch.createStarted();
         try {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35a227f0/utils/common/src/test/java/org/apache/brooklyn/util/maven/MavenArtifactTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/maven/MavenArtifactTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/maven/MavenArtifactTest.java
index bfd8ca0..e1028e1 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/maven/MavenArtifactTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/maven/MavenArtifactTest.java
@@ -127,7 +127,45 @@ public class MavenArtifactTest {
                 "/repository/org/apache/brooklyn"));
     }
 
-    @Test(groups="Integration")
+    /*
+        Exception java.lang.AssertionError
+        
+        Message: Could not load /home/ubuntu/.m2/repository/org/apache/maven/plugins/maven-jar-plugin/2.6/maven-jar-plugin-2.6.jar when testing MavenRetriever: do a maven build with no integration tests first to ensure this is installed, then rerun
+        Stacktrace:
+        
+        
+        at org.testng.Assert.fail(Assert.java:94)
+        at org.apache.brooklyn.util.maven.MavenArtifactTest.testRetrievalLocalIntegration(MavenArtifactTest.java:137)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
+    @Test(groups={"Integration","Broken"})
     public void testRetrievalLocalIntegration() throws Exception {
         MavenArtifact m = MavenArtifact.fromCoordinate(MAVEN_JAR_PLUGIN_COORDINATE);
 
@@ -165,7 +203,45 @@ public class MavenArtifactTest {
         innerUin.close();
     }
 
-    @Test(groups="Integration")
+    /*
+        Exception java.lang.AssertionError
+        
+        Message: Could not load /home/ubuntu/.m2/repository/org/apache/brooklyn/brooklyn-utils-common/0.9.0-SNAPSHOT/brooklyn-utils-common-0.9.0-SNAPSHOT.jar when testing MavenRetriever: do a maven build with no integration tests first to ensure this is installed, then rerun
+        Stacktrace:
+        
+        
+        at org.testng.Assert.fail(Assert.java:94)
+        at org.apache.brooklyn.util.maven.MavenArtifactTest.testRetrievalHostedSnapshotIntegration(MavenArtifactTest.java:176)
+        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+        at java.lang.reflect.Method.invoke(Method.java:606)
+        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
+        at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
+        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
+        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
+        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
+        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
+        at org.testng.TestRunner.privateRun(TestRunner.java:767)
+        at org.testng.TestRunner.run(TestRunner.java:617)
+        at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
+        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
+        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
+        at org.testng.SuiteRunner.run(SuiteRunner.java:254)
+        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
+        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
+        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
+        at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
+        at org.testng.TestNG.run(TestNG.java:1057)
+        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:115)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:205)
+        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:108)
+        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:111)
+        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
+        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
+        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
+     */
+    @Test(groups={"Integration","Broken"})
     public void testRetrievalHostedSnapshotIntegration() throws Exception {
         MavenArtifact m = MavenArtifact.fromCoordinate(
                 "org.apache.brooklyn:brooklyn-utils-common:jar:0.9.0-SNAPSHOT");  // BROOKLYN_VERSION


[04/21] incubator-brooklyn git commit: Parameters test coverage

Posted by he...@apache.org.
Parameters test coverage


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

Branch: refs/heads/master
Commit: 9b985431e82bef78c09710093f0518f80121495c
Parents: 3965638
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Nov 3 17:31:49 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Nov 5 15:23:38 2015 +0200

----------------------------------------------------------------------
 .../objs/BasicSpecParameterFromClassTest.java   |  29 +-
 .../camp/brooklyn/AbstractYamlTest.java         |   7 +-
 .../brooklyn/catalog/CatalogParametersTest.java | 318 +++++++++++++++++++
 3 files changed, 351 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b985431/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
index 2009c98..b0f71a0 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
@@ -24,15 +24,27 @@ import java.util.List;
 
 import org.apache.brooklyn.api.catalog.CatalogConfig;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Predicate;
 import com.google.common.reflect.TypeToken;
 
 public class BasicSpecParameterFromClassTest {
+    private ManagementContext mgmt;
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        mgmt = LocalManagementContextForTests.newInstance();
+    }
+
     public interface SpecParameterTestEntity extends Entity {
         @CatalogConfig(label="String Key", priority=3)
         ConfigKey<String> STRING_KEY = ConfigKeys.newStringConfigKey("string_key");
@@ -47,15 +59,30 @@ public class BasicSpecParameterFromClassTest {
         ConfigKey<String> UNPINNNED_KEY = ConfigKeys.newStringConfigKey("unpinned_key");
     }
 
+    @ImplementedBy(ConfigInImplParameterTestEntityImpl.class)
+    public static interface ConfigInImplParameterTestEntity extends Entity {}
+    public static class ConfigInImplParameterTestEntityImpl extends AbstractEntity implements ConfigInImplParameterTestEntity {
+        public static final ConfigKey<String> SUGGESTED_VERSION = BrooklynConfigKeys.SUGGESTED_VERSION;
+    }
+
     @Test
     public void testFullDefinition() {
-        List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(SpecParameterTestEntity.class);
+        List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(mgmt, SpecParameterTestEntity.class);
+        assertEquals(inputs.size(), 4);
         assertInput(inputs.get(0), "Predicate Key", true, SpecParameterTestEntity.PREDICATE_KEY);
         assertInput(inputs.get(1), "Integer Key", true, SpecParameterTestEntity.INTEGER_KEY);
         assertInput(inputs.get(2), "String Key", true, SpecParameterTestEntity.STRING_KEY);
         assertInput(inputs.get(3), "unpinned_key", false, SpecParameterTestEntity.UNPINNNED_KEY);
     }
 
+    @Test
+    public void testConfigInImplVisible() {
+        List<SpecParameter<?>> inputs = BasicSpecParameter.fromClass(mgmt, ConfigInImplParameterTestEntity.class);
+        assertEquals(inputs.size(), 1);
+        ConfigKey<String> key = ConfigInImplParameterTestEntityImpl.SUGGESTED_VERSION;
+        assertInput(inputs.get(0), key.getName(), false, key);
+    }
+
     private void assertInput(SpecParameter<?> input, String label, boolean pinned, ConfigKey<?> type) {
         assertEquals(input.getLabel(), label);
         assertEquals(input.isPinned(), pinned);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b985431/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
index 8a858cf..a45d272 100644
--- 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
@@ -22,6 +22,7 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.util.Set;
 
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
@@ -52,6 +53,7 @@ public abstract class AbstractYamlTest {
     protected static final String TEST_VERSION = "0.1.2";
 
     private ManagementContext brooklynMgmt;
+    protected BrooklynCatalog catalog;
     protected BrooklynCampPlatform platform;
     protected BrooklynCampPlatformLauncherNoServer launcher;
     private boolean forceUpdate;
@@ -73,6 +75,7 @@ public abstract class AbstractYamlTest {
         };
         launcher.launch();
         brooklynMgmt = launcher.getBrooklynMgmt();
+        catalog = brooklynMgmt.getCatalog();
         platform = launcher.getCampPlatform();
     }
 
@@ -168,11 +171,11 @@ public abstract class AbstractYamlTest {
         return LOG;
     }
 
-    private String joinLines(Iterable<String> catalogYaml) {
+    protected String joinLines(Iterable<String> catalogYaml) {
         return Joiner.on("\n").join(catalogYaml);
     }
 
-    private String joinLines(String[] catalogYaml) {
+    protected String joinLines(String... catalogYaml) {
         return Joiner.on("\n").join(catalogYaml);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b985431/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java
new file mode 100644
index 0000000..6407d4a
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogParametersTest.java
@@ -0,0 +1,318 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.location.AbstractLocation;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.core.objs.BasicSpecParameter;
+import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.testng.SkipException;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class CatalogParametersTest extends AbstractYamlTest {
+    private static final String SYMBOLIC_NAME = "my.catalog.app.id.load";
+
+    private static final ConfigKey<String> SHARED_CONFIG = ConfigKeys.newStringConfigKey("sample.config");
+    public static class ConfigEntityForTest extends AbstractEntity {
+        public static final ConfigKey<String> SAMPLE_CONFIG = SHARED_CONFIG;
+    }
+    public static class ConfigPolicyForTest extends AbstractPolicy {
+        public static final ConfigKey<String> SAMPLE_CONFIG = SHARED_CONFIG;
+    }
+    public static class ConfigLocationForTest extends AbstractLocation {
+        private static final long serialVersionUID = 1L;
+        public static final ConfigKey<String> SAMPLE_CONFIG = SHARED_CONFIG;
+    }
+
+    @DataProvider(name="brooklynTypes")
+    public Object[][] brooklynTypes() {
+        return new Object[][] {
+            {ConfigEntityForTest.class},
+            {ConfigPolicyForTest.class},
+            {ConfigLocationForTest.class}};
+    }
+    
+    @DataProvider(name="catalogTemplates")
+    public Object[][] catalogTemplates() {
+        return new Object[][] {
+            {joinLines(
+                    "brooklyn.catalog:",
+                    "  id: " + SYMBOLIC_NAME,
+                    "  version: " + TEST_VERSION,
+                    "  item:",
+                    "    type: ${testClass}",
+                    "    brooklyn.parameters:",
+                    "    - simple")},
+            {joinLines(
+                    "brooklyn.catalog:",
+                    "  id: " + SYMBOLIC_NAME,
+                    "  version: " + TEST_VERSION,
+                    "  brooklyn.parameters:",
+                    "  - simple",
+                    "  item:",
+                    "    type: ${testClass}")}
+        };
+    }
+    
+    @DataProvider(name="typesAndTemplates")
+    public Object[][] typesAndTemplates() {
+        // cartesian product of brooklynTypes X catalogTemplates
+        Object[][] brooklynTypes = brooklynTypes();
+        Object[][] catalogTemplates = catalogTemplates();
+        Object[][] arr = new Object[brooklynTypes.length * catalogTemplates.length][];
+        for (int i = 0; i < catalogTemplates.length; i++) {
+            for (int j = 0; j < brooklynTypes.length; j++) {
+                Object[] item = new Object[2];
+                item[0] = brooklynTypes[j][0];
+                item[1] = catalogTemplates[i][0];
+                arr[i*brooklynTypes.length + j] = item;
+            }
+        }
+        return arr;
+    }
+
+    @Test(dataProvider = "typesAndTemplates")
+    public void testParameters(Class<? extends BrooklynObject> testClass, String template) {
+        addCatalogItems(template.replace("${testClass}", testClass.getName()));
+
+        ConfigKey<String> SIMPLE_CONFIG = ConfigKeys.newStringConfigKey("simple");
+        SpecParameter<String> SIMPLE_PARAM = new BasicSpecParameter<>("simple", true, SIMPLE_CONFIG);
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        assertEquals(item.getParameters(), ImmutableList.of(SIMPLE_PARAM));
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        AbstractBrooklynObjectSpec<?,?> spec = catalog.createSpec((CatalogItem)item);
+        assertEquals(ImmutableSet.copyOf(spec.getParameters()), ImmutableList.of(SIMPLE_PARAM));
+    }
+
+    @Test(dataProvider = "brooklynTypes")
+    public void testDefaultParameters(Class<? extends BrooklynObject> testClass) {
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + SYMBOLIC_NAME,
+            "  version: " + TEST_VERSION,
+            "  item:",
+            "    type: "+ testClass.getName());
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        assertEquals(ImmutableSet.copyOf(item.getParameters()), ImmutableSet.copyOf(BasicSpecParameter.fromClass(mgmt(), testClass)));
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        AbstractBrooklynObjectSpec<?,?> spec = (AbstractBrooklynObjectSpec<?,?>) catalog.createSpec((CatalogItem)item);
+        assertEquals(ImmutableSet.copyOf(spec.getParameters()), ImmutableSet.copyOf(BasicSpecParameter.fromClass(mgmt(),testClass)));
+    }
+
+
+    @Test
+    public void testRootParametersUnwrapped() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + SYMBOLIC_NAME,
+                "  version: " + TEST_VERSION,
+                "  item:",
+                "    services:",
+                "    - type: " + ConfigEntityForTest.class.getName(),
+                "    brooklyn.parameters:",
+                "    - simple");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 1);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+    }
+
+    @Test
+    public void testExplicitParametersInMetaOverride() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + SYMBOLIC_NAME,
+                "  version: " + TEST_VERSION,
+                "  brooklyn.parameters:",
+                "    - metaSimple",
+                "  item:",
+                "    type: " + ConfigEntityForTest.class.getName(),
+                "    brooklyn.parameters:",
+                "    - simple");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 1);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "metaSimple");
+    }
+
+    @Test(dataProvider="brooklynTypes")
+    public void testDepentantCatalogsInheritParameters(Class<? extends BrooklynObject> type) {
+        if (type == ConfigLocationForTest.class) {
+            //TODO
+            throw new SkipException("Locations don't inherit parameters, should migrate to the type registry first");
+        }
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: paramItem",
+                "    item:",
+                "      type: " + type.getName(),
+                "      brooklyn.parameters:",
+                "      - simple",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: paramItem:" + TEST_VERSION);
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 1);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+    }
+
+    @Test(dataProvider="brooklynTypes")
+    public void testDepentantCatalogsOverrideParameters(Class<? extends BrooklynObject> type) {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: paramItem",
+                "    item:",
+                "      type: " + type.getName(),
+                "      brooklyn.parameters:",
+                "      - simple",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: paramItem:" + TEST_VERSION,
+                "      brooklyn.parameters:",
+                "      - override");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        List<SpecParameter<?>> inputs = item.getParameters();
+        assertEquals(inputs.size(), 1);
+        SpecParameter<?> firstInput = inputs.get(0);
+        assertEquals(firstInput.getLabel(), "override");
+    }
+
+    @Test
+    public void testChildEntitiyHasParameters() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + SYMBOLIC_NAME,
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - item:",
+                "      type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.children:",
+                "      - type: " + ConfigEntityForTest.class.getName(),
+                "        brooklyn.parameters:",
+                "        - simple");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        @SuppressWarnings({ "rawtypes", "unchecked"})
+        EntitySpec<?> parentSpec = (EntitySpec<?>) catalog.createSpec((CatalogItem)item);
+        EntitySpec<?> spec = parentSpec.getChildren().get(0);
+        SpecParameter<?> firstInput = spec.getParameters().get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+    }
+
+    @Test
+    public void testAppSpecInheritsCatalogParameters() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: " + BasicApplication.class.getName(),
+                "      brooklyn.parameters:",
+                "      - simple");
+
+        EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpecForApplication(mgmt(), joinLines(
+                "services:",
+                "- type: " + ver(SYMBOLIC_NAME)));
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        SpecParameter<?> firstInput = params.get(0);
+        assertEquals(firstInput.getLabel(), "simple");
+    }
+
+    @Test
+    public void testParametersCoercedOnSetAndReferences() throws Exception {
+        Integer testValue = Integer.valueOf(55);
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: " + SYMBOLIC_NAME,
+                "  version: " + TEST_VERSION,
+                "  brooklyn.parameters:",
+                "  - name: num",
+                "    type: integer",
+                "  item:",
+                "    type: " + BasicApplication.class.getName(),
+                "    brooklyn.children:",
+                "    - type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.config:",
+                "        refConfig: $brooklyn:scopeRoot().config(\"num\")",
+                "    - type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.config:",
+                "        refConfig: $brooklyn:config(\"num\")"); //inherited config
+
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.children:",
+                "  - type: " + ver(SYMBOLIC_NAME),
+                "    brooklyn.config:",
+                "      num: \"" + testValue + "\"");
+
+        Entity scopeRoot = Iterables.getOnlyElement(app.getChildren());
+
+        ConfigKey<Object> numKey = ConfigKeys.newConfigKey(Object.class, "num");
+        assertEquals(scopeRoot.config().get(numKey), testValue);
+
+        ConfigKey<Object> refConfigKey = ConfigKeys.newConfigKey(Object.class, "refConfig");
+
+        Iterator<Entity> childIter = scopeRoot.getChildren().iterator();
+        Entity c1 = childIter.next();
+        assertEquals(c1.config().get(refConfigKey), testValue);
+        Entity c2 = childIter.next();
+        assertEquals(c2.config().get(refConfigKey), testValue);
+        assertFalse(childIter.hasNext());
+    }
+
+}