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 2017/10/03 14:23:59 UTC

[22/35] brooklyn-server git commit: Merge branch 'master' into adjunct-rest-2

Merge branch 'master' into adjunct-rest-2

Big changes to config key construction, following on from previous deprecation


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

Branch: refs/heads/master
Commit: 62bcbc5f4b7695420b026952ce6ae7f180dcaec6
Parents: 45261c7 df83d44
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Sep 25 11:29:45 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Sep 25 11:29:45 2017 +0100

----------------------------------------------------------------------
 api/pom.xml                                     |    2 +-
 .../brooklyn/api/catalog/BrooklynCatalog.java   |    4 +
 .../brooklyn/api/typereg/RegisteredType.java    |    5 +-
 camp/camp-base/pom.xml                          |    2 +-
 camp/camp-brooklyn/pom.xml                      |    2 +-
 .../camp/brooklyn/AbstractYamlTest.java         |   31 +-
 .../brooklyn/EmptySoftwareProcessYamlTest.java  |   94 +-
 .../camp/brooklyn/FunctionSensorYamlTest.java   |  123 ++
 .../VanillaSoftwareProcessYamlTest.java         |  299 +++++
 .../CatalogOsgiVersionMoreEntityRebindTest.java |   10 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |    3 +
 .../java-web-app-and-db-with-function-2.yaml    |    9 +-
 .../java-web-app-and-db-with-function.yaml      |    7 +-
 ...-java-web-app-spec-and-db-with-function.yaml |    7 +-
 .../test/resources/visitors-creation-script.sql |   19 +-
 camp/camp-server/pom.xml                        |    2 +-
 camp/pom.xml                                    |    2 +-
 core/pom.xml                                    |    2 +-
 .../apache/brooklyn/core/BrooklynVersion.java   |    2 +-
 .../brooklyn/core/config/BasicConfigKey.java    |   41 +-
 .../brooklyn/core/entity/AbstractEntity.java    |    6 +-
 .../apache/brooklyn/core/entity/Attributes.java |   10 +-
 .../core/entity/BrooklynConfigKeys.java         |  124 +-
 .../core/mgmt/entitlement/Entitlements.java     |    1 +
 .../mgmt/ha/OsgiBundleInstallationResult.java   |    4 +-
 .../BasicExternalConfigSupplierRegistry.java    |   12 +-
 .../core/objs/AbstractEntityAdjunct.java        |   61 +-
 .../core/sensor/BasicAttributeSensor.java       |   11 +-
 .../brooklyn/core/sensor/BasicSensor.java       |   19 +-
 .../apache/brooklyn/core/sensor/Sensors.java    |    9 +-
 .../core/sensor/function/FunctionSensor.java    |   89 ++
 .../core/typereg/BasicBrooklynTypeRegistry.java |   20 +-
 .../typereg/BasicTypeImplementationPlan.java    |    4 +-
 .../typereg/RegisteredTypeLoadingContexts.java  |    6 +-
 .../core/typereg/RegisteredTypePredicates.java  |   78 +-
 .../brooklyn/core/typereg/RegisteredTypes.java  |    2 +-
 .../enricher/stock/AbstractAggregator.java      |   37 +-
 .../enricher/stock/AbstractTransformer.java     |   22 +-
 .../brooklyn/enricher/stock/Aggregator.java     |   15 +-
 .../brooklyn/enricher/stock/Combiner.java       |   33 +-
 .../apache/brooklyn/enricher/stock/Joiner.java  |   17 +-
 .../brooklyn/enricher/stock/MapAggregator.java  |   11 +-
 .../enricher/stock/PercentageEnricher.java      |    7 +-
 .../brooklyn/enricher/stock/Transformer.java    |   23 +-
 .../brooklyn/enricher/stock/UpdatingMap.java    |   23 +-
 .../YamlRollingTimeWindowMeanEnricher.java      |   13 +-
 .../stock/YamlTimeWeightedDeltaEnricher.java    |    7 +-
 .../enricher/stock/reducer/Reducer.java         |   26 +-
 .../brooklyn/entity/group/AbstractGroup.java    |   13 +-
 .../apache/brooklyn/entity/group/Cluster.java   |    2 +
 .../brooklyn/entity/group/DynamicCluster.java   |   21 +-
 .../brooklyn/entity/group/DynamicFabric.java    |   23 +-
 .../brooklyn/entity/group/DynamicGroup.java     |    6 +-
 .../brooklyn/entity/stock/BasicStartable.java   |    6 +-
 .../brooklyn/entity/stock/DelegateEntity.java   |    7 +-
 core/src/main/resources/catalog.bom             |   57 +-
 .../entity/RecordingSensorEventListener.java    |   12 +
 .../core/mgmt/osgi/OsgiStandaloneTest.java      |    4 +-
 .../core/policy/basic/EnricherTypeTest.java     |    6 -
 .../sensor/function/FunctionSensorTest.java     |   77 ++
 .../core/test/entity/TestEntityImpl.java        |    2 +-
 .../stock/TransformingEnricherTest.java         |    7 +-
 .../util/core/internal/ssh/ExecCmdAsserts.java  |   12 +-
 core/src/test/resources/catalog.bom             |    2 +-
 karaf/commands/pom.xml                          |    2 +-
 karaf/features/pom.xml                          |    2 +-
 karaf/httpcomponent-extension/pom.xml           |    2 +-
 karaf/init/pom.xml                              |    2 +-
 .../init/src/main/resources/catalog-classes.bom |  107 +-
 karaf/jetty-config/pom.xml                      |    2 +-
 karaf/pom.xml                                   |    2 +-
 karaf/start/pom.xml                             |    2 +-
 launcher-common/pom.xml                         |    2 +-
 launcher/pom.xml                                |    2 +-
 .../java-web-app-and-db-with-function.yaml      |    3 +-
 .../test/resources/visitors-creation-script.sql |   19 +-
 locations/container/pom.xml                     |    2 +-
 .../resources/generic-application.tests.bom     |    8 +-
 .../src/test/resources/generic.tests.bom        |    2 +-
 locations/jclouds/pom.xml                       |    2 +-
 .../location/jclouds/JcloudsLocation.java       |   73 +-
 .../api/JcloudsLocationConfigPublic.java        |    6 +
 .../JcloudsMaxConcurrencyStubbedTest.java       |  225 ++++
 logging/logback-includes/pom.xml                |    2 +-
 logging/logback-xml/pom.xml                     |    2 +-
 parent/pom.xml                                  |    2 +-
 policy/pom.xml                                  |    2 +-
 .../action/AbstractScheduledEffectorPolicy.java |  292 +++++
 .../policy/action/PeriodicEffectorPolicy.java   |  116 ++
 .../policy/action/ScheduledEffectorPolicy.java  |  100 ++
 .../policy/autoscaling/AutoScalerPolicy.java    |   25 +-
 .../policy/ha/ConnectionFailureDetector.java    |   14 +-
 .../policy/ha/ServiceFailureDetector.java       |   16 +-
 .../brooklyn/policy/ha/ServiceReplacer.java     |   20 +-
 .../brooklyn/policy/ha/ServiceRestarter.java    |   16 +-
 .../policy/ha/SshMachineFailureDetector.java    |    4 +-
 policy/src/main/resources/catalog.bom           |   92 +-
 .../action/AbstractEffectorPolicyTest.java      |   81 ++
 .../action/PeriodicEffectorPolicyTest.java      |  123 ++
 .../action/ScheduledEffectorPolicyTest.java     |  121 ++
 .../action/ScheduledPolicyRebindTest.java       |  137 +++
 .../AutoScalerPolicyPoolSizeTest.java           |   18 +-
 .../AbstractLoadBalancingPolicyTest.java        |    1 -
 pom.xml                                         |    4 +-
 rest/rest-api/pom.xml                           |    2 +-
 .../apache/brooklyn/rest/api/AdjunctApi.java    |    6 +-
 .../org/apache/brooklyn/rest/api/BundleApi.java |   37 +-
 .../apache/brooklyn/rest/api/CatalogApi.java    |   56 +-
 .../brooklyn/rest/api/EntityConfigApi.java      |   10 +-
 .../apache/brooklyn/rest/api/SubtypeApi.java    |   96 --
 .../org/apache/brooklyn/rest/api/TypeApi.java   |   16 +-
 .../rest/domain/AdjunctConfigSummary.java       |   85 --
 .../brooklyn/rest/domain/AdjunctDetail.java     |    4 +-
 .../brooklyn/rest/domain/BundleSummary.java     |    7 +
 .../brooklyn/rest/domain/ConfigSummary.java     |   66 +-
 .../rest/domain/EnricherConfigSummary.java      |   11 +-
 .../rest/domain/EntityConfigSummary.java        |   67 +-
 .../rest/domain/LocationConfigSummary.java      |   40 +-
 .../rest/domain/PolicyConfigSummary.java        |   29 +-
 .../apache/brooklyn/rest/domain/TypeDetail.java |    3 +-
 .../brooklyn/rest/domain/TypeSummary.java       |   12 +-
 rest/rest-resources/pom.xml                     |    2 +-
 .../apache/brooklyn/rest/BrooklynRestApi.java   |    2 -
 .../rest/resources/AdjunctResource.java         |    8 +-
 .../brooklyn/rest/resources/BundleResource.java |   45 +-
 .../rest/resources/EntityConfigResource.java    |    8 +-
 .../rest/resources/SubtypeResource.java         |   82 --
 .../brooklyn/rest/resources/TypeResource.java   |   23 +-
 .../rest/transform/AdjunctTransformer.java      |   41 +-
 .../rest/transform/EntityTransformer.java       |  111 +-
 .../rest/transform/PolicyTransformer.java       |    3 +-
 .../rest/transform/TypeTransformer.java         |   43 +-
 .../BundleAndTypeAndSubtypeResourcesTest.java   | 1093 -----------------
 .../resources/BundleAndTypeResourcesTest.java   | 1098 ++++++++++++++++++
 .../resources/EntityConfigResourceTest.java     |    2 +-
 rest/rest-server/pom.xml                        |    2 +-
 server-cli/pom.xml                              |    2 +-
 .../brooklyn/cli/lister/ItemDescriptors.java    |   28 +-
 .../main/resources/brooklyn/default.catalog.bom |    2 +-
 server-cli/src/main/resources/catalog.bom       |    2 +-
 software/base/pom.xml                           |    2 +-
 .../entity/brooklynnode/BrooklynNode.java       |    2 +-
 .../brooklynnode/BrooklynNodeSshDriver.java     |    2 +-
 .../brooklyn/entity/java/JmxmpSslSupport.java   |    2 +-
 .../apache/brooklyn/entity/java/UsesJava.java   |   10 +-
 .../apache/brooklyn/entity/java/UsesJmx.java    |   37 +-
 .../software/base/AbstractVanillaProcess.java   |   21 +-
 .../software/base/EmptySoftwareProcessImpl.java |    4 +-
 .../entity/software/base/SoftwareProcess.java   |   37 +-
 .../software/base/SoftwareProcessImpl.java      |    1 -
 .../software/base/VanillaSoftwareProcess.java   |    5 +-
 .../base/VanillaSoftwareProcessImpl.java        |   16 +-
 .../base/VanillaSoftwareProcessSshDriver.java   |   12 +-
 .../software/base/VanillaWindowsProcess.java    |   22 +-
 software/base/src/main/resources/catalog.bom    |   17 +-
 software/winrm/pom.xml                          |    2 +-
 test-framework/pom.xml                          |    2 +-
 test-framework/src/main/resources/catalog.bom   |   12 +-
 test-support/pom.xml                            |    2 +-
 .../test/performance/PerformanceTestUtils.java  |   50 +-
 .../osgi/com-example-entities/pom.xml           |    2 +-
 utils/common/dependencies/osgi/entities/pom.xml |    2 +-
 .../dependencies/osgi/more-entities-v1/pom.xml  |    2 +-
 .../osgi/more-entities-v2-evil-twin/pom.xml     |    2 +-
 .../dependencies/osgi/more-entities-v2/pom.xml  |    2 +-
 utils/common/pom.xml                            |    2 +-
 .../apache/brooklyn/util/guava/TypeTokens.java  |   38 +-
 .../javalang/coerce/TypeCoercerExtensible.java  |   15 +-
 .../brooklyn/util/maven/MavenArtifactTest.java  |    4 +-
 utils/groovy/pom.xml                            |    2 +-
 utils/jmx/jmxmp-ssl-agent/pom.xml               |    2 +-
 utils/jmx/jmxrmi-agent/pom.xml                  |    2 +-
 utils/rest-swagger/pom.xml                      |    2 +-
 utils/rt-felix/pom.xml                          |    2 +-
 utils/test-support/pom.xml                      |    2 +-
 175 files changed, 4572 insertions(+), 2177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
