You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2016/07/28 17:25:27 UTC

[2/3] brooklyn-server git commit: Merge brooklyn.parameters in YAML files

Merge brooklyn.parameters in YAML files


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

Branch: refs/heads/master
Commit: a04bf4d9428eaef2ab047057752bad1502a8e8fa
Parents: 4a65aed
Author: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Authored: Sun Jul 3 01:24:38 2016 +0100
Committer: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Committed: Wed Jul 27 16:09:54 2016 +0100

----------------------------------------------------------------------
 .../internal/AbstractBrooklynObjectSpec.java    |  43 ++--
 .../BrooklynEntityDecorationResolver.java       |  20 +-
 .../spi/creation/CampInternalUtils.java         |  19 +-
 .../TestSensorAndEffectorInitializer.java       |  10 +-
 .../catalog/SpecParameterUnwrappingTest.java    | 249 ++++++++++++++++---
 .../brooklyn/core/objs/BasicSpecParameter.java  |  38 ++-
 .../core/objs/SpecParameterPredicates.java      | 110 ++++++++
 7 files changed, 392 insertions(+), 97 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/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 e7bf04d..51eacee 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
@@ -27,26 +27,27 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.api.mgmt.EntityManager;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.objs.BrooklynObject;
-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.collections.MutableSet;
-import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 
-/** Defines a spec for creating a {@link BrooklynObject}.
+import org.apache.brooklyn.api.mgmt.EntityManager;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+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.collections.MutableSet;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+
+/**
+ * Defines a spec for creating a {@link BrooklynObject}.
  * <p>
  * In addition to the contract defined by the code,
  * subclasses should provide a public static <code>create(Class)</code>
@@ -54,7 +55,8 @@ import com.google.common.collect.Maps;
  * <p>
  * The spec is then passed to type-specific methods,
  * e.g. {@link EntityManager#createEntity(org.apache.brooklyn.api.entity.EntitySpec)}
- * to create a managed instance of the target type. */
+ * to create a managed instance of the target type.
+ */
 public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrooklynObjectSpec<T,SpecT>> implements Serializable {
 
     private static final long serialVersionUID = 3010955277740333030L;
@@ -134,7 +136,7 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
         Iterables.addAll(this.tags, tagsToReplace);
         return self();
     }
-    
+
     // TODO which semantics are correct? replace has been the behaviour;
     // add breaks tests and adds unwanted parameters,
     // but replacing will cause some desired parameters to be lost.
@@ -153,17 +155,16 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
     @Beta
     public SpecT parametersAdd(List<? extends SpecParameter<?>> parameters) {
         // parameters follows immutable pattern, unlike the other fields
-        Builder<SpecParameter<?>> result = ImmutableList.<SpecParameter<?>>builder();
-        if (this.parameters!=null)
-            result.addAll(this.parameters);
-        result.addAll( checkNotNull(parameters, "parameters") );
-        this.parameters = result.build();
+        Set<SpecParameter<?>> params = MutableSet.<SpecParameter<?>>copyOf(this.parameters);
+        params.removeAll(parameters);
+        params.addAll(parameters);
+        this.parameters = ImmutableList.copyOf(params);
         return self();
     }
     /** replaces parameters with the given */
     @Beta
     public SpecT parametersReplace(List<? extends SpecParameter<?>> parameters) {
-        this.parameters = ImmutableList.copyOf( checkNotNull(parameters, "parameters") );
+        this.parameters = ImmutableList.copyOf(checkNotNull(parameters, "parameters"));
         return self();
     }
 
@@ -302,12 +303,12 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
     }
 
     public <V> SpecT removeConfig(ConfigKey<V> key) {
-        config.remove( checkNotNull(key, "key") );
+        config.remove(checkNotNull(key, "key"));
         return self();
     }
 
     public <V> SpecT removeFlag(String key) {
-        flags.remove( checkNotNull(key, "key") );
+        flags.remove(checkNotNull(key, "key"));
         return self();
     }
 
@@ -323,7 +324,7 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
     public Map<String, ?> getFlags() {
         return Collections.unmodifiableMap(flags);
     }
-    
+
     /**
      * @return Read-only configuration values
      */

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
index 4913cb1..fd2a69b 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityDecorationResolver.java
@@ -21,6 +21,9 @@ package org.apache.brooklyn.camp.brooklyn.spi.creation;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
@@ -39,9 +42,6 @@ import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.guava.Maybe;
 
-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.
  * @since 0.7.0
