You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/11 22:42:40 UTC

[02/18] incubator-brooklyn git commit: HttpValueFunctions: not anonymous inner classes

HttpValueFunctions: not anonymous inner classes

- HttpValueFunctions uses static classes rather than anonymous inner
  classes
  (because they are extremely brittle in persisted state)
- Adds containsHeader(), used by nginx
- Nginx uses static classes, rather than anonymous inner classes


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

Branch: refs/heads/master
Commit: ee3c1ca6eb5d045bc74adc72438f613a1a912dc8
Parents: 0dc3911
Author: Aled Sage <al...@gmail.com>
Authored: Sat Apr 18 12:44:35 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 17:51:12 2015 +0100

----------------------------------------------------------------------
 .../event/feed/http/HttpValueFunctions.java     | 55 +++++++++++-
 .../brooklyn/util/http/HttpToolResponse.java    |  2 +-
 .../event/feed/http/HttpValueFunctionsTest.java | 94 ++++++++++++++++++++
 .../entity/proxy/nginx/NginxControllerImpl.java | 23 +++--
 4 files changed, 163 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ee3c1ca6/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 bcd79ad..3e7e6b2 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpValueFunctions.java
@@ -34,6 +34,11 @@ public class HttpValueFunctions {
     private HttpValueFunctions() {} // instead use static utility methods
     
     public static Function<HttpToolResponse, Integer> responseCode() {
+        return new ResponseCode();
+    }
+    
+    /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+    private static Function<HttpToolResponse, Integer> responseCodeLegacy() {
         return new Function<HttpToolResponse, Integer>() {
             @Override public Integer apply(HttpToolResponse input) {
                 return input.getResponseCode();
@@ -41,6 +46,12 @@ public class HttpValueFunctions {
         };
     }
 
+    private static class ResponseCode implements Function<HttpToolResponse, Integer> {
+        @Override public Integer apply(HttpToolResponse input) {
+            return input.getResponseCode();
+        }
+    }
+
     public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int expected) {
         return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.equalTo(expected)));
     }
@@ -52,15 +63,26 @@ public class HttpValueFunctions {
         }
         return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.in(expectedList)));
     }
-    
+
     public static Function<HttpToolResponse, String> stringContentsFunction() {
+        return new StringContents();
+    }
+    
+    /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+    private static Function<HttpToolResponse, String> stringContentsFunctionLegacy() {
         return new Function<HttpToolResponse, String>() {
             @Override public String apply(HttpToolResponse input) {
                 return input.getContentAsString();
             }
         };
     }
-    
+
+    private static class StringContents implements Function<HttpToolResponse, String> {
+        @Override public String apply(HttpToolResponse input) {
+            return input.getContentAsString();
+        }
+    }
+
     public static Function<HttpToolResponse, JsonElement> jsonContents() {
         return Functionals.chain(stringContentsFunction(), JsonFunctions.asJson());
     }
@@ -78,13 +100,42 @@ public class HttpValueFunctions {
     }
     
     public static Function<HttpToolResponse, Long> latency() {
+        return new Latency();
+    }
+
+    /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+    private static Function<HttpToolResponse, Long> latencyLegacy() {
         return new Function<HttpToolResponse, Long>() {
             public Long apply(HttpToolResponse input) {
                 return input.getLatencyFullContent();
             }
         };
     }
+
+    private static class Latency implements Function<HttpToolResponse, Long> {
+        public Long apply(HttpToolResponse input) {
+            return input.getLatencyFullContent();
+        }
+    };
+
+    public static Function<HttpToolResponse, Boolean> containsHeader(String header) {
+        return new ContainsHeader(header);
+    }
+
+    private static class ContainsHeader implements Function<HttpToolResponse, Boolean> {
+        private final String header;
+
+        public ContainsHeader(String header) {
+            this.header = header;
+        }
+        @Override
+        public Boolean apply(HttpToolResponse input) {
+            List<String> actual = input.getHeaderLists().get(header);
+            return actual != null && actual.size() > 0;
+        }
+    }
     
+
     /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function)} */ @Deprecated
     public static <A,B,C> Function<A,C> chain(final Function<A,? extends B> f1, final Function<B,C> f2) {
         return Functionals.chain(f1, f2);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ee3c1ca6/core/src/main/java/brooklyn/util/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/http/HttpToolResponse.java b/core/src/main/java/brooklyn/util/http/HttpToolResponse.java
index 1722e41..1837a87 100644
--- a/core/src/main/java/brooklyn/util/http/HttpToolResponse.java
+++ b/core/src/main/java/brooklyn/util/http/HttpToolResponse.java
@@ -86,7 +86,7 @@ public class HttpToolResponse implements HttpPollValue {
         }
     }
 