----------------------------------------------------------------------
diff --cc rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
index 5fc1366,0000000..1886f63
mode 100644,000000..100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
@@@ -1,233 -1,0 +1,233 @@@
 +/*
 + * 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.rest.api;
 +
 +import java.util.List;
 +import java.util.Map;
 +
 +import javax.ws.rs.Consumes;
 +import javax.ws.rs.DELETE;
 +import javax.ws.rs.GET;
 +import javax.ws.rs.POST;
 +import javax.ws.rs.Path;
 +import javax.ws.rs.PathParam;
 +import javax.ws.rs.Produces;
 +import javax.ws.rs.QueryParam;
 +import javax.ws.rs.core.MediaType;
 +import javax.ws.rs.core.Response;
 +
- import org.apache.brooklyn.rest.domain.AdjunctConfigSummary;
 +import org.apache.brooklyn.rest.domain.AdjunctDetail;
 +import org.apache.brooklyn.rest.domain.AdjunctSummary;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
 +import org.apache.brooklyn.rest.domain.Status;
 +
 +import io.swagger.annotations.Api;
 +import io.swagger.annotations.ApiOperation;
 +import io.swagger.annotations.ApiParam;
 +import io.swagger.annotations.ApiResponse;
 +import io.swagger.annotations.ApiResponses;
 +
 +@Path("/applications/{application}/entities/{entity}/adjuncts")
 +@Api("Entity Adjuncts (policies, enrichers, feeds)")
 +@Produces(MediaType.APPLICATION_JSON)
 +@Consumes(MediaType.APPLICATION_JSON)
 +public interface AdjunctApi {
 +
 +    @GET
 +    @ApiOperation(value = "Fetch the adjuncts attached to a specific application entity",
 +            response = org.apache.brooklyn.rest.domain.AdjunctSummary.class,
 +            responseContainer = "List")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application or entity")
 +    })
 +    public List<AdjunctSummary> list(
 +            @ApiParam(value = "Application ID or name", required = true)
 +            @PathParam("application") final String application,
 +            @ApiParam(value = "Entity ID or name", required = true)
 +            @PathParam("entity") final String entityToken,
 +            @ApiParam(value = "Filter by adjunct type", required = false)
 +            @QueryParam("adjunctType") final String adjunctType);
 +
 +    @POST
 +    @ApiOperation(value = "Add an adjunct (policy, enricher, or feed)", notes = "Returns a summary of the added adjunct")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application or entity"),
 +            @ApiResponse(code = 400, message = "Type is not a suitable adjunct")
 +    })
 +    public AdjunctSummary addAdjunct(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "type", value = "Adjunct from the type registry to instantiate and add", required = true)
 +            @QueryParam("type")
 +            String adjunctRegisteredTypeName,
 +
 +            // TODO would like to make this optional but jersey complains if we do
 +            @ApiParam(name = "config", value = "Configuration for the adjunct (as key value pairs)", required = true)
 +            Map<String, String> config);
 +
 +    @GET
 +    @Path("/{adjunct}")
 +    @ApiOperation(value = "Gets detail of an adjunct")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity or adjunct")
 +    })
 +    public AdjunctDetail get(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "adjunct", value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctId);
 +    
 +    @GET
 +    @Path("/{adjunct}/status")
 +    @ApiOperation(value = "Gets status of an adjunct (RUNNING / SUSPENDED)")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity or adjunct")
 +    })
 +    public Status getStatus(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "adjunct", value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctId);
 +
 +    @POST
 +    @Path("/{adjunct}/start")
 +    @ApiOperation(value = "Start or resume an adjunct")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity or adjunct")
 +    })
 +    public Response start(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "adjunct", value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctId);
 +
 +    @POST
 +    @Path("/{adjunct}/stop")
 +    @ApiOperation(value = "Suspends an adjunct")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity or adjunct")
 +    })
 +    public Response stop(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "adjunct", value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctId);
 +
 +    @DELETE
 +    @Path("/{adjunct}")
 +    @ApiOperation(value = "Destroy an adjunct", notes="Removes an adjunct from being associated with the entity and destroys it (stopping first if running)")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity or adjunct")
 +    })
 +    public Response destroy(
 +            @ApiParam(name = "application", value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +
 +            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +
 +            @ApiParam(name = "adjunct", value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctId);
 +
 +    /// ---------- config ---------------
 +    
 +    @GET
 +    @Path("/{adjunct}/config")
 +    @ApiOperation(value = "Fetch the config keys for a specific adjunct",
-             response = org.apache.brooklyn.rest.domain.AdjunctConfigSummary.class,
++            response = org.apache.brooklyn.rest.domain.ConfigSummary.class,
 +            responseContainer = "List")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application or entity or adjunct")
 +    })
-     public List<AdjunctConfigSummary> listConfig(
++    public List<ConfigSummary> listConfig(
 +            @ApiParam(value = "Application ID or name", required = true)
 +            @PathParam("application") final String application,
 +            @ApiParam(value = "Entity ID or name", required = true)
 +            @PathParam("entity") final String entityToken,
 +            @ApiParam(value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") final String adjunctToken);
 +
 +    // TODO support parameters  ?show=value,summary&name=xxx &format={string,json,xml}
 +    // (and in sensors class)
 +    @GET
 +    @Path("/{adjunct}/config-current")
 +    @ApiOperation(value = "Fetch config key values in batch", notes="Returns a map of config name to value")
 +    public Map<String, Object> batchConfigRead(
 +            @ApiParam(value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +            @ApiParam(value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +            @ApiParam(value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctToken) ;
 +
 +    @GET
 +    @Path("/{adjunct}/config/{config}")
 +    @ApiOperation(value = "Fetch config value", response = Object.class)
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity, adjunct or config key")
 +    })
 +    public String getConfig(
 +            @ApiParam(value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +            @ApiParam(value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +            @ApiParam(value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctToken,
 +            @ApiParam(value = "Config key ID", required = true)
 +            @PathParam("config") String configKeyName);
 +
 +    @POST
 +    @Path("/{adjunct}/config/{config}")
 +    @Consumes(value = {"*/*"})
 +    @ApiOperation(value = "Sets the given config on this adjunct")
 +    @ApiResponses(value = {
 +            @ApiResponse(code = 404, message = "Could not find application, entity, adjunct or config key")
 +    })
 +    public Response setConfig(
 +            @ApiParam(value = "Application ID or name", required = true)
 +            @PathParam("application") String application,
 +            @ApiParam(value = "Entity ID or name", required = true)
 +            @PathParam("entity") String entityToken,
 +            @ApiParam(value = "Adjunct ID or name", required = true)
 +            @PathParam("adjunct") String adjunctToken,
 +            @ApiParam(value = "Config key ID", required = true)
 +            @PathParam("config") String configKeyName,
 +            @ApiParam(name = "value", value = "New value for the configuration", required = true)
 +            Object value);
 +}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