@@ -181,20 +181,14 @@ public abstract class BrooklynEntityDecorationResolver<DT> {
     public static class SpecParameterResolver extends BrooklynEntityDecorationResolver<SpecParameter<?>> {
 
         protected SpecParameterResolver(BrooklynYamlTypeInstantiator.Factory instantiator) { super(instantiator); }
-        @Override protected String getDecorationKind() { return "Spec Parameter initializer"; }
+
+        @Override
+        protected String getDecorationKind() { return "Spec Parameter initializer"; }
 
         @Override
         public void decorate(EntitySpec<?> entitySpec, ConfigBag attrs) {
             List<? extends SpecParameter<?>> explicitParams = buildListOfTheseDecorationsFromEntityAttributes(attrs);
-            // TODO see discussion at EntitySpec.parameters; 
-            // maybe we should instead inherit always, or 
-            // inherit except where it is set as config and then add the new explicit ones
-            if (!explicitParams.isEmpty()) {
-                entitySpec.parameters(explicitParams);
-            }
-            if (entitySpec.getParameters().isEmpty()) {
-                entitySpec.parameters(BasicSpecParameter.fromSpec(instantiator.loader.getManagementContext(), entitySpec));
-            }
+            BasicSpecParameter.addParameters(entitySpec, explicitParams, instantiator.loader);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
index 8c9bf63..b2ec074 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
@@ -26,6 +26,11 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
@@ -56,17 +61,11 @@ 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;
-
 /** package-private; as {@link RegisteredType} becomes standard hopefully we can remove this */
 class CampInternalUtils {
 
     static EntitySpec<? extends Application> createWrapperApp(AssemblyTemplate template, BrooklynClassLoadingContext loader) {
-        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(
-            loader, buildWrapperAppTemplate(template));
+        BrooklynComponentTemplateResolver resolver = BrooklynComponentTemplateResolver.Factory.newInstance(loader, buildWrapperAppTemplate(template));
         EntitySpec<Application> wrapperSpec = resolver.resolveSpec(ImmutableSet.<String>of());
         resetSpecIfTemplateHasNoExplicitParameters(template, wrapperSpec);
         // caller always sets WRAPPER_APP config; should we do it here?
@@ -171,7 +170,7 @@ class CampInternalUtils {
         }
 
         String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type");
-        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
+        Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_CONFIG);
         if (brooklynConfig==null) brooklynConfig = MutableMap.of();
         LocationSpec<?> locationSpec = resolveLocationSpec(type, brooklynConfig, loader);
         List<?> explicitParams = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
@@ -181,9 +180,9 @@ class CampInternalUtils {
 
     private static void initParameters(List<?> explicitParams, AbstractBrooklynObjectSpec<?, ?> spec, BrooklynClassLoadingContext loader) {
         if (explicitParams != null) {
-            spec.parameters(BasicSpecParameter.fromConfigList(explicitParams, loader));
+            BasicSpecParameter.addParameters(spec, BasicSpecParameter.fromConfigList(explicitParams, loader), loader);
         } else {
-            spec.parameters(BasicSpecParameter.fromSpec(loader.getManagementContext(), spec));
+            BasicSpecParameter.addParameters(spec, ImmutableList.<SpecParameter<?>>of(), loader);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
index 72c427f..36422c9 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
@@ -20,6 +20,10 @@ package org.apache.brooklyn.camp.brooklyn;
 
 import java.util.Map;
 
+import org.testng.Assert;
+
+import com.google.common.base.Preconditions;
+
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
@@ -28,9 +32,7 @@ import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.testng.Assert;
-
-import com.google.common.base.Preconditions;
+import org.apache.brooklyn.util.text.Strings;
 
 public class TestSensorAndEffectorInitializer implements EntityInitializer {
 
@@ -47,7 +49,7 @@ public class TestSensorAndEffectorInitializer implements EntityInitializer {
                 @Override
                 public String call(ConfigBag parameters) {
                     Object name = parameters.getStringKey("name");
-                    entity().sensors().set(Sensors.newStringSensor(SENSOR_LAST_HELLO), ""+name);
+                    entity().sensors().set(Sensors.newStringSensor(SENSOR_LAST_HELLO), Strings.toString(name));
                     return helloWord()+" "+name;
                 }
             }).build();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterUnwrappingTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterUnwrappingTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterUnwrappingTest.java
index d563395..77db2d5 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterUnwrappingTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterUnwrappingTest.java
@@ -18,13 +18,23 @@
  */
 package org.apache.brooklyn.camp.brooklyn.catalog;
 
+import static org.apache.brooklyn.core.objs.SpecParameterPredicates.labelEqualTo;
+import static org.apache.brooklyn.core.objs.SpecParameterPredicates.nameEqualTo;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
+import static org.testng.Assert.assertTrue;
 
 import java.util.Iterator;
 import java.util.List;
 
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
@@ -37,8 +47,10 @@ import org.apache.brooklyn.api.policy.Policy;
 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.config.ConfigPredicates;
 import org.apache.brooklyn.core.entity.AbstractApplication;
 import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.EntityPredicates;
 import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -46,13 +58,7 @@ import org.apache.brooklyn.core.objs.BasicSpecParameter;
 import org.apache.brooklyn.core.policy.AbstractPolicy;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 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;
+import org.apache.brooklyn.entity.stock.BasicStartable;
 
 public class SpecParameterUnwrappingTest extends AbstractYamlTest {
     private static final String SYMBOLIC_NAME = "my.catalog.app.id.load";
@@ -134,18 +140,13 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
 
         CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
         AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
-        List<SpecParameter<?>> inputs = spec.getParameters();
-        assertEquals(inputs.size(), 1);
-        SpecParameter<?> firstInput = inputs.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
     }
 
     @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");
-        }
+    public void testDependantCatalogsInheritParameters(Class<? extends BrooklynObject> type) {
         addCatalogItems(
                 "brooklyn.catalog:",
                 "  version: " + TEST_VERSION,
@@ -158,18 +159,18 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
                 "      - simple",
                 "  - id: " + SYMBOLIC_NAME,
                 "    item:",
-                "      type: paramItem:" + TEST_VERSION);
+                "      type: paramItem");
 
         CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
         AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
-        List<SpecParameter<?>> inputs = spec.getParameters();
-        assertEquals(inputs.size(), 1);
-        SpecParameter<?> firstInput = inputs.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("simple")).isPresent());
     }
 
     @Test(dataProvider="brooklynTypes")
-    public void testDepentantCatalogsOverrideParameters(Class<? extends BrooklynObject> type) {
+    public void testDependantCatalogsExtendsParameters(Class<? extends BrooklynObject> type) {
         addCatalogItems(
                 "brooklyn.catalog:",
                 "  version: " + TEST_VERSION,
@@ -182,17 +183,128 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
                 "      - simple",
                 "  - id: " + SYMBOLIC_NAME,
                 "    item:",
-                // Don't set explicit version, not supported by locations
                 "      type: paramItem",
                 "      brooklyn.parameters:",
                 "      - override");
 
         CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
         AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
-        List<SpecParameter<?>> inputs = spec.getParameters();
-        assertEquals(inputs.size(), 1);
-        SpecParameter<?> firstInput = inputs.get(0);
-        assertEquals(firstInput.getLabel(), "override");
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 2);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, nameEqualTo("override")).isPresent());
+    }
+
+    @Test(dataProvider="brooklynTypes")
+    public void testDependantCatalogMergesParameters(Class<? extends BrooklynObject> type) {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: paramItem",
+                "    item:",
+                "      type: " + type.getName(),
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        label: simple",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: paramItem",
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        label: override");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("override")).isPresent());
+    }
+
+    @Test
+    public void testDependantCatalogConfigOverridesParameters() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: paramItem",
+                "    item:",
+                "      type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        default: biscuits",
+                "      brooklyn.config:",
+                "        simple: value",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: paramItem",
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        default: rabbits");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        Optional<ConfigKey<?>> config = Iterables.tryFind(spec.getConfig().keySet(), ConfigPredicates.nameEqualTo("simple"));
+        assertTrue(config.isPresent());
+        Object value = spec.getConfig().get(config.get());
+        assertEquals(value, "value");
+    }
+
+    @Test
+    public void testCatalogConfigOverridesParameters() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        default: biscuits",
+                "      brooklyn.config:",
+                "        simple: value");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        Optional<ConfigKey<?>> config = Iterables.tryFind(spec.getConfig().keySet(), ConfigPredicates.nameEqualTo("simple"));
+        assertTrue(config.isPresent());
+        Object value = spec.getConfig().get(config.get());
+        assertEquals(value, "value");
+    }
+
+    @Test
+    public void testDependantCatalogConfigReplacesParameters() {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "  - id: paramItem",
+                "    item:",
+                "      type: " + ConfigEntityForTest.class.getName(),
+                "      brooklyn.config:",
+                "        simple: value",
+                "  - id: " + SYMBOLIC_NAME,
+                "    item:",
+                "      type: paramItem",
+                "      brooklyn.parameters:",
+                "      - name: simple",
+                "        default: rabbits");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(SYMBOLIC_NAME, TEST_VERSION);
+        AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        Optional<ConfigKey<?>> config = Iterables.tryFind(spec.getConfig().keySet(), ConfigPredicates.nameEqualTo("simple"));
+        assertTrue(config.isPresent());
+        Object value = spec.getConfig().get(config.get());
+        assertEquals(value, "value");
     }
 
     @Test
