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