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/07/18 18:37:40 UTC

[1/6] git commit: Added entity initializers for HttpRequestSensors. Polling over a URI and retrieving a single JSON value from the response.

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 4fa68908b -> 82f850665


Added entity initializers for HttpRequestSensors. Polling over a URI and retrieving a single JSON value from the response.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/7a288158
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/7a288158
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/7a288158

Branch: refs/heads/master
Commit: 7a2881581e006f0f87b1eeedaea16dbf707e84fa
Parents: bcdf42c
Author: Miguel Barrientos <mb...@lcc.uma.es>
Authored: Wed Jul 2 09:33:30 2014 +0200
Committer: Miguel Barrientos <mb...@lcc.uma.es>
Committed: Mon Jul 14 18:25:51 2014 +0200

----------------------------------------------------------------------
 .../event/feed/http/HttpValueFunctions.java     |  8 +--
 .../entity/software/http/HttpRequestSensor.java | 63 ++++++++++++++++++++
 .../entity/software/HttpRequestSensorTest.java  | 63 ++++++++++++++++++++
 3 files changed, 130 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7a288158/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
index cc7db00..0981b0e 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
@@ -42,7 +42,7 @@ public class HttpValueFunctions {
     }
 
     public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int expected) {
-        return chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.equalTo(expected)));
+        return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.equalTo(expected)));
     }
     
     public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int... expected) {
@@ -50,7 +50,7 @@ public class HttpValueFunctions {
         for (int e : expected) {
             expectedList.add((Integer)e);
         }
-        return chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.in(expectedList)));
+        return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.in(expectedList)));
     }
     
     public static Function<HttpToolResponse, String> stringContentsFunction() {
@@ -62,7 +62,7 @@ public class HttpValueFunctions {
     }
     
     public static Function<HttpToolResponse, JsonElement> jsonContents() {
-        return chain(stringContentsFunction(), JsonFunctions.asJson());
+        return Functionals.chain(stringContentsFunction(), JsonFunctions.asJson());
     }
     
     public static <T> Function<HttpToolResponse, T> jsonContents(String element, Class<T> expected) {
@@ -70,7 +70,7 @@ public class HttpValueFunctions {
     }
     
     public static <T> Function<HttpToolResponse, T> jsonContents(String[] elements, Class<T> expected) {
-        return chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
+        return Functionals.chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
     }
     
     public static Function<HttpToolResponse, Long> latency() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7a288158/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
new file mode 100644
index 0000000..8cc04f9
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
@@ -0,0 +1,63 @@
+package brooklyn.entity.software.http;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.effector.AddSensor;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.feed.http.HttpFeed;
+import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.event.feed.http.HttpValueFunctions;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.time.Duration;
+import com.google.common.base.Preconditions;
+import com.jayway.jsonpath.JsonPath;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * Configurable {@link brooklyn.entity.proxying.EntityInitializer} which adds an HTTP sensor feed to retrieve the
+ * <code>JSONObject</code> from a JSON response in order to populate the sensor with the indicated <code>name</code>.
+ */
+// generics introduced here because we might support a configurable 'targetType` parameter in future, 
+// with automatic casting (e.g. for ints); this way it remains compatible
+public final class HttpRequestSensor<T extends String> extends AddSensor<String, AttributeSensor<String>> {
+
+    private static final org.slf4j.Logger log = LoggerFactory.getLogger(HttpRequestSensor.class);
+
+    public static final ConfigKey<String> JSON_PATH = ConfigKeys.newStringConfigKey("jsonPath");
+    public static final ConfigKey<String> SENSOR_URI = ConfigKeys.newStringConfigKey("uri");
+
+    String jsonPath;
+    String uri;
+
+    public HttpRequestSensor(ConfigBag params) {
+        super(newSensor(String.class, params));
+        jsonPath = Preconditions.checkNotNull(params.get(JSON_PATH), JSON_PATH);
+        uri = Preconditions.checkNotNull(params.get(SENSOR_URI), SENSOR_URI);
+    }
+
+    @Override
+    public void apply(final EntityLocal entity) {
+        super.apply(entity);
+
+        Duration period = Duration.ONE_SECOND;
+
+        HttpPollConfig<String> pollConfig = new HttpPollConfig<String>(sensor)
+                .onSuccess(HttpValueFunctions.jsonContents(jsonPath, String.class));
+
+        if (period != null) pollConfig.period(period);
+
+        HttpFeed.builder().entity(entity)
+                .baseUri(uri)
+                .poll(pollConfig)
+                .build();
+
+        log.info("HTTPRequestSensor: " + uri + " -> " + jsonPath);
+    }
+
+    public HttpRequestSensor(Map<String, String> params) {
+        this(ConfigBag.newInstance(params));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7a288158/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
new file mode 100644
index 0000000..1ea5f48
--- /dev/null
+++ b/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
@@ -0,0 +1,63 @@
+package brooklyn.entity.software;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.software.http.HttpRequestSensor;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.location.Location;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.config.ConfigBag;
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static brooklyn.test.Asserts.succeedsEventually;
+
+public class HttpRequestSensorTest {
+    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+    final static AttributeSensor<String> SENSOR_JSON_OBJECT = Sensors.newStringSensor("aJSONObject","");
+    final static AttributeSensor<String> SENSOR_URI = Sensors.newStringSensor("uri","");
+
+    private TestApplication app;
+    private EntityLocal entity;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(app.newLocalhostProvisioningLocation().obtain()));
+        app.start(ImmutableList.<Location>of());
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+    }
+
+    @Test(groups="Integration")
+    public void testHttpSensor() throws Exception {
+        new HttpRequestSensor<String>(ConfigBag.newInstance()
+                .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
+                .configure(HttpRequestSensor.JSON_PATH, "myKey")
+                .configure(HttpRequestSensor.SENSOR_URI, "http://echo.jsontest.com/myKey/myValue"))
+            .apply(entity);
+        entity.setAttribute(Attributes.SERVICE_UP, true);
+
+        succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null);
+            }
+        });
+
+        String val = entity.getAttribute(SENSOR_STRING);
+        assertEquals(val, "myValue", "val=" + val);
+    }
+}