@@ -213,8 +325,10 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
         @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");
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("simple")).isPresent());
     }
 
     @Test
@@ -234,8 +348,8 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
                 "- type: " + ver(SYMBOLIC_NAME));
         List<SpecParameter<?>> params = spec.getParameters();
         assertEquals(params.size(), 1);
-        SpecParameter<?> firstInput = params.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("simple")).isPresent());
     }
 
 
@@ -256,8 +370,8 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
                 "- type: " + ver(SYMBOLIC_NAME));
         List<SpecParameter<?>> params = spec.getParameters();
         assertEquals(params.size(), 1);
-        SpecParameter<?> firstInput = params.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("simple")).isPresent());
     }
 
     @Test
@@ -278,8 +392,8 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
                 "- type: " + ver(SYMBOLIC_NAME));
         List<SpecParameter<?>> params = spec.getParameters();
         assertEquals(params.size(), 1);
-        SpecParameter<?> firstInput = params.get(0);
-        assertEquals(firstInput.getLabel(), "simple");
+        assertTrue(Iterables.tryFind(params, nameEqualTo("simple")).isPresent());
+        assertTrue(Iterables.tryFind(params, labelEqualTo("simple")).isPresent());
     }
 
     @Test
@@ -352,6 +466,69 @@ public class SpecParameterUnwrappingTest extends AbstractYamlTest {
         assertFalse(childIter.hasNext());
     }
 
