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:40 UTC
[03/35] brooklyn-server git commit: add adjunct REST API,
deprecating policy endpoint
add adjunct REST API, deprecating policy endpoint
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/45261c7e
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/45261c7e
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/45261c7e
Branch: refs/heads/master
Commit: 45261c7e155e1022cd172d9816a647ba35f0218c
Parents: 2860af5
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Sep 13 16:22:56 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Sep 13 17:34:53 2017 +0100
----------------------------------------------------------------------
.../org/apache/brooklyn/api/sensor/Feed.java | 2 +-
.../brooklyn/core/entity/AbstractEntity.java | 5 +
.../brooklyn/core/entity/EntityInternal.java | 2 +-
.../apache/brooklyn/core/policy/Policies.java | 30 ++-
.../apache/brooklyn/rest/api/AdjunctApi.java | 233 ++++++++++++++++
.../org/apache/brooklyn/rest/api/PolicyApi.java | 2 +
.../brooklyn/rest/api/PolicyConfigApi.java | 27 +-
.../brooklyn/rest/domain/AdjunctDetail.java | 72 +++++
.../brooklyn/rest/domain/AdjunctSummary.java | 150 +++++++++++
.../rest/domain/CatalogEnricherSummary.java | 2 +
.../rest/domain/CatalogEntitySummary.java | 2 +
.../rest/domain/CatalogItemSummary.java | 2 +
.../rest/domain/CatalogLocationSummary.java | 2 +
.../rest/domain/CatalogPolicySummary.java | 2 +
.../rest/domain/EnricherConfigSummary.java | 3 +-
.../rest/domain/PolicyConfigSummary.java | 3 +-
.../brooklyn/rest/domain/PolicySummary.java | 83 +-----
.../org/apache/brooklyn/rest/domain/Status.java | 7 +-
.../apache/brooklyn/rest/BrooklynRestApi.java | 2 +
.../rest/resources/AdjunctResource.java | 263 +++++++++++++++++++
.../rest/resources/PolicyConfigResource.java | 1 +
.../brooklyn/rest/resources/PolicyResource.java | 1 +
.../rest/transform/AdjunctTransformer.java | 117 +++++++++
.../rest/transform/EntityTransformer.java | 21 ++
.../rest/transform/PolicyTransformer.java | 3 +
.../rest/util/BrooklynRestResourceUtils.java | 43 +++
26 files changed, 983 insertions(+), 97 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/api/src/main/java/org/apache/brooklyn/api/sensor/Feed.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/sensor/Feed.java b/api/src/main/java/org/apache/brooklyn/api/sensor/Feed.java
index d50e092..01a4714 100644
--- a/api/src/main/java/org/apache/brooklyn/api/sensor/Feed.java
+++ b/api/src/main/java/org/apache/brooklyn/api/sensor/Feed.java
@@ -43,7 +43,7 @@ public interface Feed extends EntityAdjunct, Rebindable {
/**
* True if everything has been _started_ (or it is starting) but not stopped,
- * even if it is suspended; see also {@link #isActive()}
+ * even if it is suspended; see also {@link #isRunning()}
*/
boolean isActivated();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 08b6591..8c31512 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -1951,6 +1951,11 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
}
return changed;
}
+
+ @Override
+ public Iterator<Feed> iterator() {
+ return getFeeds().iterator();
+ }
}
// -------- SENSORS --------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/core/src/main/java/org/apache/brooklyn/core/entity/EntityInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityInternal.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityInternal.java
index d6d51a1..7377f38 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityInternal.java
@@ -189,7 +189,7 @@ public interface EntityInternal extends BrooklynObjectInternal, EntityLocal, Reb
void remove(AttributeSensor<?> attribute);
}
- public interface FeedSupport {
+ public interface FeedSupport extends Iterable<Feed> {
Collection<Feed> getFeeds();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/core/src/main/java/org/apache/brooklyn/core/policy/Policies.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/policy/Policies.java b/core/src/main/java/org/apache/brooklyn/core/policy/Policies.java
index db9bece..4b32dfc 100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/Policies.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/Policies.java
@@ -20,7 +20,9 @@ package org.apache.brooklyn.core.policy;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Feed;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
@@ -28,6 +30,8 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.annotations.Beta;
+
import groovy.lang.Closure;
@SuppressWarnings({"rawtypes","unchecked"})
@@ -81,11 +85,27 @@ public class Policies {
}
public static Lifecycle getPolicyStatus(Policy p) {
- if (p.isRunning()) return Lifecycle.RUNNING;
- if (p.isDestroyed()) return Lifecycle.DESTROYED;
- if (p.isSuspended()) return Lifecycle.STOPPED;
- // TODO could policy be in an error state?
- return Lifecycle.CREATED;
+ return inferAdjunctStatus(p);
+ }
+
+ @Beta
+ public static Lifecycle inferAdjunctStatus(EntityAdjunct a) {
+ if (a.isRunning()) return Lifecycle.RUNNING;
+ if (a.isDestroyed()) return Lifecycle.DESTROYED;
+
+ // adjuncts don't currently support an "error" state; though that would be useful!
+
+ if (a instanceof Policy) {
+ if (((Policy)a).isSuspended()) return Lifecycle.STOPPED;
+ return Lifecycle.CREATED;
+ }
+ if (a instanceof Feed) {
+ if (((Feed)a).isSuspended()) return Lifecycle.STOPPED;
+ if (((Feed)a).isActivated()) return Lifecycle.STARTING;
+ return Lifecycle.CREATED;
+ }
+
+ return Lifecycle.STOPPED;
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..5fc1366
--- /dev/null
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/AdjunctApi.java
@@ -0,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.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,
+ responseContainer = "List")
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Could not find application or entity or adjunct")
+ })
+ public List<AdjunctConfigSummary> 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/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
index a698f7d..329c0e1 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
@@ -36,6 +36,8 @@ import java.util.Map;
@Api("Entity Policies")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
+/** @deprecated since 0.12.0 use AdjunctApi */
+@Deprecated
public interface PolicyApi {
@GET
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
index 1e6bfe6..06a4b86 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
@@ -18,23 +18,32 @@
*/
package org.apache.brooklyn.rest.api;
-import io.swagger.annotations.Api;
-import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
+import java.util.List;
+import java.util.Map;
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+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.core.MediaType;
import javax.ws.rs.core.Response;
-import java.util.List;
-import java.util.Map;
+
+import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
+
+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}/policies/{policy}/config")
@Api("Entity Policy Config")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
+/** @deprecated since 0.12.0 use AdjunctApi */
+@Deprecated
public interface PolicyConfigApi {
@GET
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..ddce5f4
--- /dev/null
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctDetail.java
@@ -0,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 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) {
+ 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/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctSummary.java
new file mode 100644
index 0000000..ca80644
--- /dev/null
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/AdjunctSummary.java
@@ -0,0 +1,150 @@
+/*
+ * 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.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
+import org.apache.brooklyn.api.objs.HighlightTuple;
+import org.apache.brooklyn.api.objs.Identifiable;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.google.common.collect.ImmutableMap;
+
+public class AdjunctSummary implements HasName, Serializable, Identifiable {
+
+ private static final long serialVersionUID = -8106551648118942612L;
+
+ private String id;
+ private String name;
+ private BrooklynObjectType adjunctType;
+ @JsonInclude(Include.NON_EMPTY)
+ private String catalogItemId;
+ private Status state;
+ @JsonInclude(Include.NON_EMPTY)
+ private Map<String, HighlightTuple> highlights;
+
+ private Map<String, URI> links;
+
+ // for json
+ protected AdjunctSummary() {}
+
+ public AdjunctSummary(EntityAdjunct a) {
+ id = a.getId();
+ name = a.getDisplayName();
+ adjunctType = BrooklynObjectType.of(a);
+ catalogItemId = a.getCatalogItemId();
+ highlights = a.getHighlights();
+ }
+
+ /** @deprecated since 0.12.0 only for legacy type-specific summary classes */
+ @Deprecated
+ protected AdjunctSummary(
+ String id,
+ String name,
+ BrooklynObjectType adjunctType,
+ String catalogItemId,
+ Status state,
+ Map<String, HighlightTuple> highlights,
+ Map<String, URI> links) {
+ this.id = id;
+ this.name = name;
+ this.adjunctType = adjunctType;
+ this.catalogItemId = catalogItemId;
+ this.state = state;
+ this.highlights = (highlights == null) ? ImmutableMap.of() : ImmutableMap.copyOf(highlights);
+ this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public BrooklynObjectType getAdjunctType() {
+ return adjunctType;
+ }
+
+ public String getCatalogItemId() {
+ return catalogItemId;
+ }
+
+ public Status getState() {
+ return state;
+ }
+
+ public Map<String, HighlightTuple> getHighlights() {
+ return highlights;
+ }
+
+ public Map<String, URI> getLinks() {
+ return links;
+ }
+
+ public AdjunctSummary state(Status state) {
+ this.state = state; return this;
+ }
+
+ public AdjunctSummary links(Map<String, URI> links) {
+ this.links = links; return this;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof AdjunctSummary)) return false;
+ AdjunctSummary that = (AdjunctSummary) o;
+ return Objects.equals(id, that.id) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(adjunctType, that.adjunctType) &&
+ Objects.equals(catalogItemId, that.catalogItemId) &&
+ Objects.equals(state, that.state) &&
+ Objects.equals(highlights, that.highlights) &&
+ Objects.equals(links, that.links) ;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, adjunctType, catalogItemId, state, highlights, links);
+ }
+
+ @Override
+ public String toString() {
+ return (adjunctType!=null ? adjunctType.name() : "AdjunctSummary")+"{" +
+ "id='" + id + '\'' +
+ ", name='" + name + '\'' +
+ ", catalogItemId='" + catalogItemId + '\'' +
+ ", state='" + state + '\'' +
+ ", highlights=" + highlights +
+ ", links=" + links +
+ '}';
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEnricherSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEnricherSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEnricherSummary.java
index 2e81ae1..c655515 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEnricherSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEnricherSummary.java
@@ -27,6 +27,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.ImmutableSet;
+/** @deprecated since 0.12.0 new TypeApi returns TypeSummary */
+@Deprecated
public class CatalogEnricherSummary extends CatalogItemSummary {
private static final long serialVersionUID = -588856488327394445L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEntitySummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEntitySummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEntitySummary.java
index 5947b7f..7dbc1be 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEntitySummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogEntitySummary.java
@@ -27,6 +27,8 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+/** @deprecated since 0.12.0 new TypeApi returns TypeSummary */
+@Deprecated
public class CatalogEntitySummary extends CatalogItemSummary {
private static final long serialVersionUID = 1063908984191424539L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogItemSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogItemSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogItemSummary.java
index cdb86d4..cd85c13 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogItemSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogItemSummary.java
@@ -36,6 +36,8 @@ import com.google.common.collect.ImmutableMap;
* see also, subclasses */
@JsonIgnoreProperties(ignoreUnknown = true)
// ignore unknown, ie properties from subclasses (entity)
+/** @deprecated since 0.12.0 new TypeApi returns TypeSummary */
+@Deprecated
public class CatalogItemSummary implements HasId, HasName, Serializable {
private static final long serialVersionUID = -823483595879417681L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogLocationSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogLocationSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogLocationSummary.java
index 0213a0c..5fb1a4b 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogLocationSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogLocationSummary.java
@@ -26,6 +26,8 @@ import java.util.Set;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableSet;
+/** @deprecated since 0.12.0 new TypeApi returns TypeSummary */
+@Deprecated
public class CatalogLocationSummary extends CatalogItemSummary {
private static final long serialVersionUID = 8420991584336514673L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogPolicySummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogPolicySummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogPolicySummary.java
index 37e5786..ad67786 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogPolicySummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/CatalogPolicySummary.java
@@ -27,6 +27,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.ImmutableSet;
+/** @deprecated since 0.12.0 new TypeApi returns TypeSummary */
+@Deprecated
public class CatalogPolicySummary extends CatalogItemSummary {
private static final long serialVersionUID = -588856488327394445L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EnricherConfigSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EnricherConfigSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EnricherConfigSummary.java
index c868fb8..7b40206 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EnricherConfigSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/EnricherConfigSummary.java
@@ -23,7 +23,8 @@ import java.util.Map;
import org.apache.brooklyn.config.ConfigKey;
-// TODO remove? this class has no value over its super
+/** @deprecated since 0.12.0 new {@link AdjunctConfigSummary}; this class does nothing additional */
+@Deprecated
public class EnricherConfigSummary extends AdjunctConfigSummary {
private static final long serialVersionUID = 4339330833863794513L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
index 5dfb898..797bd0c 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
@@ -23,7 +23,8 @@ import java.util.Map;
import org.apache.brooklyn.config.ConfigKey;
-//TODO remove? this class has no value over its super
+/** @deprecated since 0.12.0 new {@link AdjunctConfigSummary}; this class does nothing additional */
+@Deprecated
public class PolicyConfigSummary extends AdjunctConfigSummary {
private static final long serialVersionUID = 4339330833863794513L;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
index ce9c9e0..da4a86a 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
@@ -18,29 +18,20 @@
*/
package org.apache.brooklyn.rest.domain;
-import java.io.Serializable;
import java.net.URI;
import java.util.Map;
-import java.util.Objects;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.google.common.collect.ImmutableMap;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
import org.apache.brooklyn.api.objs.HighlightTuple;
-public class PolicySummary implements HasName, HasId, Serializable {
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/** @deprecated since 0.12.0 use {@link AdjunctSummary}; this class is identical */
+@Deprecated
+public class PolicySummary extends AdjunctSummary {
private static final long serialVersionUID = -5086680835225136768L;
- private final String id;
- private final String name;
- @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
- private final String catalogItemId;
- private final Status state;
- private final Map<String, URI> links;
- private final Map<String, HighlightTuple> highlights;
-
public PolicySummary(
@JsonProperty("id") String id,
@JsonProperty("name") String name,
@@ -48,67 +39,7 @@ public class PolicySummary implements HasName, HasId, Serializable {
@JsonProperty("state") Status state,
@JsonProperty("highlights") Map<String, HighlightTuple> highlights,
@JsonProperty("links") Map<String, URI> links) {
- this.id = id;
- this.name = name;
- this.catalogItemId = catalogItemId;
- this.state = state;
- this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
- this.highlights = (highlights == null) ? ImmutableMap.of() : ImmutableMap.copyOf(highlights);
- }
-
- @Override
- public String getId() {
- return id;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- public String getCatalogItemId() {
- return catalogItemId;
+ super(id, name, BrooklynObjectType.POLICY, catalogItemId, state, highlights, links);
}
- public Status getState() {
- return state;
- }
-
- public Map<String, URI> getLinks() {
- return links;
- }
-
- public Map<String, HighlightTuple> getHighlights() {
- return highlights;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof PolicySummary)) return false;
- PolicySummary that = (PolicySummary) o;
- return Objects.equals(id, that.id) &&
- Objects.equals(name, that.name) &&
- Objects.equals(catalogItemId, that.catalogItemId) &&
- state == that.state &&
- Objects.equals(highlights, that.highlights) &&
- Objects.equals(links, that.links) ;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, name, catalogItemId, state, highlights, links);
- }
-
- @Override
- public String toString() {
- return "PolicySummary{" +
- "id='" + id + '\'' +
- ", name='" + name + '\'' +
- ", catalogItemId='" + catalogItemId + '\'' +
- ", state=" + state +
- ", highlights=" + highlights +
- ", links=" + links +
- '}';
- }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
index e2b2ce4..4a998c7 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
@@ -18,9 +18,10 @@
*/
package org.apache.brooklyn.rest.domain;
-/**
- * @author Adam Lowe
- */
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+
+/** Canonical set, similar to {@link Lifecycle}, but cleaned up for outside consumption
+ * and more appropriate for adjunct types */
public enum Status {
ACCEPTED,
STARTING,
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
index b3eb4e4..233d717 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.brooklyn.rest.resources.AbstractBrooklynRestResource;
import org.apache.brooklyn.rest.resources.AccessResource;
import org.apache.brooklyn.rest.resources.ActivityResource;
+import org.apache.brooklyn.rest.resources.AdjunctResource;
import org.apache.brooklyn.rest.resources.ApidocResource;
import org.apache.brooklyn.rest.resources.ApplicationResource;
import org.apache.brooklyn.rest.resources.BundleResource;
@@ -63,6 +64,7 @@ public class BrooklynRestApi {
resources.add(new EntityConfigResource());
resources.add(new SensorResource());
resources.add(new EffectorResource());
+ resources.add(new AdjunctResource());
resources.add(new PolicyResource());
resources.add(new PolicyConfigResource());
resources.add(new ActivityResource());
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..9dd4c10
--- /dev/null
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AdjunctResource.java
@@ -0,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.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(
+ 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();
+ for (ConfigKey<?> key : adjunct.config().findKeysPresent(Predicates.alwaysTrue())) {
+ result.add(AdjunctTransformer.configSummary(brooklyn(), entity, adjunct, key, ui.getBaseUriBuilder()));
+ }
+ 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/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
index 6dcdf19..1fca535 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
@@ -41,6 +41,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@HaHotStateRequired
+@Deprecated
public class PolicyConfigResource extends AbstractBrooklynRestResource implements PolicyConfigApi {
@Override
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
index 0b8d2c2..125b0b7 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
@@ -47,6 +47,7 @@ import com.google.common.collect.FluentIterable;
import com.google.common.collect.Maps;
@HaHotStateRequired
+@Deprecated
public class PolicyResource extends AbstractBrooklynRestResource implements PolicyApi {
private static final Logger log = LoggerFactory.getLogger(PolicyResource.class);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
----------------------------------------------------------------------
diff --git 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
new file mode 100644
index 0000000..db7d4cd
--- /dev/null
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/AdjunctTransformer.java
@@ -0,0 +1,117 @@
+/*
+ * 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.ws.rs.core.UriBuilder;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
+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.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.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 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)
+ .build();
+
+ return new AdjunctConfigSummary(config.getName(), config.getTypeName(), config.getDescription(),
+ utils.getStringValueForDisplay(config.getDefaultValue()),
+ config.isReconfigurable(),
+ links);
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/EntityTransformer.java
----------------------------------------------------------------------
diff --git 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
index 6bf3f19..cb7877f 100644
--- 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
@@ -32,10 +32,12 @@ import javax.ws.rs.core.UriBuilder;
import org.apache.brooklyn.api.catalog.CatalogConfig;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.objs.SpecParameter;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
import org.apache.brooklyn.rest.api.ApplicationApi;
import org.apache.brooklyn.rest.api.CatalogApi;
@@ -46,12 +48,15 @@ import org.apache.brooklyn.rest.domain.EnricherConfigSummary;
import org.apache.brooklyn.rest.domain.EntityConfigSummary;
import org.apache.brooklyn.rest.domain.EntitySummary;
import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
+import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
/**
* @author Adam Lowe
@@ -84,6 +89,7 @@ public class EntityTransformer {
.put("config", URI.create(entityUri + "/config"))
.put("sensors", URI.create(entityUri + "/sensors"))
.put("effectors", URI.create(entityUri + "/effectors"))
+ .put("adjuncts", URI.create(entityUri + "/adjuncts"))
.put("policies", URI.create(entityUri + "/policies"))
.put("activities", URI.create(entityUri + "/activities"))
.put("locations", URI.create(entityUri + "/locations"))
@@ -212,4 +218,19 @@ public class EntityTransformer {
Double priority = input.isPinned() ? Double.valueOf(1d) : null;
return enricherConfigSummary(input.getConfigKey(), input.getLabel(), priority, null);
}
+
+ public static Map<String, Object> getConfigValues(BrooklynRestResourceUtils utils, BrooklynObject obj) {
+ // alternatively could do this - should be the same ?
+// for (ConfigKey<?> key: adjunct.config().findKeysPresent(Predicates.alwaysTrue())) {
+// result.config(key.getName(), utils.getStringValueForDisplay( adjunct.config().get(key) ));
+// }
+
+ Map<String, Object> source = ConfigBag.newInstance(
+ ((BrooklynObjectInternal)obj).config().getInternalConfigMap().getAllConfigInheritedRawValuesIgnoringErrors() ).getAllConfig();
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (Map.Entry<String, Object> ek : source.entrySet()) {
+ result.put(ek.getKey(), utils.getStringValueForDisplay(ek.getValue()));
+ }
+ return result;
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java
index 8dad949..294fd41 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/PolicyTransformer.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.policy.Policies;
+import org.apache.brooklyn.rest.domain.AdjunctSummary;
import org.apache.brooklyn.rest.domain.ApplicationSummary;
import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
import org.apache.brooklyn.rest.domain.PolicySummary;
@@ -42,7 +43,9 @@ import static org.apache.brooklyn.rest.util.WebResourceUtils.serviceUriBuilder;
/**
* Converts from Brooklyn entities to restful API summary objects
+ * @deprecated since 0.12.0 use {@link AdjunctTransformer} and {@link AdjunctSummary}
*/
+@Deprecated
public class PolicyTransformer {
public static PolicySummary policySummary(Entity entity, Policy policy, UriBuilder ub) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/45261c7e/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
index 9e1ce53..9b0a3d4 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -38,7 +38,10 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationRegistry;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.Feed;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
@@ -112,6 +115,16 @@ public class BrooklynRestResourceUtils {
public Policy getPolicy(String application, String entity, String policy) {
return getPolicy(getEntity(application, entity), policy);
}
+
+ /** finds the policy indicated by the given ID or name.
+ * @see {@link #getEntity(String,String)}; it then searches the policies of that
+ * entity for one whose ID or name matches that given.
+ * <p>
+ *
+ * @throws 404 or 412 (unless input is null in which case output is null) */
+ public EntityAdjunct getAdjunct(String application, String entity, String adjunct) {
+ return getAdjunct(getEntity(application, entity), adjunct);
+ }
/** finds the policy indicated by the given ID or name.
* @see {@link #getPolicy(String,String,String)}.
@@ -130,6 +143,36 @@ public class BrooklynRestResourceUtils {
throw WebResourceUtils.notFound("Cannot find policy '%s' in entity '%s'", policy, entity);
}
+
+ /** finds the policy indicated by the given ID or name.
+ * @see {@link #getAdjunct(String,String,String)}.
+ * <p>
+ *
+ * @throws 404 or 412 (unless input is null in which case output is null) */
+ public EntityAdjunct getAdjunct(Entity entity, String adjunct) {
+ if (adjunct==null) return null;
+
+ for (Policy p: entity.policies()) {
+ if (adjunct.equals(p.getId())) return p;
+ }
+ for (Policy p: entity.policies()) {
+ if (adjunct.equals(p.getDisplayName())) return p;
+ }
+ for (Enricher p: entity.enrichers()) {
+ if (adjunct.equals(p.getId())) return p;
+ }
+ for (Enricher p: entity.enrichers()) {
+ if (adjunct.equals(p.getDisplayName())) return p;
+ }
+ for (Feed p: ((EntityInternal)entity).feeds()) {
+ if (adjunct.equals(p.getId())) return p;
+ }
+ for (Feed p: ((EntityInternal)entity).feeds()) {
+ if (adjunct.equals(p.getDisplayName())) return p;
+ }
+
+ throw WebResourceUtils.notFound("Cannot find adjunct '%s' in entity '%s'", adjunct, entity);
+ }
/** finds the entity indicated by the given ID or name
* <p>