----------------------------------------------------------------------
diff --cc rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
index 4a5bbde,4a5bbde..a0e3604
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
@@@ -18,7 -18,7 +18,6 @@@
   */
  package org.apache.brooklyn.rest.api;
  
--import io.swagger.annotations.Api;
  import java.util.List;
  import java.util.Map;
  
@@@ -32,12 -32,12 +31,13 @@@ import javax.ws.rs.Produces
  import javax.ws.rs.QueryParam;
  import javax.ws.rs.core.MediaType;
  
--import org.apache.brooklyn.rest.domain.EntityConfigSummary;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
  
--import io.swagger.annotations.ApiResponse;
--import io.swagger.annotations.ApiResponses;
++import io.swagger.annotations.Api;
  import io.swagger.annotations.ApiOperation;
  import io.swagger.annotations.ApiParam;
++import io.swagger.annotations.ApiResponse;
++import io.swagger.annotations.ApiResponses;
  
  @Path("/applications/{application}/entities/{entity}/config")
  @Api("Entity Config")
@@@ -52,7 -52,7 +52,7 @@@ public interface EntityConfigApi 
      @ApiResponses(value = {
              @ApiResponse(code = 404, message = "Could not find application or entity")
      })
--    public List<EntityConfigSummary> list(
++    public List<ConfigSummary> list(
              @ApiParam(value = "Application ID or name", required = true)
              @PathParam("application") final String application,
              @ApiParam(value = "Entity ID or name", required = true)

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
----------------------------------------------------------------------
diff --cc rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
index ddce5f4,0000000..a2f348c
mode 100644,000000..100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
@@@ -1,72 -1,0 +1,72 @@@
 +/*
 + * 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.rest.domain;
 +
 +import java.util.Map;
 +import java.util.Set;
 +
 +import org.apache.brooklyn.api.objs.EntityAdjunct;
 +import org.apache.brooklyn.util.collections.MutableMap;
 +import org.apache.brooklyn.util.collections.MutableSet;
 +
 +import com.fasterxml.jackson.annotation.JsonInclude;
 +import com.fasterxml.jackson.annotation.JsonInclude.Include;
 +
 +public class AdjunctDetail extends AdjunctSummary {
 +
 +    private static final long serialVersionUID = -5086680835225136768L;
 +
 +    @JsonInclude(Include.NON_EMPTY)
 +    private String functionallyUniqueIdentifier;
 +    @JsonInclude(Include.NON_EMPTY)
 +    private Set<Object> tags;
 +    @JsonInclude(Include.NON_EMPTY)
-     final Set<AdjunctConfigSummary> parameters = MutableSet.of();
++    final Set<ConfigSummary> parameters = MutableSet.of();
 +    final Map<String,Object> config = MutableMap.of();
 +
 +    // for json
 +    protected AdjunctDetail() {}
 +
 +    public AdjunctDetail(EntityAdjunct a) {
 +        super(a);
 +        this.functionallyUniqueIdentifier = a.getUniqueTag();
 +        this.tags = a.tags().getTags();
 +    }
 +    
 +    public String getFunctionallyUniqueIdentifier() {
 +        return functionallyUniqueIdentifier;
 +    }
 +    
 +    public Set<Object> getTags() {
 +        return tags;
 +    }
 +    
-     public AdjunctDetail parameter(AdjunctConfigSummary p) {
++    public AdjunctDetail parameter(ConfigSummary p) {
 +        parameters.add(p); return this;
 +    }
 +
 +    public AdjunctDetail config(String key, Object val) {
 +        config.put(key, val); return this;
 +    }
 +
 +    public AdjunctDetail config(Map<String,Object> vals) {
 +        config.putAll(vals); return this;
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
----------------------------------------------------------------------
diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
index 9dd4c10,0000000..3b5185a
mode 100644,000000..100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
@@@ -1,263 -1,0 +1,263 @@@
 +/*
 + * 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.rest.resources;
 +
 +import java.util.Collections;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +
 +import javax.ws.rs.core.Context;
 +import javax.ws.rs.core.Response;
 +import javax.ws.rs.core.UriInfo;
 +
 +import org.apache.brooklyn.api.entity.Entity;
 +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 +import org.apache.brooklyn.api.objs.BrooklynObjectType;
 +import org.apache.brooklyn.api.objs.EntityAdjunct;
 +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.sensor.Feed;
 +import org.apache.brooklyn.api.typereg.RegisteredType;
 +import org.apache.brooklyn.config.ConfigKey;
 +import org.apache.brooklyn.core.config.ConfigPredicates;
 +import org.apache.brooklyn.core.entity.EntityInternal;
 +import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 +import org.apache.brooklyn.rest.api.AdjunctApi;
- import org.apache.brooklyn.rest.domain.AdjunctConfigSummary;
 +import org.apache.brooklyn.rest.domain.AdjunctDetail;
 +import org.apache.brooklyn.rest.domain.AdjunctSummary;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
 +import org.apache.brooklyn.rest.domain.Status;
 +import org.apache.brooklyn.rest.domain.SummaryComparators;
 +import org.apache.brooklyn.rest.filter.HaHotStateRequired;
 +import org.apache.brooklyn.rest.transform.AdjunctTransformer;
 +import org.apache.brooklyn.rest.transform.EntityTransformer;
 +import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
 +import org.apache.brooklyn.rest.util.WebResourceUtils;
 +import org.apache.brooklyn.util.core.ClassLoaderUtils;
 +import org.apache.brooklyn.util.core.flags.TypeCoercions;
 +import org.apache.brooklyn.util.exceptions.Exceptions;
 +import org.apache.brooklyn.util.text.Strings;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +
 +import com.google.common.base.Function;
 +import com.google.common.base.Predicates;
 +import com.google.common.collect.FluentIterable;
 +import com.google.common.collect.Iterables;
 +import com.google.common.collect.Lists;
 +
 +@HaHotStateRequired
 +public class AdjunctResource extends AbstractBrooklynRestResource implements AdjunctApi {
 +
 +    private static final Logger log = LoggerFactory.getLogger(AdjunctResource.class);
 +
 +    private @Context UriInfo ui;
 +
 +    @Override
 +    public List<AdjunctSummary> list(String application, String entityToken, String adjunctType) {
 +        final Entity entity = brooklyn().getEntity(application, entityToken);
 +        Iterable<? extends EntityAdjunct> source = Collections.emptyList();
 +        boolean all = Strings.isBlank(adjunctType);
 +        boolean any = false;
 +        if (all || adjunctType.equalsIgnoreCase(BrooklynObjectType.POLICY.name())) {
 +            any = true;
 +            source = Iterables.concat(source, entity.policies());
 +        }
 +        if (all || adjunctType.equalsIgnoreCase(BrooklynObjectType.ENRICHER.name())) {
 +            any = true;
 +            source = Iterables.concat(source, entity.enrichers());
 +        }
 +        if (all || adjunctType.equalsIgnoreCase(BrooklynObjectType.FEED.name())) {
 +            any = true;
 +            source = Iterables.concat(source, ((EntityInternal)entity).feeds());
 +        }
 +        if (!any) {
 +            throw WebResourceUtils.badRequest("Unknown adjunct type '%s'; use 'policy', 'enricher', or 'feed'", adjunctType);
 +        }
 +        return FluentIterable.from(source)
 +            .transform(new Function<EntityAdjunct, AdjunctSummary>() {
 +                @Override
 +                public AdjunctSummary apply(EntityAdjunct adjunct) {
 +                    return AdjunctTransformer.adjunctSummary(entity, adjunct, ui.getBaseUriBuilder());
 +                }
 +            })
 +            .toSortedList(SummaryComparators.nameComparator());
 +    }
 +
 +    // TODO would like to make 'config' arg optional but jersey complains if we do
 +    @SuppressWarnings({ "rawtypes", "unchecked" })
 +    @Override
 +    public AdjunctSummary addAdjunct(String application, String entityToken, String adjunctTypeName, Map<String, String> config) {
 +        Entity entity = brooklyn().getEntity(application, entityToken);
 +        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
 +            throw WebResourceUtils.forbidden("User '%s' is not authorized to modify entity '%s'",
 +                    Entitlements.getEntitlementContext().user(), entity);
 +        }
 +        
 +        RegisteredType rt = brooklyn().getTypeRegistry().get(adjunctTypeName);
 +        AbstractBrooklynObjectSpec<?, ?> spec;
 +        if (rt!=null) {
 +            spec = brooklyn().getTypeRegistry().createSpec(rt, null, null);
 +        } else {
 +            try {
 +                Class<?> type = new ClassLoaderUtils(this, mgmt()).loadClass(adjunctTypeName);
 +                if (Policy.class.isAssignableFrom(type)) spec = PolicySpec.create((Class) type);
 +                else if (Enricher.class.isAssignableFrom(type)) spec = EnricherSpec.create((Class) type);
 +                else if (Feed.class.isAssignableFrom(type)) {
 +                    // TODO add FeedSpec ?  would be needed even if using the type registry
 +                    throw WebResourceUtils.badRequest("Creation of feeds from java type (%s) not supported", adjunctTypeName);
 +                } else {
 +                    throw WebResourceUtils.badRequest("Invalid type %s; not a support adjunct type", adjunctTypeName);
 +                }
 +            } catch (ClassNotFoundException e) {
 +                throw WebResourceUtils.badRequest("No adjunct with type %s found", adjunctTypeName);
 +            } catch (ClassCastException e) {
 +                throw WebResourceUtils.badRequest("No adjunct with type %s found", adjunctTypeName);
 +            } catch (Exception e) {
 +                throw Exceptions.propagate(e);
 +            }
 +        }
 +
 +        spec.configure(config);
 +
 +        EntityAdjunct instance;
 +        if (spec instanceof PolicySpec) instance = entity.policies().add((PolicySpec)spec);
 +        else if (spec instanceof EnricherSpec) instance = entity.enrichers().add((EnricherSpec)spec);
 +        else {
 +            // TODO add FeedSpec
 +            throw WebResourceUtils.badRequest("Unexpected spec type %s", spec);
 +        }
 +
 +        log.debug("REST API added adjunct " + instance + " to " + entity);
 +
 +        return AdjunctTransformer.adjunctDetail(brooklyn(), entity, instance, ui.getBaseUriBuilder());
 +    }
 +
 +    @Override
 +    public AdjunctDetail get(String application, String entityToken, String adjunctId) {
 +        Entity entity = brooklyn().getEntity(application, entityToken);
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(entity, adjunctId);
 +
 +        return AdjunctTransformer.adjunctDetail(brooklyn(), entity, adjunct, ui.getBaseUriBuilder());
 +    }
 +    
 +    @Override
 +    public Status getStatus(String application, String entityToken, String adjunctId) {
 +        return AdjunctTransformer.inferStatus( brooklyn().getAdjunct(application, entityToken, adjunctId) );
 +    }
 +
 +    @Override
 +    public Response start(String application, String entityToken, String adjunctId) {
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctId);
 +        if (adjunct instanceof Policy) ((Policy)adjunct).resume();
 +        else if (adjunct instanceof Feed) ((Feed)adjunct).resume();
 +        else throw WebResourceUtils.badRequest("%s does not support start/resume", adjunct);
 +        
 +        return Response.status(Response.Status.NO_CONTENT).build();
 +    }
 +
 +    @Override
 +    public Response stop(String application, String entityToken, String adjunctId) {
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctId);
 +        if (adjunct instanceof Policy) ((Policy)adjunct).suspend();
 +        else if (adjunct instanceof Feed) ((Feed)adjunct).suspend();
 +        else throw WebResourceUtils.badRequest("%s does not support suspend", adjunct);
 +        
 +        return Response.status(Response.Status.NO_CONTENT).build();
 +    }
 +
 +    @Override
 +    public Response destroy(String application, String entityToken, String adjunctId) {
 +        Entity entity = brooklyn().getEntity(application, entityToken);
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(entity, adjunctId);
 +
 +        if (adjunct instanceof Policy) {
 +            ((Policy)adjunct).suspend();
 +            entity.policies().remove((Policy) adjunct);
 +        } else if (adjunct instanceof Enricher) {
 +            entity.enrichers().remove((Enricher) adjunct);
 +        } else if (adjunct instanceof Feed) {
 +            ((Feed)adjunct).suspend();
 +            ((EntityInternal)entity).feeds().remove((Feed) adjunct);
 +        } else {
 +            throw WebResourceUtils.badRequest("Unexpected adjunct type %s", adjunct);
 +        }
 +        
 +        return Response.status(Response.Status.NO_CONTENT).build();
 +    }
 +    
 +    // ---- config ----
 +    
 +    @Override
-     public List<AdjunctConfigSummary> listConfig(
++    public List<ConfigSummary> listConfig(
 +            final String application, final String entityToken, final String adjunctToken) {
 +        Entity entity = brooklyn().getEntity(application, entityToken);
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(entity, adjunctToken);
 +
-         List<AdjunctConfigSummary> result = Lists.newArrayList();
++        List<ConfigSummary> result = Lists.newArrayList();
 +        for (ConfigKey<?> key : adjunct.config().findKeysPresent(Predicates.alwaysTrue())) {
-             result.add(AdjunctTransformer.configSummary(brooklyn(), entity, adjunct, key, ui.getBaseUriBuilder()));
++            result.add(AdjunctTransformer.configSummary(brooklyn(), ui.getBaseUriBuilder(), entity, adjunct, key));
 +        }
 +        return result;
 +    }
 +
 +    // TODO support parameters  ?show=value,summary&name=xxx &format={string,json,xml}
 +    // (and in sensors class)
 +    @Override
 +    public Map<String, Object> batchConfigRead(String application, String entityToken, String adjunctToken) {
 +        // TODO: add test
 +        return EntityTransformer.getConfigValues(brooklyn(), brooklyn().getAdjunct(application, entityToken, adjunctToken) );
 +    }
 +
 +    @Override
 +    public String getConfig(String application, String entityToken, String adjunctToken, String configKeyName) {
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(application, entityToken, adjunctToken);
 +        Set<ConfigKey<?>> cki = adjunct.config().findKeysDeclared(ConfigPredicates.nameSatisfies(Predicates.equalTo(configKeyName)));
 +        if (cki.isEmpty()) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, adjunctToken, entityToken);
 +
 +        return brooklyn().getStringValueForDisplay(adjunct.config().get(cki.iterator().next()));
 +    }
 +
 +    @SuppressWarnings({ "unchecked", "rawtypes" })
 +    @Override
 +    public Response setConfig(String application, String entityToken, String adjunctToken, String configKeyName, Object value) {
 +        Entity entity = brooklyn().getEntity(application, entityToken);
 +        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
 +            throw WebResourceUtils.forbidden("User '%s' is not authorized to modify entity '%s'",
 +                    Entitlements.getEntitlementContext().user(), entity);
 +        }
 +
 +        EntityAdjunct adjunct = brooklyn().getAdjunct(entity, adjunctToken);
 +        Set<ConfigKey<?>> cki = adjunct.config().findKeysDeclared(ConfigPredicates.nameSatisfies(Predicates.equalTo(configKeyName)));
 +        if (cki.isEmpty()) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, adjunctToken, entityToken);
 +        ConfigKey<?> ck = cki.iterator().next();
 +        
 +        adjunct.config().set((ConfigKey) cki, TypeCoercions.coerce(value, ck.getTypeToken()));
 +
 +        return Response.status(Response.Status.OK).build();
 +    }
 +
 +    public static String getStringValueForDisplay(BrooklynRestResourceUtils utils, EntityAdjunct policy, Object value) {
 +        return utils.getStringValueForDisplay(value);
 +    }
 +    
 +}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityConfigResource.java
----------------------------------------------------------------------
diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityConfigResource.java
index d85f1d7,d85f1d7..dd909e4
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityConfigResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityConfigResource.java
@@@ -32,7 -32,7 +32,7 @@@ import org.apache.brooklyn.core.entity.
  import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
  import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.EntityAndItem;
  import org.apache.brooklyn.rest.api.EntityConfigApi;
--import org.apache.brooklyn.rest.domain.EntityConfigSummary;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
  import org.apache.brooklyn.rest.filter.HaHotStateRequired;
  import org.apache.brooklyn.rest.transform.EntityTransformer;
  import org.apache.brooklyn.rest.util.WebResourceUtils;
@@@ -52,7 -52,7 +52,7 @@@ public class EntityConfigResource exten
      private static final Logger LOG = LoggerFactory.getLogger(EntityConfigResource.class);
  
      @Override
--    public List<EntityConfigSummary> list(final String application, final String entityToken) {
++    public List<ConfigSummary> list(final String application, final String entityToken) {
          final Entity entity = brooklyn().getEntity(application, entityToken);
          if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
              throw WebResourceUtils.forbidden("User '%s' is not authorized to see entity '%s'",
@@@ -61,7 -61,7 +61,7 @@@
  
          // TODO merge with keys which have values:
          //      ((EntityInternal) entity).config().getBag().getAllConfigAsConfigKeyMap();
--        List<EntityConfigSummary> result = Lists.newArrayList();
++        List<ConfigSummary> result = Lists.newArrayList();
          
          for (ConfigKey<?> key : entity.getEntityType().getConfigKeys()) {
              // Exclude config that user is not allowed to see
@@@ -70,7 -70,7 +70,7 @@@
                          new Object[] {Entitlements.getEntitlementContext().user(), key.getName(), entity});
                  continue;
              }
--            result.add(EntityTransformer.entityConfigSummary(entity, key, ui.getBaseUriBuilder()));
++            result.add(EntityTransformer.configSummary(brooklyn(), ui.getBaseUriBuilder(), entity, key));
          }
          
          return result;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
----------------------------------------------------------------------
diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
index db7d4cd,0000000..f841f33
mode 100644,000000..100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
@@@ -1,117 -1,0 +1,116 @@@
 +/*
 + * 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.rest.transform;
 +
 +import static org.apache.brooklyn.rest.util.WebResourceUtils.serviceUriBuilder;
 +
 +import java.net.URI;
 +import java.util.Map;
 +
++import javax.annotation.Nullable;
 +import javax.ws.rs.core.UriBuilder;
 +
 +import org.apache.brooklyn.api.entity.Entity;
 +import org.apache.brooklyn.api.objs.EntityAdjunct;
++import org.apache.brooklyn.api.objs.SpecParameter;
 +import org.apache.brooklyn.api.policy.Policy;
 +import org.apache.brooklyn.api.sensor.Feed;
 +import org.apache.brooklyn.config.ConfigKey;
 +import org.apache.brooklyn.core.policy.Policies;
 +import org.apache.brooklyn.rest.api.AdjunctApi;
 +import org.apache.brooklyn.rest.api.ApplicationApi;
 +import org.apache.brooklyn.rest.api.EntityApi;
- import org.apache.brooklyn.rest.domain.AdjunctConfigSummary;
 +import org.apache.brooklyn.rest.domain.AdjunctDetail;
 +import org.apache.brooklyn.rest.domain.AdjunctSummary;
- import org.apache.brooklyn.rest.domain.ApplicationSummary;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
 +import org.apache.brooklyn.rest.domain.Status;
 +import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
 +import org.apache.brooklyn.util.collections.MutableMap;
 +
 +import com.google.common.base.Predicates;
- import com.google.common.collect.ImmutableMap;
 +
 +/**
 + * Converts from Brooklyn entities to restful API summary objects
 + */
 +public class AdjunctTransformer {
 +
 +    public static AdjunctSummary adjunctSummary(Entity entity, EntityAdjunct adjunct, UriBuilder ub) {
 +        return embellish(new AdjunctSummary(adjunct), entity, adjunct, ub);
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    private static <T extends AdjunctSummary> T embellish(T adjunctSummary, Entity entity, EntityAdjunct adjunct, UriBuilder ub) {
 +        return (T) adjunctSummary.state(inferStatus(adjunct)).links( buildLinks(entity, adjunct, ub, adjunctSummary instanceof AdjunctDetail) );
 +    }
 +
 +    public static AdjunctDetail adjunctDetail(BrooklynRestResourceUtils utils, Entity entity, EntityAdjunct adjunct, UriBuilder ub) {
 +        AdjunctDetail result = embellish(new AdjunctDetail(adjunct), entity, adjunct, ub);
 +        for (ConfigKey<?> key: adjunct.config().findKeysDeclared(Predicates.alwaysTrue())) {
-             result.parameter(configSummary(utils, entity, adjunct, key, ub));
++            result.parameter(configSummary(utils, ub, entity, adjunct, key));
 +        }
 +        result.config(EntityTransformer.getConfigValues(utils, adjunct));
 +        return result;
 +    }
 +
 +    protected static Map<String, URI> buildLinks(Entity entity, EntityAdjunct adjunct, UriBuilder ub, boolean detail) {
 +        MutableMap<String,URI> links = MutableMap.of();
 +
 +        links.put("self", serviceUriBuilder(ub, AdjunctApi.class, "get").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +        
 +        if (detail) {
 +            links.put("application", serviceUriBuilder(ub, ApplicationApi.class, "get").build(entity.getApplicationId()));
 +            links.put("entity", serviceUriBuilder(ub, EntityApi.class, "get").build(entity.getApplicationId(), entity.getId()));
 +            links.put("config", serviceUriBuilder(ub, AdjunctApi.class, "listConfig").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +            links.put("status", serviceUriBuilder(ub, AdjunctApi.class, "getStatus").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +            if (adjunct instanceof Policy || adjunct instanceof Feed) {
 +                links.put("start", serviceUriBuilder(ub, AdjunctApi.class, "start").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +                links.put("stop", serviceUriBuilder(ub, AdjunctApi.class, "stop").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +            }
 +            links.put("destroy", serviceUriBuilder(ub, AdjunctApi.class, "destroy").build(entity.getApplicationId(), entity.getId(), adjunct.getId()));
 +        }
 +        
 +        return links.asUnmodifiable();
 +    }
 +
 +    public static Status inferStatus(EntityAdjunct adjunct) {
 +        return ApplicationTransformer.statusFromLifecycle( Policies.inferAdjunctStatus(adjunct) );
 +    }
 +
-     public static AdjunctConfigSummary configSummary(BrooklynRestResourceUtils utils, ApplicationSummary application, Entity entity, EntityAdjunct adjunct, ConfigKey<?> config, UriBuilder ub) {
-         return configSummary(utils, entity, adjunct, config, ub);
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, @Nullable Entity entity, @Nullable EntityAdjunct adjunct, SpecParameter<?> input) {
++        Double priority = input.isPinned() ? Double.valueOf(1d) : null;
++        return configSummary(utils, ub, entity, adjunct, input.getConfigKey(), input.getLabel(), priority, input.isPinned());
 +    }
 +
-     public static AdjunctConfigSummary configSummary(BrooklynRestResourceUtils utils, Entity entity, EntityAdjunct adjunct, ConfigKey<?> config, UriBuilder ub) {
-         URI applicationUri = serviceUriBuilder(ub, ApplicationApi.class, "get").build(entity.getApplicationId());
-         URI entityUri = serviceUriBuilder(ub, EntityApi.class, "get").build(entity.getApplicationId(), entity.getId());
-         URI adjunctUri = serviceUriBuilder(ub, AdjunctApi.class, "get").build(entity.getApplicationId(), entity.getId(), adjunct.getId());
-         URI configUri = serviceUriBuilder(ub, AdjunctApi.class, "getConfig").build(entity.getApplicationId(), entity.getId(), adjunct.getId(), config.getName());
- 
-         Map<String, URI> links = ImmutableMap.<String, URI>builder()
-                 .put("self", configUri)
-                 .put("application", applicationUri)
-                 .put("entity", entityUri)
-                 .put("policy", adjunctUri)
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, EntityAdjunct adjunct, ConfigKey<?> config) {
++        // TODO get catalog info from other sources?
++        // see EntityTransformer.configSummary
++        return configSummary(utils, ub, entity, adjunct, config, null, null, null);
++    }
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, @Nullable Entity entity, @Nullable EntityAdjunct adjunct, ConfigKey<?> config, String label, Double priority, Boolean pinned) {
++        URI configUri = entity==null ? null : serviceUriBuilder(ub, AdjunctApi.class, "getConfig").build(entity.getApplicationId(), entity.getId(), adjunct.getId(), config.getName());
++        Map<String, URI> links = MutableMap.<String, URI>builder()
++                .putIfNotNull("self", configUri)
++                // no point in including app/entity on every summary shown in a list
++                // (this is only ever used in a list, as self points at the value)
 +                .build();
 +
-         return new AdjunctConfigSummary(config.getName(), config.getTypeName(), config.getDescription(), 
-                 utils.getStringValueForDisplay(config.getDefaultValue()), 
-                 config.isReconfigurable(), 
-                 links);
++        // TODO get actions, see EntityTransformer.configSummary
++        return new ConfigSummary(config, label, priority, pinned, links);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
----------------------------------------------------------------------
diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
index cb7877f,73b2831..9359bb5
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
@@@ -126,58 -120,58 +126,78 @@@ public class EntityTransformer 
              }));
      }
  
++    /** @deprecated since 0.13.0 use {@link #configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, ConfigKey, String, Double, Boolean) */
++    @Deprecated
      public static EntityConfigSummary entityConfigSummary(ConfigKey<?> config, String label, Double priority, Boolean pinned, Map<String, URI> links) {
--        Map<String, URI> mapOfLinks =  links==null ? null : ImmutableMap.copyOf(links);
--        return new EntityConfigSummary(config, label, priority, pinned, mapOfLinks);
--    }
--
-     public static AdjunctConfigSummary adjunctConfigSummary(ConfigKey<?> config, String label, Double priority, Map<String, URI> links) {
-         return new AdjunctConfigSummary(config, label, priority, links);
 -    public static ConfigSummary configSummary(ConfigKey<?> config, String label, Double priority, Boolean pinned, Map<String, URI> links) {
 -        return new ConfigSummary(config, label, priority, pinned, links);
++        return new EntityConfigSummary(config, label, priority, pinned, links);
      }
  
++    /** @deprecated since 0.13.0 use {@link AdjunctTransformer#configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, org.apache.brooklyn.api.objs.EntityAdjunct, ConfigKey, String, Double, Boolean)} */
++    @Deprecated
      public static PolicyConfigSummary policyConfigSummary(ConfigKey<?> config, String label, Double priority, Map<String, URI> links) {
          return new PolicyConfigSummary(config, label, priority, links);
      }
  
++    /** @deprecated since 0.13.0 use {@link AdjunctTransformer#configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, org.apache.brooklyn.api.objs.EntityAdjunct, ConfigKey, String, Double, Boolean)} */
++    @Deprecated
      public static EnricherConfigSummary enricherConfigSummary(ConfigKey<?> config, String label, Double priority, Map<String, URI> links) {
          return new EnricherConfigSummary(config, label, priority, links);
      }
  
      /** generates a representation for a given config key, 
       * with label inferred from annoation in the entity class,
--     * and links pointing to the entity and the applicaiton */
++     * and links pointing to the entity and the application 
++     * @deprecated since 0.13.0 use {@link #configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, ConfigKey)} */
++    @Deprecated
      public static EntityConfigSummary entityConfigSummary(Entity entity, ConfigKey<?> config, UriBuilder ub) {
--      /*
--       * following code nearly there to get the @CatalogConfig annotation
--       * in the class and use that to populate a label
--       */
--
--//    EntityDynamicType typeMap = 
--//            ((AbstractEntity)entity).getMutableEntityType();
--//      // above line works if we can cast; line below won't work, but there should some way
--//      // to get back the handle to the spec from an entity local, which then *would* work
--//            EntityTypes.getDefinedEntityType(entity.getClass());
++        return (EntityConfigSummary) configSummary(null, ub, entity, config);
++    }
++    
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, ConfigKey<?> config) {
++        // TODO get catalog/display info
++        
++        /*
++         * following code nearly there to get the @CatalogConfig annotation
++         * in the class and use that to populate a label
++         */
  
--//    String label = typeMap.getConfigKeyField(config.getName());
--        String label = null;
--        Double priority = null;
++//      EntityDynamicType typeMap = 
++//              ((AbstractEntity)entity).getMutableEntityType();
++//        // above line works if we can cast; line below won't work, but there should some way
++//        // to get back the handle to the spec from an entity local, which then *would* work
++//              EntityTypes.getDefinedEntityType(entity.getClass());
  
--        URI applicationUri = serviceUriBuilder(ub, ApplicationApi.class, "get").build(entity.getApplicationId());
--        URI entityUri = serviceUriBuilder(ub, EntityApi.class, "get").build(entity.getApplicationId(), entity.getId());
--        URI selfUri = serviceUriBuilder(ub, EntityConfigApi.class, "get").build(entity.getApplicationId(), entity.getId(), config.getName());
++//      String label = typeMap.getConfigKeyField(config.getName());
++        return configSummary(null, ub, entity, config, null);
++    }
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, ConfigKey<?> config, CatalogConfig annotation) {
++        String label = annotation==null ? null : annotation.label();
++        Double priority = annotation==null ? null : annotation.priority();
++        boolean pinned = annotation!=null && annotation.pinned();
++        return configSummary(utils, ub, entity, config, label, priority, pinned);
++    }
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, ConfigKey<?> config, String label, Double priority, Boolean pinned) {
++        // entity can be null if coming from catalog
++        URI applicationUri = entity==null ? null : serviceUriBuilder(ub, ApplicationApi.class, "get").build(entity.getApplicationId());
++        URI entityUri = entity==null ? null : serviceUriBuilder(ub, EntityApi.class, "get").build(entity.getApplicationId(), entity.getId());
++        URI selfUri = entity==null ? null : serviceUriBuilder(ub, EntityConfigApi.class, "get").build(entity.getApplicationId(), entity.getId(), config.getName());
          
          MutableMap.Builder<String, URI> lb = MutableMap.<String, URI>builder()
--            .put("self", selfUri)
--            .put("application", applicationUri)
--            .put("entity", entityUri)
--            .put("action:json", selfUri);
++            .putIfNotNull("self", selfUri)
++            // TODO wasteful including these on every item as it is just a list, remove
++            .putIfNotNull("application", applicationUri)
++            .putIfNotNull("entity", entityUri)
++            // TODO is this json or a display value?
++            .putIfNotNull("action:json", selfUri);
  
          Iterable<RendererHints.NamedAction> hints = Iterables.filter(RendererHints.getHintsFor(config), RendererHints.NamedAction.class);
          for (RendererHints.NamedAction na : hints) {
--            SensorTransformer.addNamedAction(lb, na, entity.getConfig(config), config, entity);
++            if (entity!=null) {
++                SensorTransformer.addNamedAction(lb, na, entity.getConfig(config), config, entity);
++            }
          }
      
--        return entityConfigSummary(config, label, priority, null, lb.build());
++        return new EntityConfigSummary(config, label, priority, pinned, lb.build());
      }
  
      public static URI applicationUri(Application entity, UriBuilder ub) {
@@@ -188,6 -182,6 +208,8 @@@
          return serviceUriBuilder(ub, EntityApi.class, "get").build(entity.getApplicationId(), entity.getId());
      }
      
++    /** @deprecated since 0.13.0 use {@link #configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, ConfigKey, CatalogConfig) */
++    @Deprecated
      public static EntityConfigSummary entityConfigSummary(ConfigKey<?> config, Field configKeyField) {
          CatalogConfig catalogConfig = configKeyField!=null ? configKeyField.getAnnotation(CatalogConfig.class) : null;
          String label = catalogConfig==null ? null : catalogConfig.label();
@@@ -196,6 -190,6 +218,8 @@@
          return entityConfigSummary(config, label, priority, pinned, null);
      }
  
++    /** @deprecated since 0.13.0 use {@link #configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, ConfigKey, AtomicInteger) */
++    @Deprecated
      public static EntityConfigSummary entityConfigSummary(SpecParameter<?> input, AtomicInteger paramPriorityCnt) {
          // Increment the priority because the config container is a set. Server-side we are using an ordered set
          // which results in correctly ordered items on the wire (as a list). Clients which use the java bindings
@@@ -204,16 -198,17 +228,39 @@@
          return entityConfigSummary(input.getConfigKey(), input.getLabel(), priority, input.isPinned(), null);
      }
  
-     public static AdjunctConfigSummary adjunctConfigSummary(SpecParameter<?> input) {
++    /** @deprecated since 0.13.0 use {@link #configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, SpecParameter) */
++    @Deprecated
+     public static ConfigSummary configSummary(SpecParameter<?> input) {
 -        // could increment priority, or take from annotation, or introduce new field
++        // TODO could increment priority, or take from annotation, or introduce new field
          Double priority = input.isPinned() ? Double.valueOf(1d) : null;
-         return policyConfigSummary(input.getConfigKey(), input.getLabel(), priority, null);
 -        return configSummary(input.getConfigKey(), input.getLabel(), priority, input.isPinned(), null);
++        return new EntityConfigSummary(input.getConfigKey(), input.getLabel(), priority, input.isPinned(), null);
      }
  
++    
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, SpecParameter<?> input, AtomicInteger paramPriorityCnt) {
++        // Increment the priority because the config container is a set. Server-side we are using an ordered set
++        // which results in correctly ordered items on the wire (as a list). Clients which use the java bindings
++        // though will push the items in an unordered set - so give them means to recover the correct order.
++        Double priority = input.isPinned() ? Double.valueOf(paramPriorityCnt.incrementAndGet()) : null;
++        return configSummary(utils, ub, entity, input.getConfigKey(), input.getLabel(), priority, input.isPinned());
++    }
++
++    public static ConfigSummary configSummary(BrooklynRestResourceUtils utils, UriBuilder ub, Entity entity, SpecParameter<?> input) {
++        // TODO allow taking priority from a setting somewhere?
++        // (this just sets priority 1 if no value specified)
++        return configSummary(utils, ub, entity, input, new AtomicInteger(0));
++    }
++
++
++    /** @deprecated since 0.13.0 use {@link AdjunctTransformer#configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, org.apache.brooklyn.api.objs.EntityAdjunct, SpecParameter)} */
++    @Deprecated
      public static PolicyConfigSummary policyConfigSummary(SpecParameter<?> input) {
          Double priority = input.isPinned() ? Double.valueOf(1d) : null;
          return policyConfigSummary(input.getConfigKey(), input.getLabel(), priority, null);
      }
  
++    /** @deprecated since 0.13.0 use {@link AdjunctTransformer#configSummary(BrooklynRestResourceUtils, UriBuilder, Entity, org.apache.brooklyn.api.objs.EntityAdjunct, SpecParameter)} */
++    @Deprecated
      public static EnricherConfigSummary enricherConfigSummary(SpecParameter<?> input) {
          Double priority = input.isPinned() ? Double.valueOf(1d) : null;
          return enricherConfigSummary(input.getConfigKey(), input.getLabel(), priority, null);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java
----------------------------------------------------------------------
diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java
index fb3fdd3,e37ee6a..d081efd
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java
@@@ -50,11 -50,11 +50,10 @@@ import org.apache.brooklyn.core.objs.Br
  import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
  import org.apache.brooklyn.core.typereg.RegisteredTypes;
  import org.apache.brooklyn.rest.api.TypeApi;
- import org.apache.brooklyn.rest.domain.AdjunctConfigSummary;
  import org.apache.brooklyn.rest.domain.BundleInstallationRestResult;
  import org.apache.brooklyn.rest.domain.BundleSummary;
+ import org.apache.brooklyn.rest.domain.ConfigSummary;
  import org.apache.brooklyn.rest.domain.EffectorSummary;
--import org.apache.brooklyn.rest.domain.EntityConfigSummary;
  import org.apache.brooklyn.rest.domain.SensorSummary;
  import org.apache.brooklyn.rest.domain.SummaryComparators;
  import org.apache.brooklyn.rest.domain.TypeDetail;
@@@ -96,14 -96,14 +95,15 @@@ public class TypeTransformer 
                      RegisteredTypes.isSubtypeOf(item, Policy.class) || RegisteredTypes.isSubtypeOf(item, Enricher.class) || RegisteredTypes.isSubtypeOf(item, Feed.class)
                      ) {
                  try {
-                     Set<AdjunctConfigSummary> config = Sets.newLinkedHashSet();
+                     Set<ConfigSummary> config = Sets.newLinkedHashSet();
                      
                      AbstractBrooklynObjectSpec<?,?> spec = b.getTypeRegistry().createSpec(item, null, null);
++                    AtomicInteger priority = new AtomicInteger(0);
                      for (final SpecParameter<?> input : spec.getParameters()){
-                         config.add(EntityTransformer.adjunctConfigSummary(input));
 -                        config.add(EntityTransformer.configSummary(input));
++                        config.add(EntityTransformer.configSummary(null, null, null, input, priority));
                      }
                      
-                     result.getExtraFields().put("config", config);
+                     result.setExtraField("config", config);
                  } catch (Exception e) {
                      Exceptions.propagateIfFatal(e);
                      log.trace("Unable to create spec for "+item+": "+e, e);
@@@ -119,7 -119,7 +119,7 @@@
  
      protected static <T extends TypeSummary> void embellishEntity(T result, RegisteredType item, BrooklynRestResourceUtils b) {
          try {
--            Set<EntityConfigSummary> config = Sets.newLinkedHashSet();
++            Set<ConfigSummary> config = Sets.newLinkedHashSet();
              Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
              Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());
        
@@@ -129,7 -129,7 +129,7 @@@
     
              AtomicInteger paramPriorityCnt = new AtomicInteger();
              for (SpecParameter<?> input: spec.getParameters())
--                config.add(EntityTransformer.entityConfigSummary(input, paramPriorityCnt));
++                config.add(EntityTransformer.configSummary(null, null, null, input, paramPriorityCnt));
              for (Sensor<?> x: type.getSensors())
                  sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
              for (Effector<?> x: type.getEffectors())

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/62bcbc5f/server-cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
----------------------------------------------------------------------
diff --cc server-cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
index f245d06,f245d06..61a7a2a
--- a/server-cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
+++ b/server-cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
@@@ -18,16 -18,16 +18,18 @@@
   */
  package org.apache.brooklyn.cli.lister;
  
--import java.net.URI;
++import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Comparator;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
++import java.util.concurrent.atomic.AtomicInteger;
  
  import org.apache.brooklyn.api.catalog.BrooklynCatalog;
  import org.apache.brooklyn.api.catalog.Catalog;
++import org.apache.brooklyn.api.catalog.CatalogConfig;
  import org.apache.brooklyn.api.catalog.CatalogItem;
  import org.apache.brooklyn.api.effector.Effector;
  import org.apache.brooklyn.api.entity.EntityType;
@@@ -41,8 -41,8 +43,8 @@@ import org.apache.brooklyn.config.Confi
  import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
  import org.apache.brooklyn.core.objs.BrooklynDynamicType;
  import org.apache.brooklyn.core.objs.BrooklynTypes;
++import org.apache.brooklyn.rest.domain.ConfigSummary;
  import org.apache.brooklyn.rest.domain.EffectorSummary;
--import org.apache.brooklyn.rest.domain.EntityConfigSummary;
  import org.apache.brooklyn.rest.domain.SensorSummary;
  import org.apache.brooklyn.rest.domain.SummaryComparators;
  import org.apache.brooklyn.rest.transform.EffectorTransformer;
@@@ -131,12 -131,12 +133,14 @@@ public class ItemDescriptors 
          }
          
          if (!headingsOnly) {
--            Set<EntityConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
++            Set<ConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
              Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
              Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());
  
              for (ConfigKey<?> x: type.getConfigKeys()) {
--                config.add(EntityTransformer.entityConfigSummary(x, dynamicType.getConfigKeyField(x.getName())));
++                Field field = dynamicType.getConfigKeyField(x.getName());
++                CatalogConfig annotation = field==null ? null : field.getAnnotation(CatalogConfig.class);
++                config.add(EntityTransformer.configSummary(null, null, null, x, annotation));
              }
              result.put("config", config);
              
@@@ -184,7 -184,7 +188,7 @@@
      public static Map<String, Object> toItemDescriptor(BrooklynCatalog catalog, CatalogItem<?, ?> item, boolean headingsOnly) {
          Map<String,Object> itemDescriptor = MutableMap.of();
          AbstractBrooklynObjectSpec<?,?> spec = catalog.peekSpec(item);
--        List<EntityConfigSummary> config = new ArrayList<>();
++        List<ConfigSummary> config = new ArrayList<>();
  
          if (item.getDisplayName() != null) {
              itemDescriptor.put("name", item.getDisplayName());
@@@ -199,19 -199,19 +203,9 @@@
          itemDescriptor.put("iconUrl", blankIfNull(item.getIconUrl()));
  
          if (!headingsOnly) {
--            double priorityCounter = 0.0d;
++            AtomicInteger priority = new AtomicInteger(0);
              for (SpecParameter<?> param: spec.getParameters()) {
--                Double priority;
--                if (param.isPinned()) {
--                    priority = priorityCounter;
--                    priorityCounter++;
--                } else {
--                    priority = null;
--                }
--
--                EntityConfigSummary entityConfigSummary = EntityTransformer.entityConfigSummary(param.getConfigKey(),
--                    param.getLabel(), priority, param.isPinned(), MutableMap.<String,URI>of());
--                config.add(entityConfigSummary);
++                config.add(EntityTransformer.configSummary(null, null, null, param, priority));
              }
              itemDescriptor.put("config", config);
          }