+    private static final ConfigKey<Integer> NUM = ConfigKeys.newIntegerConfigKey("num");
+
+    @Test
+    public void testParameterDefaultsUsedInConfig() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  version: " + TEST_VERSION,
+                "  items:",
+                "    - id: " + ConfigEntityForTest.class.getSimpleName() + "WithParams",
+                "      itemType: entity",
+                "      item:",
+                "        type: " + ConfigEntityForTest.class.getName(),
+                "        brooklyn.parameters:",
+                "          - name: num",
+                "            type: integer",
+                "            default: 1234",
+                "        brooklyn.children:",
+                "          - type: " + BasicStartable.class.getName(),
+                "            name: s",
+                "            brooklyn.config:",
+                "              test: $brooklyn:parent().config(\"num\")",
+                "    - id: " + SYMBOLIC_NAME,
+                "      itemType: entity",
+                "      item:",
+                "        type: " + BasicApplication.class.getName(),
+                "        brooklyn.children:",
+                "          - type: " + ConfigEntityForTest.class.getSimpleName() + "WithParams",
+                "            name: a",
+                "          - type: " + ConfigEntityForTest.class.getSimpleName() + "WithParams",
+                "            name: b",
+                "            brooklyn.config:",
+                "              num: 5678",
+                "          - type: " + ConfigEntityForTest.class.getSimpleName() + "WithParams",
+                "            name: c",
+                "            brooklyn.config:",
+                "              test: $brooklyn:config(\"num\")");
+
+        CatalogItem<?, ?> item = catalog.getCatalogItem(ConfigEntityForTest.class.getSimpleName() + "WithParams", TEST_VERSION);
+        AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
+        List<SpecParameter<?>> params = spec.getParameters();
+        assertEquals(params.size(), 1);
+        assertTrue(Iterables.tryFind(params, nameEqualTo("num")).isPresent());
+
+        Application app = (Application) createAndStartApplication(
+                "services:",
+                "  - type: " + ver(SYMBOLIC_NAME));
+
+        Optional<Entity> s = Iterables.tryFind(mgmt().getEntityManager().getEntitiesInApplication(app), EntityPredicates.displayNameEqualTo("s"));
+        assertTrue(s.isPresent());
+        assertEquals(s.get().config().get(ConfigKeys.newIntegerConfigKey("test")).intValue(), 1234);
+
+        Iterable<Entity> children = app.getChildren();
+        Optional<Entity> a = Iterables.tryFind(children, EntityPredicates.displayNameEqualTo("a"));
+        assertTrue(a.isPresent());
+        assertEquals(a.get().config().get(NUM).intValue(), 1234);
+        Optional<Entity> b = Iterables.tryFind(children, EntityPredicates.displayNameEqualTo("b"));
+        assertTrue(b.isPresent());
+        assertEquals(b.get().config().get(NUM).intValue(), 5678);
+        Optional<Entity> c = Iterables.tryFind(children, EntityPredicates.displayNameEqualTo("c"));
+        assertTrue(c.isPresent());
+        assertEquals(c.get().config().get(ConfigKeys.newIntegerConfigKey("test")).intValue(), 1234);
+    }
+
     @Test
     public void testAppRootParameters() throws Exception {
         EntitySpec<? extends Application> spec = createAppSpec(

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/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 d89c8cb..3ec9469 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
@@ -26,6 +26,16 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.annotations.Beta;
+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;
+
 import org.apache.brooklyn.api.catalog.CatalogConfig;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
@@ -48,16 +58,6 @@ import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.StringPredicates;
 import org.apache.brooklyn.util.time.Duration;
 
-import com.google.common.annotations.Beta;
-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;
 
@@ -130,9 +130,7 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
         if (getClass() != obj.getClass())
             return false;
         BasicSpecParameter<?> other = (BasicSpecParameter<?>) obj;
-        return Objects.equal(label,  other.label) &&
-                pinned == other.pinned &&
-                Objects.equal(configKey, other.configKey);
+        return Objects.equal(configKey, other.configKey);
     }
 
     @Override
@@ -384,5 +382,19 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
         }
     }
 
