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/09/26 00:49:28 UTC

[04/12] git commit: FunctionFeed: test persistence

FunctionFeed: test persistence

- and make easier to build a FunctionPollConfig


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

Branch: refs/heads/master
Commit: 9fe95f9b697ca10b9f1f184e61ed5e9f1b961be5
Parents: d7ab5b5
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 5 12:04:26 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Sep 4 08:46:49 2014 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/DataEntityImpl.java   |  2 +-
 .../event/feed/function/FunctionPollConfig.java | 33 +++++++++++++---
 .../event/feed/http/HttpPollConfig.java         | 16 ++++----
 .../brooklyn/entity/rebind/RebindFeedTest.java  | 41 ++++++++++++++++++--
 .../event/feed/function/FunctionFeedTest.java   | 25 ++++++++++++
 5 files changed, 98 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9fe95f9b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
index 8d1743f..140e488 100644
--- a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
@@ -62,7 +62,7 @@ public class DataEntityImpl extends AbstractEntity implements DataEntity {
         if (map != null && map.size() > 0) {
             for (Map.Entry<AttributeSensor<?>, Supplier<?>> entry : map.entrySet()) {
                 final AttributeSensor sensor = entry.getKey();
-                final Supplier supplier = entry.getValue();
+                final Supplier<?> supplier = entry.getValue();
                 builder.poll(new FunctionPollConfig<Object, Object>(sensor)
                         .supplier(supplier)
                         .onFailureOrException(Functions.constant(null)));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9fe95f9b/core/src/main/java/brooklyn/event/feed/function/FunctionPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/function/FunctionPollConfig.java b/core/src/main/java/brooklyn/event/feed/function/FunctionPollConfig.java
index 7c4ef43..b2ff3f1 100644
--- a/core/src/main/java/brooklyn/event/feed/function/FunctionPollConfig.java
+++ b/core/src/main/java/brooklyn/event/feed/function/FunctionPollConfig.java
@@ -24,6 +24,7 @@ import groovy.lang.Closure;
 import java.util.concurrent.Callable;
 
 import brooklyn.event.AttributeSensor;
+import brooklyn.event.feed.FeedConfig;
 import brooklyn.event.feed.PollConfig;
 import brooklyn.util.GroovyJavaMethods;
 
@@ -33,6 +34,10 @@ public class FunctionPollConfig<S, T> extends PollConfig<S, T, FunctionPollConfi
 
     private Callable<?> callable;
     
+    public static <T> FunctionPollConfig<?, T> forSensor(AttributeSensor<T> sensor) {
+        return new FunctionPollConfig<Object, T>(sensor);
+    }
+    
     public FunctionPollConfig(AttributeSensor<T> sensor) {
         super(sensor);
     }
@@ -46,20 +51,36 @@ public class FunctionPollConfig<S, T> extends PollConfig<S, T, FunctionPollConfi
         return callable;
     }
     
-    public FunctionPollConfig<S, T> callable(Callable<? extends S> val) {
+    /**
+     * The {@link Callable} to be invoked on each poll.
+     * <p>
+     * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
+     * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
+     * return the wrong type.
+     */
+    @SuppressWarnings("unchecked")
+    public <newS> FunctionPollConfig<newS, T> callable(Callable<? extends newS> val) {
         this.callable = checkNotNull(val, "callable");
-        return this;
+        return (FunctionPollConfig<newS, T>) this;
     }
     
-    public FunctionPollConfig<S, T> supplier(final Supplier<? extends S> val) {
+    /**
+     * Supplies the value to be returned by each poll.
+     * <p>
+     * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
+     * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
+     * return the wrong type.
+     */
+    @SuppressWarnings("unchecked")
+    public <newS> FunctionPollConfig<newS, T> supplier(final Supplier<? extends newS> val) {
         checkNotNull(val, "supplier");
-        this.callable = new Callable<S>() {
+        this.callable = new Callable<newS>() {
             @Override
-            public S call() throws Exception {
+            public newS call() throws Exception {
                 return val.get();
             }
         };
-        return this;
+        return (FunctionPollConfig<newS, T>) this;
     }
 
     public FunctionPollConfig<S, T> closure(Closure<?> val) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9fe95f9b/core/src/main/java/brooklyn/event/feed/http/HttpPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpPollConfig.java b/core/src/main/java/brooklyn/event/feed/http/HttpPollConfig.java
index c8362fc..c091006 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpPollConfig.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpPollConfig.java
@@ -52,6 +52,14 @@ public class HttpPollConfig<T> extends PollConfig<HttpToolResponse, T, HttpPollC
             return input != null && input.getResponseCode() >= 200 && input.getResponseCode() <= 399;
         }};
     
+    public static <T> HttpPollConfig<T> forSensor(AttributeSensor<T> sensor) {
+        return new HttpPollConfig<T>(sensor);
+    }
+    
+    public static HttpPollConfig<Void> forMultiple() {
+        return new HttpPollConfig<Void>(PollConfig.NO_SENSOR);
+    }
+    
     public HttpPollConfig(AttributeSensor<T> sensor) {
         super(sensor);
         super.checkSuccess(DEFAULT_SUCCESS);
@@ -65,14 +73,6 @@ public class HttpPollConfig<T> extends PollConfig<HttpToolResponse, T, HttpPollC
         headers = other.headers;
     }
     
-    public static <T> HttpPollConfig<T> forSensor(AttributeSensor<T> sensor) {
-        return new HttpPollConfig<T>(sensor);
-    }
-    
-    public static HttpPollConfig<Void> forMultiple() {
-        return new HttpPollConfig<Void>(PollConfig.NO_SENSOR);
-    }
-    
     public String getSuburl() {
         return suburl;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9fe95f9b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
index 056e440..a0b5f04 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
@@ -33,6 +33,8 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
+import brooklyn.event.feed.function.FunctionFeed;
+import brooklyn.event.feed.function.FunctionPollConfig;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
@@ -42,6 +44,7 @@ import brooklyn.test.entity.TestEntityImpl;
 import brooklyn.util.http.BetterMockWebServer;
 
 import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.Callables;
 import com.google.mockwebserver.MockResponse;
 
 public class RebindFeedTest extends RebindTestFixtureWithApp {
@@ -73,8 +76,8 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
     
     @Test
     public void testHttpFeedRegisteredInInitIsPersisted() throws Exception {
-        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityImpl.class)
-                .configure(MyEntityImpl.BASE_URL, baseUrl));
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithHttpFeedImpl.class)
+                .configure(MyEntityWithHttpFeedImpl.BASE_URL, baseUrl));
         EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_INT, (Integer)200);
         EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_STRING, "{\"foo\":\"myfoo\"}");
         assertEquals(origEntity.getFeedSupport().getFeeds().size(), 1);
@@ -92,13 +95,30 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
         EntityTestUtils.assertAttributeEqualsEventually(newEntity, SENSOR_STRING, "{\"foo\":\"myfoo\"}");
     }
 