-    public HttpToolResponse(int responseCode, Map<String,List<String>> headers, byte[] content,
+    public HttpToolResponse(int responseCode, Map<String,? extends List<String>> headers, byte[] content,
             long startTime, long durationMillisOfFirstResponse, long durationMillisOfFullContent) {
         this.response = null;
         this.responseCode = responseCode;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ee3c1ca6/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
new file mode 100644
index 0000000..7769427
--- /dev/null
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 brooklyn.event.feed.http;
+
+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.util.NoSuchElementException;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.util.http.HttpToolResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class HttpValueFunctionsTest {
+
+    private int responseCode = 200;
+    private long fullLatency = 1000;
+    private String headerName = "my_header";
+    private String headerVal = "my_header_val";
+    private String bodyKey = "mykey";
+    private String bodyVal = "myvalue";
+    private String body = "{"+bodyKey+":"+bodyVal+"}";
+    private long now;
+    private HttpToolResponse response;
+    
+    @BeforeMethod
+    public void setUp() throws Exception {
+        now = System.currentTimeMillis();
+        response = new HttpToolResponse(responseCode, ImmutableMap.of(headerName, ImmutableList.of(headerVal)), 
+                body.getBytes(), now-fullLatency, fullLatency / 2, fullLatency);
+    }
+    
+    @Test
+    public void testResponseCode() throws Exception {
+        assertEquals(HttpValueFunctions.responseCode().apply(response), Integer.valueOf(responseCode));
+    }
+
+    @Test
+    public void testContainsHeader() throws Exception {
+        assertTrue(HttpValueFunctions.containsHeader(headerName).apply(response));
+        assertFalse(HttpValueFunctions.containsHeader("wrong_header").apply(response));
+    }
+    
+    @Test
+    public void testStringContents() throws Exception {
+        assertEquals(HttpValueFunctions.stringContentsFunction().apply(response), body);
+    }
+
+    @Test
+    public void testJsonContents() throws Exception {
+        JsonElement json = HttpValueFunctions.jsonContents().apply(response);
+        assertTrue(json.isJsonObject());
+        assertEquals(json.getAsJsonObject().entrySet(), ImmutableMap.of(bodyKey, new JsonPrimitive(bodyVal)).entrySet());
+    }
+
+    @Test
+    public void testJsonContentsGettingElement() throws Exception {
+        assertEquals(HttpValueFunctions.jsonContents(bodyKey, String.class).apply(response), bodyVal);
+    }
+
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testJsonContentsGettingMissingElement() throws Exception {
+        assertNull(HttpValueFunctions.jsonContents("wrongkey", String.class).apply(response));
+    }
+
+    @Test
+    public void testLatency() throws Exception {
+        assertEquals(HttpValueFunctions.latency().apply(response), Long.valueOf(fullLatency));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ee3c1ca6/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index dd34e69..0253f96 100644
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -44,6 +44,7 @@ import brooklyn.event.SensorEventListener;
 import brooklyn.event.feed.ConfigToAttributes;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.management.SubscriptionHandle;
 import brooklyn.policy.PolicySpec;
 import brooklyn.util.ResourceUtils;
@@ -117,17 +118,23 @@ public class NginxControllerImpl extends AbstractControllerImpl implements Nginx
                 .poll(new HttpPollConfig<Boolean>(NGINX_URL_ANSWERS_NICELY)
                         // Any response from Nginx is good.
                         .checkSuccess(Predicates.alwaysTrue())
-                        .onResult(new Function<HttpToolResponse, Boolean>() {
-                                @Override
-                                public Boolean apply(HttpToolResponse input) {
-                                    // Accept any nginx response (don't assert specific version), so that sub-classing
-                                    // for a custom nginx build is not strict about custom version numbers in headers
-                                    List<String> actual = input.getHeaderLists().get("Server");
-                                    return actual != null && actual.size() == 1;
-                                }})
+                        // Accept any nginx response (don't assert specific version), so that sub-classing
+                        // for a custom nginx build is not strict about custom version numbers in headers
+                        .onResult(HttpValueFunctions.containsHeader("Server"))
                         .setOnException(false))
                 .build());
         
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Function<HttpToolResponse, Boolean>() {
+            @Override
+            public Boolean apply(HttpToolResponse input) {
+                // Accept any nginx response (don't assert specific version), so that sub-classing
+                // for a custom nginx build is not strict about custom version numbers in headers
+                List<String> actual = input.getHeaderLists().get("Server");
+                return actual != null && actual.size() == 1;
+            }
+        };
+        
         if (!Lifecycle.RUNNING.equals(getAttribute(SERVICE_STATE_ACTUAL))) {
             // TODO when updating the map, if it would change from empty to empty on a successful run
             // gate with the above check to prevent flashing on ON_FIRE during rebind (this is invoked on rebind as well as during start)