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 2014/12/15 17:57:32 UTC
[5/9] incubator-brooklyn git commit: REST API support for setting
multiple sensors or config with a map
REST API support for setting multiple sensors or config with a map
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/25dccf0f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/25dccf0f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/25dccf0f
Branch: refs/heads/master
Commit: 25dccf0fed5186bd78b3090282a9e897dd7715a5
Parents: 7c0e0bd
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Nov 28 09:21:17 2014 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Dec 12 13:54:55 2014 +0000
----------------------------------------------------------------------
.../java/brooklyn/rest/api/EntityConfigApi.java | 18 +++-
.../main/java/brooklyn/rest/api/SensorApi.java | 14 +++
.../rest/resources/EntityConfigResource.java | 27 +++++-
.../brooklyn/rest/resources/SensorResource.java | 21 +++++
.../resources/EntityConfigResourceTest.java | 93 ++++++++++++++++----
.../rest/resources/SensorResourceTest.java | 16 ++++
6 files changed, 169 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
index 76dd25d..7c576bf 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/EntityConfigApi.java
@@ -104,6 +104,22 @@ public interface EntityConfigApi {
);
@POST
+ @ApiOperation(value = "Manually set multiple config values")
+ @ApiErrors(value = {
+ @ApiError(code = 404, reason = "Could not find application or entity")
+ })
+ public void setFromMap(
+ @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 = "Apply the config to all pre-existing descendants", required = false)
+ @QueryParam("recurse") @DefaultValue("false") final Boolean recurse,
+ @ApiParam(value = "Map of config key names to values", required = true)
+ Map<?,?> newValues
+ ) ;
+
+ @POST
@Path("/{config}")
@ApiOperation(value = "Manually set a config value")
@ApiErrors(value = {
@@ -117,7 +133,7 @@ public interface EntityConfigApi {
@ApiParam(value = "Config key name", required = true)
@PathParam("config") String configName,
@ApiParam(value = "Apply the config to all pre-existing descendants", required = false)
- @QueryParam("raw") @DefaultValue("false") final Boolean recurse,
+ @QueryParam("recurse") @DefaultValue("false") final Boolean recurse,
@ApiParam(value = "Value to set")
Object newValue
) ;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-api/src/main/java/brooklyn/rest/api/SensorApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/SensorApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/SensorApi.java
index 349da5a..982aa52 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/SensorApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/SensorApi.java
@@ -109,6 +109,20 @@ public interface SensorApi {
) ;
@POST
+ @ApiOperation(value = "Manually set multiple sensor values")
+ @ApiErrors(value = {
+ @ApiError(code = 404, reason = "Could not find application or entity")
+ })
+ public void setFromMap(
+ @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 = "Map of sensor names to values", required = true)
+ Map<?,?> newValues
+ ) ;
+
+ @POST
@Path("/{sensor}")
@ApiOperation(value = "Manually set a sensor value")
@ApiErrors(value = {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
index e5e2aac..66c1ef7 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
@@ -89,7 +89,7 @@ public class EntityConfigResource extends AbstractBrooklynRestResource implement
@Override
public String getPlain(String application, String entityToken, String configKeyName, Boolean raw) {
- return Strings.toString(get(true, application, entityToken, configKeyName, raw));
+ return Strings.toString(get(false, application, entityToken, configKeyName, raw));
}
public Object get(boolean preferJson, String application, String entityToken, String configKeyName, Boolean raw) {
@@ -110,6 +110,31 @@ public class EntityConfigResource extends AbstractBrooklynRestResource implement
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
+ public void setFromMap(String application, String entityToken, Boolean recurse, Map<?, ?> newValues) {
+ final EntityLocal entity = brooklyn().getEntity(application, entityToken);
+ if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
+ throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'",
+ Entitlements.getEntitlementContext().user(), entity);
+ }
+
+ if (LOG.isDebugEnabled())
+ LOG.debug("REST user "+Entitlements.getEntitlementContext()+" setting configs "+newValues);
+ for (Map.Entry<?,?> entry: newValues.entrySet()) {
+ String configName = Strings.toString(entry.getKey());
+ Object newValue = entry.getValue();
+
+ ConfigKey ck = findConfig(entity, configName);
+ ((EntityInternal) entity).setConfig(ck, TypeCoercions.coerce(newValue, ck.getTypeToken()));
+ if (Boolean.TRUE.equals(recurse)) {
+ for (Entity e2: Entities.descendants(entity, Predicates.alwaysTrue(), false)) {
+ ((EntityInternal) e2).setConfig(ck, newValue);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
public void set(String application, String entityToken, String configName, Boolean recurse, Object newValue) {
final EntityLocal entity = brooklyn().getEntity(application, entityToken);
if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
index fedd60d..987a995 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
@@ -38,6 +38,7 @@ import brooklyn.rest.api.SensorApi;
import brooklyn.rest.domain.SensorSummary;
import brooklyn.rest.transform.SensorTransformer;
import brooklyn.rest.util.WebResourceUtils;
+import brooklyn.util.text.Strings;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
@@ -103,7 +104,27 @@ public class SensorResource extends AbstractBrooklynRestResource implements Sens
if (s instanceof AttributeSensor) return (AttributeSensor<?>) s;
return new BasicAttributeSensor<Object>(Object.class, name);
}
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public void setFromMap(String application, String entityToken, Map<?, ?> newValues) {
+ final EntityLocal entity = brooklyn().getEntity(application, entityToken);
+ if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
+ throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'",
+ Entitlements.getEntitlementContext().user(), entity);
+ }
+ if (log.isDebugEnabled())
+ log.debug("REST user "+Entitlements.getEntitlementContext()+" setting sensors "+newValues);
+ for (Map.Entry<?,?> entry: newValues.entrySet()) {
+ String sensorName = Strings.toString(entry.getKey());
+ Object newValue = entry.getValue();
+
+ AttributeSensor sensor = findSensor(entity, sensorName);
+ entity.setAttribute(sensor, newValue);
+ }
+ }
+
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void set(String application, String entityToken, String sensorName, Object newValue) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
index 1f18f60..af8ca5d 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityConfigResourceTest.java
@@ -18,11 +18,33 @@
*/
package brooklyn.rest.resources;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityPredicates;
import brooklyn.rest.domain.ApplicationSpec;
import brooklyn.rest.domain.EntityConfigSummary;
import brooklyn.rest.domain.EntitySpec;
import brooklyn.rest.testing.BrooklynRestResourceTest;
import brooklyn.rest.testing.mocks.RestMockSimpleEntity;
+import brooklyn.util.collections.MutableMap;
+
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
@@ -30,26 +52,13 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import javax.annotation.Nullable;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
@Test(singleThreaded = true)
public class EntityConfigResourceTest extends BrooklynRestResourceTest {
private final static Logger log = LoggerFactory.getLogger(EntityConfigResourceTest.class);
- private URI application;
+ private URI applicationUri;
+ private EntityInternal entity;
@BeforeClass(alwaysRun = true)
@Override
@@ -65,9 +74,11 @@ public class EntityConfigResourceTest extends BrooklynRestResourceTest {
ClientResponse response = clientDeploy(simpleSpec);
int status = response.getStatus();
assertTrue(status >= 200 && status <= 299, "expected HTTP Response of 2xx but got " + status);
- application = response.getLocation();
+ applicationUri = response.getLocation();
log.debug("Built app: application");
- waitForApplicationToBeRunning(application);
+ waitForApplicationToBeRunning(applicationUri);
+
+ entity = (EntityInternal) Iterables.find(getManagementContext().getEntityManager().getEntities(), EntityPredicates.displayNameEqualTo("simple-ent"));
}
@Test
@@ -106,11 +117,57 @@ public class EntityConfigResourceTest extends BrooklynRestResourceTest {
}
@Test
- public void testGet() throws Exception {
+ public void testGetJson() throws Exception {
String configValue = client().resource(
URI.create("/v1/applications/simple-app/entities/simple-ent/config/install.version"))
+ .accept(MediaType.APPLICATION_JSON_TYPE)
.get(String.class);
assertEquals(configValue, "\"1.0.0\"");
}
+ @Test
+ public void testGetPlain() throws Exception {
+ String configValue = client().resource(
+ URI.create("/v1/applications/simple-app/entities/simple-ent/config/install.version"))
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .get(String.class);
+ assertEquals(configValue, "1.0.0");
+ }
+
+ @Test
+ public void testSet() throws Exception {
+ try {
+ String uri = "/v1/applications/simple-app/entities/simple-ent/config/"+
+ RestMockSimpleEntity.SAMPLE_CONFIG.getName();
+ ClientResponse response = client().resource(uri)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, "\"hello world\"");
+ assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+
+ assertEquals(entity.getConfig(RestMockSimpleEntity.SAMPLE_CONFIG), "hello world");
+
+ String value = client().resource(uri).accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
+ assertEquals(value, "\"hello world\"");
+
+ } finally { entity.setConfig(RestMockSimpleEntity.SAMPLE_CONFIG, RestMockSimpleEntity.SAMPLE_CONFIG.getDefaultValue()); }
+ }
+
+ @Test
+ public void testSetFromMap() throws Exception {
+ try {
+ String uri = "/v1/applications/simple-app/entities/simple-ent/config";
+ ClientResponse response = client().resource(uri)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, MutableMap.of(
+ RestMockSimpleEntity.SAMPLE_CONFIG.getName(), "hello world"));
+ assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+
+ assertEquals(entity.getConfig(RestMockSimpleEntity.SAMPLE_CONFIG), "hello world");
+
+ String value = client().resource(uri+"/"+RestMockSimpleEntity.SAMPLE_CONFIG.getName()).accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
+ assertEquals(value, "\"hello world\"");
+
+ } finally { entity.setConfig(RestMockSimpleEntity.SAMPLE_CONFIG, RestMockSimpleEntity.SAMPLE_CONFIG.getDefaultValue()); }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/25dccf0f/usage/rest-server/src/test/java/brooklyn/rest/resources/SensorResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/SensorResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/SensorResourceTest.java
index bb80035..6d074c0 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/SensorResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/SensorResourceTest.java
@@ -41,6 +41,7 @@ import brooklyn.rest.domain.EntitySpec;
import brooklyn.rest.testing.BrooklynRestResourceTest;
import brooklyn.rest.testing.mocks.RestMockSimpleEntity;
import brooklyn.test.HttpTestUtils;
+import brooklyn.util.collections.MutableMap;
import brooklyn.util.stream.Streams;
import brooklyn.util.text.StringFunctions;
@@ -233,12 +234,27 @@ public class SensorResourceTest extends BrooklynRestResourceTest {
.post(ClientResponse.class, 67890);
assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+ assertEquals(entity.getAttribute(SENSOR), (Integer)67890);
+
String value = client().resource(SENSORS_ENDPOINT + "/" + SENSOR_NAME).accept(MediaType.TEXT_PLAIN_TYPE).get(String.class);
assertEquals(value, "67890 frogs");
} finally { addAmphibianSensor(entity); }
}
+ @Test
+ public void testSetFromMap() throws Exception {
+ try {
+ ClientResponse response = client().resource(SENSORS_ENDPOINT)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, MutableMap.of(SENSOR_NAME, 67890));
+ assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+
+ assertEquals(entity.getAttribute(SENSOR), (Integer)67890);
+
+ } finally { addAmphibianSensor(entity); }
+ }
+
/** Check we can delete a value */
@Test
public void testDelete() throws Exception {