[5/6] git commit: Target type made optional, default to String Support for convenience type names.

Posted by he...@apache.org.
Target type made optional, default to String
Support for convenience type names.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/61c4e993
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/61c4e993
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/61c4e993

Branch: refs/heads/master
Commit: 61c4e993da5d796935045aeddb95f8daf2d76c9b
Parents: de5991c
Author: Miguel Barrientos <mb...@lcc.uma.es>
Authored: Thu Jul 17 17:03:32 2014 +0200
Committer: Miguel Barrientos <mb...@lcc.uma.es>
Committed: Thu Jul 17 17:06:33 2014 +0200

----------------------------------------------------------------------
 .../brooklyn/entity/effector/AddSensor.java     | 26 +++++++++++++++++---
 1 file changed, 22 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/61c4e993/core/src/main/java/brooklyn/entity/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/effector/AddSensor.java b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
index 4c2f1ed..8043c64 100644
--- a/core/src/main/java/brooklyn/entity/effector/AddSensor.java
+++ b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
@@ -43,9 +43,7 @@ public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
     protected final T sensor;
     public static final ConfigKey<String> SENSOR_NAME = ConfigKeys.newStringConfigKey("name");
     public static final ConfigKey<Duration> SENSOR_PERIOD = ConfigKeys.newConfigKey(Duration.class, "period", "Period, including units e.g. 1m or 5s or 200ms");
-    
-    // TODO
-    public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType");
+    public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType", "Target type for the value", "string");
 
     public AddSensor(T sensor) {
         this.sensor = Preconditions.checkNotNull(sensor, "sensor");
@@ -63,7 +61,7 @@ public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
 
     public static <T> AttributeSensor<T> newSensor(ConfigBag params) {
         String name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "name must be supplied when defining a sensor");
-        String className = Preconditions.checkNotNull(params.get(SENSOR_TYPE), "target class must be supplied when defining a sensor");
+        String className = getFullClassName(params.get(SENSOR_TYPE));
         Class<T> type = null;
 
         try {
@@ -74,4 +72,24 @@ public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
         return Sensors.newSensor(type, name);
     }
 
+    private static String getFullClassName(String className) {
+        if(className.equalsIgnoreCase("string")){
+            return "java.lang.String";
+        }else if(className.equalsIgnoreCase("int") || className.equalsIgnoreCase("integer")){
+            return "java.lang.Integer";
+        }else if(className.equalsIgnoreCase("long")){
+            return "java.lang.Long";
+        }else if(className.equalsIgnoreCase("float")){
+            return "java.lang.Float";
+        }else if(className.equalsIgnoreCase("double")){
+            return "java.lang.Double";
+        }else if(className.equalsIgnoreCase("bool") || className.equalsIgnoreCase("boolean")){
+            return "java.lang.Boolean";
+        }else if(className.equalsIgnoreCase("object")){
+            return "java.lang.Object";
+        }else{
+            return className;
+        }
+    }
+
 }