+    /**
+     * Adds the given list of {@link SpecParameter parameters} to the provided
+     * {@link AbstractBrooklynObjectSpec spec} or generates a list from the
+     * spec if the provided list is empty.
+     *
+     * @see EntitySpec#parameters(List)
+     */
+    public static void addParameters(AbstractBrooklynObjectSpec<?, ?> spec, List<? extends SpecParameter<?>> explicitParams, BrooklynClassLoadingContext loader) {
+        if (explicitParams.size() > 0) {
+            spec.parametersAdd(explicitParams);
+        } else {
+            spec.parametersAdd(BasicSpecParameter.fromSpec(loader.getManagementContext(), spec));
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a04bf4d9/core/src/main/java/org/apache/brooklyn/core/objs/SpecParameterPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/SpecParameterPredicates.java b/core/src/main/java/org/apache/brooklyn/core/objs/SpecParameterPredicates.java
new file mode 100644
index 0000000..1eb934c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/SpecParameterPredicates.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.google.common.base.Predicate;
+
+import org.apache.brooklyn.api.objs.SpecParameter;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.util.text.Strings;
+
+public class SpecParameterPredicates {
+
+    /**
+     * Returns true if the {@link SpecParameter parameter name} is the same as
+     * that on the specified paramater.
+     */
+    public static Predicate<SpecParameter<?>> sameName(final SpecParameter<?> param) {
+        return new SameName(param);
+    }
+
+    /** @see #sameName(SpecParameter) */
+    protected static class SameName implements Predicate<SpecParameter<?>> {
+        private final SpecParameter<?> param;
+
+        public SameName(SpecParameter<?> param) {
+            this.param = param;
+        }
+
+        @Override
+        public boolean apply(SpecParameter<?> input) {
+            return input.getConfigKey().getName().equals(param.getConfigKey().getName());
+        }
+
+        @Override
+        public String toString() {
+            return String.format("sameName(%s)",Strings.toString(param));
+        }
+    }
+
+    /**
+     * Returns true if the {@link SpecParameter#getLabel() label} is the same as
+     * the specified string.
+     */
+    public static Predicate<SpecParameter<?>> labelEqualTo(final String label) {
+        return new LabelEqualTo(label);
+    }
+
+    /** @see #labelEqualTo(String) */
+    protected static class LabelEqualTo implements Predicate<SpecParameter<?>> {
+        private final String label;
+
+        public LabelEqualTo(String label) {
+            this.label = label;
+        }
+
+        @Override
+        public boolean apply(SpecParameter<?> input) {
+            return input.getLabel().equals(label);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("labelEqualTo(%s)",Strings.toString(label));
+        }
+    }
+
+    /**
+     * Returns true if the {@link ConfigKey#getName() config key name} is the same
+     * as the specified string.
+     */
+    public static Predicate<SpecParameter<?>> nameEqualTo(final String name) {
+        return new NameEqualTo(name);
+    }
+
+    /** @see #nameEqualTo(String) */
+    protected static class NameEqualTo implements Predicate<SpecParameter<?>> {
+        private final String name;
+
+        public NameEqualTo(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public boolean apply(SpecParameter<?> input) {
+            return input.getConfigKey().getName().equals(name);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("nameEqualTo(%s)",Strings.toString(name));
+        }
+    }
+
+}