This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new 603680b add rest api methods for modifying entity tags
603680b is described below
commit 603680bc44294ac85562cbd23f1e1a77c92d2393
Author: Alex Heneveld <[email protected]>
AuthorDate: Tue Oct 26 15:59:19 2021 +0100
add rest api methods for modifying entity tags
---
.../apache/brooklyn/core/mgmt/BrooklynTags.java | 12 +++++
.../org/apache/brooklyn/rest/api/EntityApi.java | 57 ++++++++++++++++++++++
.../brooklyn/rest/resources/EntityResource.java | 25 ++++++++++
.../rest/resources/EntityResourceTest.java | 43 +++++++++++++++-
4 files changed, 136 insertions(+), 1 deletion(-)
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java
b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java
index a9188c1..7c13fd0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java
@@ -25,6 +25,7 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.objs.BrooklynObject.TagSupport;
import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
import org.apache.brooklyn.util.collections.MutableList;
@@ -104,6 +105,17 @@ public class BrooklynTags {
}
}
+ public static <T> void upsertSingleKeyMapValueTag(TagSupport tagS, String
key, T value) {
+ MutableList<Object> matchingKeyTags = MutableList.of();
+ tagS.getTags().stream().forEach(t -> {
+ if (isTagSingleKeyMap(t, key)) {
+ matchingKeyTags.add(t);
+ }
+ });
+ matchingKeyTags.forEach(tagS::removeTag);
+ tagS.addTag(MutableMap.of(key, value));
+ }
+
public static NamedStringTag findFirstNamedStringTag(String kind,
Iterable<Object> tags) {
return findFirstOfKind(kind, NamedStringTag.class, tags);
}
diff --git
a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
index 6c35f69..b5dc946 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
@@ -167,6 +167,63 @@ public interface EntityApi {
@ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
@ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId);
+ // this feels too dangerous; see other items
+// @POST
+// @Path("/{entity}/tags")
+// @ApiOperation(value = "Set the tags on this entity (replaces all, use
with care)")
+// @ApiResponses(value = {
+// @ApiResponse(code = 404, message = "Could not find application
or entity")
+// })
+// public void setTags(
+// @ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
+// @ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId,
+// @ApiParam(value = "Tags to set", required = true) List<Object>
tags);
+
+ @POST
+ @Path("/{entity}/tag/add")
+ @ApiOperation(value = "Add a tag on this entity")
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Could not find application or
entity")
+ })
+ public void addTag(
+ @ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId,
+ @ApiParam(value = "Tag to add", required = true) Object tag);
+
+ @POST
+ @Path("/{entity}/tag/delete")
+ @ApiOperation(value = "Delete a tag on this entity, returning whether the
tag was found (and deleted)")
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Could not find application or
entity")
+ })
+ public boolean deleteTag(
+ @ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId,
+ @ApiParam(value = "Tag to delete", required = true) Object tag);
+
+ @POST
+ @Path("/{entity}/tag/upsert/{tagKey}")
+ @ApiOperation(value = "Inserts a tag which is a single-key map with the
given key (path parameter) and value (post body), removing any existing tag
matching the key")
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Could not find application or
entity")
+ })
+ public void upsertTag(
+ @ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("tagKey") String tagKey,
+ @ApiParam(value = "Tag map value to upsert for the given key",
required = true) Object tagValue);
+
+ @GET
+ @Path("/{entity}/tag/get/{tagKey}")
+ @ApiOperation(value = "Returns the tag value for a tag which is a
single-key map with the given key, or null (not 404 for missing tag key)")
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Could not find application or
entity")
+ })
+ public Object getTag(
+ @ApiParam(value = "Application ID or name", required = true)
@PathParam("application") String applicationId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("entity") String entityId,
+ @ApiParam(value = "Entity ID or name", required = true)
@PathParam("tagKey") String tagKey);
+
@POST
@ApiOperation(
value = "Rename an entity"
diff --git
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
index a068402..dc17a21 100644
---
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
+++
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.rest.resources;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.status;
import static javax.ws.rs.core.Response.Status.ACCEPTED;
+import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTags.SpecSummary;
import static
org.apache.brooklyn.rest.util.WebResourceUtils.serviceAbsoluteUriBuilder;
@@ -257,6 +258,30 @@ public class EntityResource extends
AbstractBrooklynRestResource implements Enti
}
@Override
+ public void addTag(String applicationId, String entityId, Object tag) {
+ Entity entity = brooklyn().getEntity(applicationId, entityId);
+ entity.tags().addTag(tag);
+ }
+
+ @Override
+ public boolean deleteTag(String applicationId, String entityId, Object
tag) {
+ Entity entity = brooklyn().getEntity(applicationId, entityId);
+ return entity.tags().removeTag(tag);
+ }
+
+ @Override
+ public void upsertTag(String applicationId, String entityId, String
tagKey, Object tagValue) {
+ Entity entity = brooklyn().getEntity(applicationId, entityId);
+ BrooklynTags.upsertSingleKeyMapValueTag(entity.tags(), tagKey,
tagValue);
+ }
+
+ @Override
+ public Object getTag(String applicationId, String entityId, String tagKey)
{
+ Entity entity = brooklyn().getEntity(applicationId, entityId);
+ return BrooklynTags.findSingleKeyMapValue(tagKey, Object.class,
entity.tags().getTags());
+ }
+
+ @Override
public Response getIcon(String applicationId, String entityId) {
Entity entity = brooklyn().getEntity(applicationId, entityId);
String url = RegisteredTypes.getIconUrl(entity);
diff --git
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EntityResourceTest.java
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EntityResourceTest.java
index 59af350..00e41d3 100644
---
a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EntityResourceTest.java
+++
b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/EntityResourceTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.brooklyn.rest.resources;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
import static org.testng.Assert.assertEquals;
import java.util.Collection;
@@ -227,5 +229,44 @@ public class EntityResourceTest extends
BrooklynRestResourceTest {
Assert.assertEquals( ((Entity)appTag).getId(),
entity.getApplicationId(), "Wrong ID: "+appTag);
Assert.assertTrue(appTag instanceof BasicApplication, "Should have
deserialized BasicApplication: "+appTag);
}
-
+
+ @Test
+ public void testTagsChangingViaRest() throws Exception {
+ entity.tags().addTag("foo");
+
+ Response response;
+
+ response = client().path(entityEndpoint +
"/tag/add").accept(MediaType.APPLICATION_JSON).post(toJsonEntity("bar"));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+
+ response = client().path(entityEndpoint +
"/tag/add").accept(MediaType.APPLICATION_JSON).post(toJsonEntity(MutableMap.of("baz_key",
"baz_value")));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+
+ String raw;
+ response = client().path(entityEndpoint +
"/tags").accept(MediaType.APPLICATION_JSON).get();
+ raw = response.readEntity(String.class);
+ log.info("TAGS raw: "+raw);
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+ Asserts.assertStringContains(raw, "foo");
+ Asserts.assertStringContains(raw, "bar");
+ Asserts.assertStringContains(raw, "baz_key", "baz_value");
+
+ response = client().path(entityEndpoint +
"/tag/upsert/baz_key").accept(MediaType.APPLICATION_JSON).post(toJsonEntity("baz2_value"));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+ response = client().path(entityEndpoint +
"/tags").accept(MediaType.APPLICATION_JSON).get();
+ raw = response.readEntity(String.class);
+ Asserts.assertStringContains(raw, "baz_key", "baz2_value");
+ Asserts.assertStringDoesNotContain(raw, "baz_value");
+
+ response = client().path(entityEndpoint +
"/tag/delete").accept(MediaType.APPLICATION_JSON).post(toJsonEntity("bar"));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+ response = client().path(entityEndpoint +
"/tag/delete").accept(MediaType.APPLICATION_JSON).post(toJsonEntity(MutableMap.of("baz_key",
"baz2_value")));
+ HttpAsserts.assertHealthyStatusCode(response.getStatus());
+ response = client().path(entityEndpoint +
"/tags").accept(MediaType.APPLICATION_JSON).get();
+ raw = response.readEntity(String.class);
+ Asserts.assertStringDoesNotContain(raw, "bar");
+ Asserts.assertStringDoesNotContain(raw, "baz_key");
+ Asserts.assertStringContains(raw, "foo");
+ }
+
}