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:17 UTC

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

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);
     }