[6/6] git commit: This closes #48

Posted by he...@apache.org.
This closes #48


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/82f85066
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/82f85066
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/82f85066

Branch: refs/heads/master
Commit: 82f8506654c5a1893da0a3c73dde1ede8aa56ee5
Parents: 4fa6890 61c4e99
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 12:36:57 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:36:57 2014 -0400

----------------------------------------------------------------------
 core/pom.xml                                    |  5 ++
 .../brooklyn/entity/effector/AddSensor.java     | 53 ++++++++++++----
 .../event/feed/http/HttpValueFunctions.java     | 12 ++--
 .../brooklyn/event/feed/http/JsonFunctions.java | 22 +++++--
 .../event/feed/http/JsonFunctionsTest.java      | 16 +++++
 pom.xml                                         |  1 +
 .../entity/software/http/HttpRequestSensor.java | 63 ++++++++++++++++++++
 .../software/http/HttpRequestSensorTest.java    | 55 +++++++++++++++++
 8 files changed, 208 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/82f85066/core/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/82f85066/pom.xml
----------------------------------------------------------------------


[2/6] git commit: Add support for json-path (https://code.google.com/p/json-path) for full access to json response

Posted by he...@apache.org.
Add support for json-path (https://code.google.com/p/json-path) for full access to json response

Moved test to new package

Refactoring to avoid removing functionality:
now it supports both full path with JSONPath (through HttpValueFunctions.jsonContentsFromPath) and 1-level json element only.

rebased minor commits


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

Branch: refs/heads/master
Commit: a2f8f655efdb869c8cd3098011e6dd6e3aa98ac0
Parents: 7a28815
Author: Miguel Barrientos <mb...@lcc.uma.es>
Authored: Sat Jul 5 02:18:07 2014 +0200
Committer: Miguel Barrientos <mb...@lcc.uma.es>
Committed: Mon Jul 14 18:26:44 2014 +0200

----------------------------------------------------------------------
 core/pom.xml                                    |  5 ++
 .../event/feed/http/HttpValueFunctions.java     |  4 ++
 .../brooklyn/event/feed/http/JsonFunctions.java | 21 ++++++-
 pom.xml                                         |  1 +
 .../entity/software/http/HttpRequestSensor.java |  8 +--
 .../entity/software/HttpRequestSensorTest.java  | 63 --------------------
 .../software/http/HttpRequestSensorTest.java    | 62 +++++++++++++++++++
 7 files changed, 95 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 5c292de..e2b858a 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -163,6 +163,11 @@
             <version>${jetty.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path</artifactId>
+            <version>${jsonPath.version}</version>
+        </dependency>
     </dependencies>
 
   <!-- add maxmind geo-ip library; exact copy of source included as required by LGPL2 -->

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
index 0981b0e..800368d 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
@@ -72,6 +72,10 @@ public class HttpValueFunctions {
     public static <T> Function<HttpToolResponse, T> jsonContents(String[] elements, Class<T> expected) {
         return Functionals.chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
     }
+
+    public static <T> Function<HttpToolResponse, T> jsonContentsFromPath(String element, Class<T> expected){
+        return Functionals.chain(jsonContents(), JsonFunctions.getPath(element), JsonFunctions.cast(expected));
+    }
     
     public static Function<HttpToolResponse, Long> latency() {
         return new Function<HttpToolResponse, Long>() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java b/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
index b9c3eee..5f5da44 100644
--- a/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
@@ -38,6 +38,7 @@ import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import com.jayway.jsonpath.JsonPath;
 
 public class JsonFunctions {
 
@@ -80,14 +81,14 @@ public class JsonFunctions {
     public static Function<JsonElement, JsonElement> walk(final Iterable<String> elements) {
         // could do this instead, pointing at Maybe for this, and for walkN, but it's slightly less efficient
 //      return Functionals.chain(MaybeFunctions.<JsonElement>wrap(), walkM(elements), MaybeFunctions.<JsonElement>get());
-        
+
         return new Function<JsonElement, JsonElement>() {
             @Override public JsonElement apply(JsonElement input) {
                 JsonElement curr = input;
                 for (String element : elements) {
                     JsonObject jo = curr.getAsJsonObject();
                     curr = jo.get(element);
-                    if (curr==null) 
+                    if (curr==null)
                         throw new NoSuchElementException("No element '"+element+" in JSON, when walking "+elements);
                 }
                 return curr;
@@ -150,6 +151,22 @@ public class JsonFunctions {
         };
     }
 
+    /**
+     * returns an element from a json object given a full path {@link com.jayway.jsonpath.JsonPath}
+     */
+    public static Function<JsonElement,? extends JsonElement> getPath(final String element) {
+        return new Function<JsonElement, JsonElement>() {
+            @Override public JsonElement apply(JsonElement input) {
+                String jsonString = input.toString();
+                JsonParser jsonParser = new JsonParser();
+                JsonElement curr = jsonParser.parse(JsonPath.<String>read(jsonString, element));
+                if (curr==null)
+                    throw new NoSuchElementException("No element '"+element+" in JSON);");
+                return curr;
+            }
+        };
+    }
+
     @SuppressWarnings("unchecked")
     public static <T> Function<JsonElement, T> cast(final Class<T> expected) {
         return new Function<JsonElement, T>() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index df490aa..70c63bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -141,6 +141,7 @@
         <osgi-core.version>4.3.0</osgi-core.version>
         <commons-io.version>2.4</commons-io.version>
         <hazelcast.version>3.0</hazelcast.version>
+        <jsonPath.version>0.9.1</jsonPath.version>
         <commons-lang3.version>3.1</commons-lang3.version>
         <commons-compress.version>1.4</commons-compress.version>
         <qpid.version>0.20</qpid.version>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
index 8cc04f9..1ae08dc 100644
--- a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
+++ b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
@@ -10,8 +10,8 @@ import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.time.Duration;
+import com.google.common.base.Functions;
 import com.google.common.base.Preconditions;
-import com.jayway.jsonpath.JsonPath;
 import org.slf4j.LoggerFactory;
 
 import java.util.Map;
@@ -45,7 +45,9 @@ public final class HttpRequestSensor<T extends String> extends AddSensor<String,
         Duration period = Duration.ONE_SECOND;
 
         HttpPollConfig<String> pollConfig = new HttpPollConfig<String>(sensor)
-                .onSuccess(HttpValueFunctions.jsonContents(jsonPath, String.class));
+                .checkSuccess(HttpValueFunctions.responseCodeEquals(200))
+                .onFailureOrException(Functions.constant((String) null))
+                .onSuccess(HttpValueFunctions.jsonContentsFromPath(jsonPath, String.class));
 
         if (period != null) pollConfig.period(period);
 
@@ -53,8 +55,6 @@ public final class HttpRequestSensor<T extends String> extends AddSensor<String,
                 .baseUri(uri)
                 .poll(pollConfig)
                 .build();
-
-        log.info("HTTPRequestSensor: " + uri + " -> " + jsonPath);
     }
 
     public HttpRequestSensor(Map<String, String> params) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
deleted file mode 100644
index 1ea5f48..0000000
--- a/software/base/src/test/java/brooklyn/entity/software/HttpRequestSensorTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package brooklyn.entity.software;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.software.http.HttpRequestSensor;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.test.entity.TestApplication;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.util.config.ConfigBag;
-import com.google.common.collect.ImmutableList;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertEquals;
-import static brooklyn.test.Asserts.succeedsEventually;
-
-public class HttpRequestSensorTest {
-    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
-    final static AttributeSensor<String> SENSOR_JSON_OBJECT = Sensors.newStringSensor("aJSONObject","");
-    final static AttributeSensor<String> SENSOR_URI = Sensors.newStringSensor("uri","");
-
-    private TestApplication app;
-    private EntityLocal entity;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(app.newLocalhostProvisioningLocation().obtain()));
-        app.start(ImmutableList.<Location>of());
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test(groups="Integration")
-    public void testHttpSensor() throws Exception {
-        new HttpRequestSensor<String>(ConfigBag.newInstance()
-                .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
-                .configure(HttpRequestSensor.JSON_PATH, "myKey")
-                .configure(HttpRequestSensor.SENSOR_URI, "http://echo.jsontest.com/myKey/myValue"))
-            .apply(entity);
-        entity.setAttribute(Attributes.SERVICE_UP, true);
-
-        succeedsEventually(new Runnable() {
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null);
-            }
-        });
-
-        String val = entity.getAttribute(SENSOR_STRING);
-        assertEquals(val, "myValue", "val=" + val);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a2f8f655/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
new file mode 100644
index 0000000..7ec06c1
--- /dev/null
+++ b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
@@ -0,0 +1,62 @@
+package brooklyn.entity.software.http;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.location.Location;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.config.ConfigBag;
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static brooklyn.test.Asserts.succeedsEventually;
+
+public class HttpRequestSensorTest {
+    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+    final static AttributeSensor<String> SENSOR_JSON_OBJECT = Sensors.newStringSensor("aJSONObject","");
+    final static AttributeSensor<String> SENSOR_URI = Sensors.newStringSensor("uri","");
+
+    private TestApplication app;
+    private EntityLocal entity;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(app.newLocalhostProvisioningLocation().obtain()));
+        app.start(ImmutableList.<Location>of());
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+    }
+
+    @Test(groups="Integration")
+    public void testHttpSensor() throws Exception {
+        new HttpRequestSensor<String>(ConfigBag.newInstance()
+                .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
+                .configure(HttpRequestSensor.JSON_PATH, "$.myKey")
+                .configure(HttpRequestSensor.SENSOR_URI, "http://echo.jsontest.com/myKey/myValue"))
+            .apply(entity);
+        entity.setAttribute(Attributes.SERVICE_UP, true);
+
+        succeedsEventually(new Runnable() {
+            public void run() {
+                String val = entity.getAttribute(SENSOR_STRING);
+                assertTrue(val != null);
+            }
+        });
+
+        String val = entity.getAttribute(SENSOR_STRING);
+        assertEquals(val, "myValue", "val=" + val);
+    }
+}


[3/6] git commit: Adds support for multiple type value on AddSensor.

Posted by he...@apache.org.
Adds support for multiple type value on AddSensor.

Target type now needs to be specified as ConfigKey


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/65ddabd2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/65ddabd2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/65ddabd2

Branch: refs/heads/master
Commit: 65ddabd298991740f4df3363b84dbdf79bf33dd2
Parents: a2f8f65
Author: Miguel Barrientos <mb...@lcc.uma.es>
Authored: Mon Jul 14 17:22:23 2014 +0200
Committer: Miguel Barrientos <mb...@lcc.uma.es>
Committed: Mon Jul 14 18:26:46 2014 +0200

----------------------------------------------------------------------
 .../brooklyn/entity/effector/AddSensor.java     | 22 +++++++++++++++-----
 .../event/feed/http/HttpValueFunctions.java     |  4 ++--
 .../brooklyn/event/feed/http/JsonFunctions.java | 19 +++++++----------
 .../entity/software/http/HttpRequestSensor.java | 19 +++++++----------
 4 files changed, 34 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65ddabd2/core/src/main/java/brooklyn/entity/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/effector/AddSensor.java b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
index 9201f23..fb58e52 100644
--- a/core/src/main/java/brooklyn/entity/effector/AddSensor.java
+++ b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
@@ -38,12 +38,11 @@ import com.google.common.base.Preconditions;
 @Beta
 public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
     protected final T sensor;
-    
     public static final ConfigKey<String> SENSOR_NAME = ConfigKeys.newStringConfigKey("name");
     public static final ConfigKey<Duration> SENSOR_PERIOD = ConfigKeys.newConfigKey(Duration.class, "period", "Period, including units e.g. 1m or 5s or 200ms");
     
     // TODO
-//    public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType");
+    public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType");
 
     public AddSensor(T sensor) {
         this.sensor = Preconditions.checkNotNull(sensor, "sensor");
@@ -53,10 +52,23 @@ public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
     public void apply(EntityLocal entity) {
         ((EntityInternal)entity).getMutableEntityType().addSensor(sensor);
     }
-    
-    public static <T> AttributeSensor<T> newSensor(Class<T> type, ConfigBag params) {
+
+    public static <T> AttributeSensor<T> newSensor(Class<T> type, ConfigBag params){
         String name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "name must be supplied when defining a sensor");
-        return Sensors.newSensor(type, name); 
+        return Sensors.newSensor(type, name);
+    }
+
+    public static <T> AttributeSensor<T> newSensor(ConfigBag params) {
+        String name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "name must be supplied when defining a sensor");
+        String className = Preconditions.checkNotNull(params.get(SENSOR_TYPE), "target class must be supplied when defining a sensor");
+        Class<T> type = null;
+
+        try {
+            type = (Class<T>) Class.forName(className);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException("Invalid target type");
+        }
+        return Sensors.newSensor(type, name);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65ddabd2/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
index 800368d..bcd79ad 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
@@ -73,8 +73,8 @@ public class HttpValueFunctions {
         return Functionals.chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
     }
 
-    public static <T> Function<HttpToolResponse, T> jsonContentsFromPath(String element, Class<T> expected){
-        return Functionals.chain(jsonContents(), JsonFunctions.getPath(element), JsonFunctions.cast(expected));
+    public static <T> Function<HttpToolResponse, T> jsonContentsFromPath(String path){
+        return Functionals.chain(jsonContents(), JsonFunctions.<T>getPath(path));
     }
     
     public static Function<HttpToolResponse, Long> latency() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65ddabd2/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java b/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
index 5f5da44..d9ef9d2 100644
--- a/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/JsonFunctions.java
@@ -34,9 +34,7 @@ import brooklyn.util.guava.MaybeFunctions;
 import com.google.common.base.Function;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
+import com.google.gson.*;
 import com.google.gson.JsonParser;
 import com.jayway.jsonpath.JsonPath;
 
@@ -152,17 +150,14 @@ public class JsonFunctions {
     }
 
     /**
-     * returns an element from a json object given a full path {@link com.jayway.jsonpath.JsonPath}
+     * returns an element from a single json primitive value given a full path {@link com.jayway.jsonpath.JsonPath}
      */
-    public static Function<JsonElement,? extends JsonElement> getPath(final String element) {
-        return new Function<JsonElement, JsonElement>() {
-            @Override public JsonElement apply(JsonElement input) {
+    public static <T> Function<JsonElement,T> getPath(final String path) {
+        return new Function<JsonElement, T>() {
+            @Override public T apply(JsonElement input) {
                 String jsonString = input.toString();
-                JsonParser jsonParser = new JsonParser();
-                JsonElement curr = jsonParser.parse(JsonPath.<String>read(jsonString, element));
-                if (curr==null)
-                    throw new NoSuchElementException("No element '"+element+" in JSON);");
-                return curr;
+                Object rawElement = JsonPath.read(jsonString, path);
+                return (T) rawElement;
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65ddabd2/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
index 1ae08dc..aab0123 100644
--- a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
+++ b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
@@ -20,20 +20,18 @@ import java.util.Map;
  * Configurable {@link brooklyn.entity.proxying.EntityInitializer} which adds an HTTP sensor feed to retrieve the
  * <code>JSONObject</code> from a JSON response in order to populate the sensor with the indicated <code>name</code>.
  */
-// generics introduced here because we might support a configurable 'targetType` parameter in future, 
-// with automatic casting (e.g. for ints); this way it remains compatible
-public final class HttpRequestSensor<T extends String> extends AddSensor<String, AttributeSensor<String>> {
+public final class HttpRequestSensor<T> extends AddSensor<T, AttributeSensor<T>> {
 
     private static final org.slf4j.Logger log = LoggerFactory.getLogger(HttpRequestSensor.class);
 
     public static final ConfigKey<String> JSON_PATH = ConfigKeys.newStringConfigKey("jsonPath");
     public static final ConfigKey<String> SENSOR_URI = ConfigKeys.newStringConfigKey("uri");
 
-    String jsonPath;
-    String uri;
+    private String jsonPath;
+    private String uri;
 
     public HttpRequestSensor(ConfigBag params) {
-        super(newSensor(String.class, params));
+        super(AddSensor.<T>newSensor(params));
         jsonPath = Preconditions.checkNotNull(params.get(JSON_PATH), JSON_PATH);
         uri = Preconditions.checkNotNull(params.get(SENSOR_URI), SENSOR_URI);
     }
@@ -44,12 +42,11 @@ public final class HttpRequestSensor<T extends String> extends AddSensor<String,
 
         Duration period = Duration.ONE_SECOND;
 
-        HttpPollConfig<String> pollConfig = new HttpPollConfig<String>(sensor)
+        HttpPollConfig<T> pollConfig = new HttpPollConfig<T>(sensor)
                 .checkSuccess(HttpValueFunctions.responseCodeEquals(200))
-                .onFailureOrException(Functions.constant((String) null))
-                .onSuccess(HttpValueFunctions.jsonContentsFromPath(jsonPath, String.class));
-
-        if (period != null) pollConfig.period(period);
+                .onFailureOrException(Functions.constant((T) null))
+                .onSuccess(HttpValueFunctions.<T>jsonContentsFromPath(jsonPath))
+                .period(period);
 
         HttpFeed.builder().entity(entity)
                 .baseUri(uri)


[4/6] git commit: Tests added for JsonFunctions.getPath

Posted by he...@apache.org.
Tests added for JsonFunctions.getPath


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

Branch: refs/heads/master
Commit: de5991c2e0d998c37174e8d680be5a59bff6948a
Parents: 65ddabd
Author: Miguel Barrientos <mb...@lcc.uma.es>
Authored: Mon Jul 14 17:23:35 2014 +0200
Committer: Miguel Barrientos <mb...@lcc.uma.es>
Committed: Thu Jul 17 12:31:33 2014 +0200

----------------------------------------------------------------------
 .../brooklyn/entity/effector/AddSensor.java     | 11 +++++----
 .../event/feed/http/JsonFunctionsTest.java      | 16 +++++++++++++
 .../entity/software/http/HttpRequestSensor.java | 15 +++++++-----
 .../software/http/HttpRequestSensorTest.java    | 25 +++++++-------------
 4 files changed, 41 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/de5991c2/core/src/main/java/brooklyn/entity/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/effector/AddSensor.java b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
index fb58e52..4c2f1ed 100644
--- a/core/src/main/java/brooklyn/entity/effector/AddSensor.java
+++ b/core/src/main/java/brooklyn/entity/effector/AddSensor.java
@@ -32,9 +32,12 @@ import brooklyn.util.time.Duration;
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 
-/** Entity initializer which adds a sensor to an entity's type definition.
- * Subclasses must add the feed; this class does not do that. 
- * @since 0.7.0 */
+/**
+ * Creates a new sensor. The configuration can include the sensor {@code name} and {@code targetType}.
+ * For the targetType, currently this only supports classes on the initial classpath
+ * (e.g. not those in OSGi bundles added at runtime).
+ * @since 0.7.0
+ * */
 @Beta
 public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
     protected final T sensor;
@@ -66,7 +69,7 @@ public class AddSensor<RT,T extends Sensor<RT>> implements EntityInitializer {
         try {
             type = (Class<T>) Class.forName(className);
         } catch (ClassNotFoundException e) {
-            throw new IllegalArgumentException("Invalid target type");
+            throw new IllegalArgumentException("Invalid target type for sensor "+name+": " + className);
         }
         return Sensors.newSensor(type, name);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/de5991c2/core/src/test/java/brooklyn/event/feed/http/JsonFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/JsonFunctionsTest.java b/core/src/test/java/brooklyn/event/feed/http/JsonFunctionsTest.java
index 047f319..5aaa47e 100644
--- a/core/src/test/java/brooklyn/event/feed/http/JsonFunctionsTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/JsonFunctionsTest.java
@@ -102,5 +102,21 @@ public class JsonFunctionsTest {
         Assert.assertNull(n);
     }
 
+    @Test
+    public void testGetPath1(){
+        Integer obj = (Integer) JsonFunctions.getPath("$.europe.uk.edinburgh.population").apply(europeMap());
+        Assert.assertEquals((int) obj, 500*1000);
+    }
 
+    @Test
+    public void testGetPath2(){
+        String obj = (String) JsonFunctions.getPath("$.europe.uk.edinburgh.lighting").apply(europeMap());
+        Assert.assertEquals(obj, "dark");
+    }
+
+    @Test
+    public void testGetPathWrong(){
+        Object obj = JsonFunctions.getPath("$.europe.spain.malaga").apply(europeMap());
+        Assert.assertNull(obj);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/de5991c2/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
index aab0123..c16a739 100644
--- a/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
+++ b/software/base/src/main/java/brooklyn/entity/software/http/HttpRequestSensor.java
@@ -14,12 +14,15 @@ import com.google.common.base.Functions;
 import com.google.common.base.Preconditions;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.Beta;
+
 import java.util.Map;
 
 /**
  * Configurable {@link brooklyn.entity.proxying.EntityInitializer} which adds an HTTP sensor feed to retrieve the
  * <code>JSONObject</code> from a JSON response in order to populate the sensor with the indicated <code>name</code>.
  */
+@Beta
 public final class HttpRequestSensor<T> extends AddSensor<T, AttributeSensor<T>> {
 
     private static final org.slf4j.Logger log = LoggerFactory.getLogger(HttpRequestSensor.class);
@@ -27,8 +30,12 @@ public final class HttpRequestSensor<T> extends AddSensor<T, AttributeSensor<T>>
     public static final ConfigKey<String> JSON_PATH = ConfigKeys.newStringConfigKey("jsonPath");
     public static final ConfigKey<String> SENSOR_URI = ConfigKeys.newStringConfigKey("uri");
 
-    private String jsonPath;
-    private String uri;
+    private final String jsonPath;
+    private final String uri;
+
+    public HttpRequestSensor(Map<String, String> params) {
+        this(ConfigBag.newInstance(params));
+    }
 
     public HttpRequestSensor(ConfigBag params) {
         super(AddSensor.<T>newSensor(params));
@@ -53,8 +60,4 @@ public final class HttpRequestSensor<T> extends AddSensor<T, AttributeSensor<T>>
                 .poll(pollConfig)
                 .build();
     }
-
-    public HttpRequestSensor(Map<String, String> params) {
-        this(ConfigBag.newInstance(params));
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/de5991c2/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
index 7ec06c1..5f29e5d 100644
--- a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
@@ -8,6 +8,7 @@ import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.location.Location;
+import brooklyn.test.EntityTestUtils;
 import brooklyn.test.entity.TestApplication;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.util.config.ConfigBag;
@@ -16,14 +17,11 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.assertEquals;
-import static brooklyn.test.Asserts.succeedsEventually;
 
 public class HttpRequestSensorTest {
-    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
-    final static AttributeSensor<String> SENSOR_JSON_OBJECT = Sensors.newStringSensor("aJSONObject","");
-    final static AttributeSensor<String> SENSOR_URI = Sensors.newStringSensor("uri","");
+    final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString");
+    final static String TARGET_TYPE = "java.lang.String";
 
     private TestApplication app;
     private EntityLocal entity;
@@ -42,21 +40,16 @@ public class HttpRequestSensorTest {
 
     @Test(groups="Integration")
     public void testHttpSensor() throws Exception {
-        new HttpRequestSensor<String>(ConfigBag.newInstance()
+        HttpRequestSensor<Integer> sensor = new HttpRequestSensor<Integer>(ConfigBag.newInstance()
                 .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
+                .configure(HttpRequestSensor.SENSOR_TYPE, TARGET_TYPE)
                 .configure(HttpRequestSensor.JSON_PATH, "$.myKey")
-                .configure(HttpRequestSensor.SENSOR_URI, "http://echo.jsontest.com/myKey/myValue"))
-            .apply(entity);
+                .configure(HttpRequestSensor.SENSOR_URI, "http://echo.jsontest.com/myKey/myValue"));
+            sensor.apply(entity);
         entity.setAttribute(Attributes.SERVICE_UP, true);
 
-        succeedsEventually(new Runnable() {
-            public void run() {
-                String val = entity.getAttribute(SENSOR_STRING);
-                assertTrue(val != null);
-            }
-        });
-
-        String val = entity.getAttribute(SENSOR_STRING);
+        EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_STRING, SENSOR_STRING.getName());
+        String val = entity.getConfig(HttpRequestSensor.SENSOR_NAME);
         assertEquals(val, "myValue", "val=" + val);
     }
 }