-    public static class MyEntityImpl extends TestEntityImpl {
+    @Test
+    public void testFunctionFeedRegisteredInInitIsPersisted() throws Exception {
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithFunctionFeedImpl.class));
+        EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_INT, (Integer)1);
+        assertEquals(origEntity.getFeedSupport().getFeeds().size(), 1);
+
+        newApp = rebind(false);
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        
+        Collection<Feed> newFeeds = newEntity.getFeedSupport().getFeeds();
+        assertEquals(newFeeds.size(), 1);
+        
+        // Expect the feed to still be polling
+        newEntity.setAttribute(SENSOR_INT, null);
+        EntityTestUtils.assertAttributeEqualsEventually(newEntity, SENSOR_INT, (Integer)1);
+    }
+    
+    public static class MyEntityWithHttpFeedImpl extends TestEntityImpl {
         public static final ConfigKey<URL> BASE_URL = ConfigKeys.newConfigKey(URL.class, "rebindFeedTest.baseUrl");
         
         @Override
         public void init() {
             super.init();
-            HttpFeed feed = addFeed(HttpFeed.builder()
+            addFeed(HttpFeed.builder()
                     .entity(this)
                     .baseUrl(getConfig(BASE_URL))
                     .poll(HttpPollConfig.forSensor(SENSOR_INT)
@@ -110,4 +130,17 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
                     .build());
         }
     }
+    
+    public static class MyEntityWithFunctionFeedImpl extends TestEntityImpl {
+        @Override
+        public void init() {
+            super.init();
+            addFeed(FunctionFeed.builder()
+                    .entity(this)
+                    .poll(FunctionPollConfig.forSensor(SENSOR_INT)
+                            .period(100)
+                            .callable(Callables.returning(1)))
+                    .build());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9fe95f9b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
index 59db329..90a0435 100644
--- a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
@@ -48,6 +48,7 @@ import brooklyn.test.entity.TestEntity;
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
 import com.google.common.base.Predicates;
+import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Callables;
 
@@ -191,6 +192,30 @@ public class FunctionFeedTest extends BrooklynAppUnitTestSupport {
             }});
     }
     
+    @Test
+    @SuppressWarnings("unused")
+    public void testFunctionPollConfigBuilding() throws Exception {
+        FunctionPollConfig<Integer, Integer> typeFromCallable = FunctionPollConfig.forSensor(SENSOR_INT)
+                .period(1)
+                .callable(Callables.returning(1))
+                .onSuccess(Functions.constant(-1));
+
+        FunctionPollConfig<Integer, Integer> typeFromSupplier = FunctionPollConfig.forSensor(SENSOR_INT)
+                .period(1)
+                .supplier(Suppliers.ofInstance(1))
+                .onSuccess(Functions.constant(-1));
+
+        FunctionPollConfig<Integer, Integer> usingConstructor = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+                .period(1)
+                .supplier(Suppliers.ofInstance(1))
+                .onSuccess(Functions.constant(-1));
+
+        FunctionPollConfig<Integer, Integer> usingConstructorWithFailureOrException = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+                .period(1)
+                .supplier(Suppliers.ofInstance(1))
+                .onFailureOrException(Functions.<Integer>constant(null));
+    }
+    
     private static class IncrementingCallable implements Callable<Integer> {
         private final AtomicInteger next = new AtomicInteger(0);