You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ri...@apache.org on 2015/06/04 15:44:52 UTC

[2/4] incubator-brooklyn git commit: Don't spin BrooklynEntityMirror forever on failure

Don't spin BrooklynEntityMirror forever on failure

* Fail on non-{2xx, 403} response received
* Fail on BrooklynNode failure


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

Branch: refs/heads/master
Commit: 03c1819eef0abdedb36622d562b206eac3bb94a2
Parents: 9595ddc
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jun 2 14:43:57 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Jun 4 15:56:22 2015 +0300

----------------------------------------------------------------------
 .../entity/brooklynnode/BrooklynNodeImpl.java   |  8 +++++-
 .../entity/brooklynnode/EntityHttpClient.java   | 26 ++++++++++++++++++++
 .../brooklynnode/EntityHttpClientImpl.java      | 12 ++++++++-
 .../brooklynnode/CallbackEntityHttpClient.java  |  6 +++++
 4 files changed, 50 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03c1819e/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 9fd34eb..e4ca6c5 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -43,6 +43,7 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.basic.SoftwareProcessImpl;
+import brooklyn.entity.brooklynnode.EntityHttpClient.ResponseCodePredicates;
 import brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;
@@ -79,7 +80,9 @@ import brooklyn.util.time.Time;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Range;
 import com.google.common.net.HostAndPort;
 import com.google.common.util.concurrent.Runnables;
 import com.google.gson.Gson;
@@ -324,15 +327,18 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
                 .backoffTo(Duration.FIVE_SECONDS)
                 .limitTimeTo(Duration.minutes(5))
                 .repeat(Runnables.doNothing())
+                .rethrowExceptionImmediately()
                 .until(new Callable<Boolean>() {
+                    @Override
                     public Boolean call() {
                         HttpToolResponse result = ((BrooklynNode)entity()).http()
+                                //will throw on non-{2xx, 403} response
+                                .responseSuccess(Predicates.<Integer>or(ResponseCodePredicates.success(), Predicates.equalTo(HttpStatus.SC_FORBIDDEN)))
                                 .post("/v1/applications", headers, plan.getBytes());
                         if (result.getResponseCode() == HttpStatus.SC_FORBIDDEN) {
                             log.debug("Remote is not ready to accept requests, response is " + result.getResponseCode());
                             return false;
                         } else {
-                            //will fail on non-2xx response
                             byte[] content = result.getContent();
                             response.set(content);
                             return true;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03c1819e/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClient.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClient.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClient.java
index 33f3c2d..25df319 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClient.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClient.java
@@ -23,10 +23,29 @@ import java.util.Map;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Range;
+
 /**
  * Helpful methods for making HTTP requests to {@link BrooklynNode} entities.
  */
 public interface EntityHttpClient {
+    public static class ResponseCodePredicates {
+        private static class ResponseCodeHealthyPredicate implements Predicate<Integer> {
+            @Override
+            public boolean apply(Integer input) {
+                return HttpTool.isStatusCodeHealthy(input);
+            }
+        }
+        public static Predicate<Integer> informational() {return Range.closed(100, 199);}
+        public static Predicate<Integer> success() {return new ResponseCodeHealthyPredicate();}
+        public static Predicate<Integer> redirect() {return Range.closed(300, 399);}
+        public static Predicate<Integer> clientError() {return Range.closed(400, 499);}
+        public static Predicate<Integer> serverError() {return Range.closed(500, 599);}
+        public static Predicate<Integer> invalid() {return Predicates.or(Range.atMost(99), Range.atLeast(600));}
+    }
+
     /**
      * @return An HTTP client builder configured to access the {@link
      *         BrooklynNode#WEB_CONSOLE_URI web console URI} at the
@@ -35,6 +54,13 @@ public interface EntityHttpClient {
     public HttpTool.HttpClientBuilder getHttpClientForBrooklynNode();
 
     /**
+     * Configure which response codes are treated as successful
+     * @param successPredicate A predicate which returns true is the response code is acceptable
+     * @return this
+     */
+    public EntityHttpClient responseSuccess(Predicate<Integer> responseSuccess);
+
+    /**
      * Makes an HTTP GET to a Brooklyn node entity.
      * @param path Relative path to resource on server, e.g v1/catalog
      * @return The server's response

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03c1819e/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
index 4a126c8..79f4b95 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
@@ -18,6 +18,8 @@
  */
 package brooklyn.entity.brooklynnode;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.net.URI;
 import java.util.Map;
 
@@ -27,6 +29,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Entity;
@@ -50,6 +53,7 @@ public class EntityHttpClientImpl implements EntityHttpClient {
     protected Entity entity;
     protected AttributeSensor<?> urlSensor;
     protected ConfigKey<?> urlConfig;
+    protected Predicate<Integer> responseSuccess = ResponseCodePredicates.success();
 
     protected EntityHttpClientImpl(Entity entity, AttributeSensor<?> urlSensor) {
         this.entity = entity;
@@ -77,6 +81,12 @@ public class EntityHttpClientImpl implements EntityHttpClient {
         return builder;
     }
 
+    @Override
+    public EntityHttpClient responseSuccess(Predicate<Integer> responseSuccess) {
+        this.responseSuccess = checkNotNull(responseSuccess, "responseSuccess");
+        return this;
+    }
+
     protected HttpToolResponse exec(String path, HttpCall httpCall) {
         HttpClient client = Preconditions.checkNotNull(getHttpClientForBrooklynNode(), "No address info for "+entity)
                 .build();
@@ -91,7 +101,7 @@ public class EntityHttpClientImpl implements EntityHttpClient {
             throw new IllegalStateException("Invalid response invoking " + uri + ": " + e, e);
         }
         Tasks.addTagDynamically(BrooklynTaskTags.tagForStream("http_response", Streams.byteArray(result.getContent())));
-        if (!HttpTool.isStatusCodeHealthy(result.getResponseCode())) {
+        if (!responseSuccess.apply(result.getResponseCode())) {
             LOG.warn("Invalid response invoking {}: response code {}\n{}: {}",
                     new Object[]{uri, result.getResponseCode(), result, new String(result.getContent())});
             throw new IllegalStateException("Invalid response invoking " + uri + ": response code " + result.getResponseCode());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03c1819e/software/base/src/test/java/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
index 737e4f1..d1033a8 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
@@ -32,6 +32,7 @@ import brooklyn.util.http.HttpTool.HttpClientBuilder;
 import brooklyn.util.http.HttpToolResponse;
 
 import com.google.common.base.Function;
+import com.google.common.base.Predicate;
 
 public class CallbackEntityHttpClient implements EntityHttpClient {
     public static class Request {
@@ -92,4 +93,9 @@ public class CallbackEntityHttpClient implements EntityHttpClient {
     public HttpToolResponse delete(String path, Map<String, String> headers) {
         throw new IllegalStateException("Method call not expected");
     }
+
+    @Override
+    public EntityHttpClient responseSuccess(Predicate<Integer> successPredicate) {
+        throw new IllegalStateException("Method call not expected");
+    }
 }