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 2015/11/04 16:47:46 UTC

[1/9] incubator-brooklyn git commit: Add EntityAsserts and HttpUtils.

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 48e4fe3ca -> a5040934d


Add EntityAsserts and HttpUtils.

This are added to allow core code to make assertions on entities without
without having a dependency on TestNG.

For now, deprecate EntityTestUtils and HttpTestUtils, and in the future these
can be removed in favour of the new 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/c316e217
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c316e217
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c316e217

Branch: refs/heads/master
Commit: c316e2177b88b2f274637d812e5659e751aeea0d
Parents: 6d00890
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Wed Oct 28 12:10:37 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Fri Oct 30 11:34:43 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/core/entity/EntityAsserts.java     | 192 ++++++
 .../deserializingClassRenames.properties        |   2 +-
 .../brooklyn/core/entity/EntityAssertsTest.java | 217 +++++++
 .../apache/brooklyn/test/EntityTestUtils.java   |  51 +-
 .../org/apache/brooklyn/test/HttpTestUtils.java |   4 +
 .../brooklyn/test/TrustingSslSocketFactory.java | 134 ----
 .../java/org/apache/brooklyn/test/Asserts.java  | 615 ++++++++++++++++++-
 .../apache/brooklyn/util/http/HttpUtils.java    | 387 ++++++++++++
 .../util/http/TrustingSslSocketFactory.java     | 134 ++++
 9 files changed, 1577 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
new file mode 100644
index 0000000..046ac52
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
@@ -0,0 +1,192 @@
+/*
+ * 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 org.apache.brooklyn.core.entity;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.test.Asserts;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.apache.brooklyn.test.Asserts.assertEquals;
+
+/**
+ * Convenience class containing assertions that may be made about entities.
+ */
+public class EntityAsserts {
+
+
+    public static <T> void assertAttributeEquals(Entity entity, AttributeSensor<T> attribute, T expected) {
+        assertEquals(entity.getAttribute(attribute), expected, "entity=" + entity + "; attribute=" + attribute);
+    }
+
+    public static <T> void assertConfigEquals(Entity entity, ConfigKey<T> configKey, T expected) {
+        assertEquals(entity.getConfig(configKey), expected, "entity=" + entity + "; configKey=" + configKey);
+    }
+
+    public static <T> void assertAttributeEqualsEventually(final Entity entity, final AttributeSensor<T> attribute, final T expected) {
+        assertAttributeEqualsEventually(Maps.newLinkedHashMap(), entity, attribute, expected);
+    }
+
+    public static <T> void assertAttributeEqualsEventually(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, final T expected) {
+        // Not using assertAttributeEventually(predicate) so get nicer error message
+        Asserts.succeedsEventually((Map) flags, new Runnable() {
+            @Override
+            public void run() {
+                assertAttributeEquals(entity, attribute, expected);
+            }
+        });
+    }
+
+    public static <T> T assertAttributeEventuallyNonNull(final Entity entity, final AttributeSensor<T> attribute) {
+        return assertAttributeEventuallyNonNull(Maps.newLinkedHashMap(), entity, attribute);
+    }
+
+    public static <T> T assertAttributeEventuallyNonNull(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute) {
+        return assertAttributeEventually(flags, entity, attribute, Predicates.notNull());
+    }
+
+    public static <T> T assertAttributeEventually(final Entity entity, final AttributeSensor<T> attribute, Predicate<? super T> predicate) {
+        return assertAttributeEventually(ImmutableMap.of(), entity, attribute, predicate);
+    }
+
+    public static <T> T assertAttributeEventually(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, final Predicate<? super T> predicate) {
+        final AtomicReference<T> result = new AtomicReference<T>();
+        Asserts.succeedsEventually((Map)flags, new Runnable() {
+            @Override public void run() {
+                T val = entity.getAttribute(attribute);
+                Asserts.assertTrue(predicate.apply(val), "val=" + val);
+                result.set(val);
+            }});
+        return result.get();
+    }
+
+    public static <T> T assertAttribute(final Entity entity, final AttributeSensor<T> attribute, final Predicate<? super T> predicate) {
+        T val = entity.getAttribute(attribute);
+        Asserts.assertTrue(predicate.apply(val), "val=" + val);
+        return val;
+    }
+
+
+    public static <T extends Entity> void assertPredicateEventuallyTrue(final T entity, final Predicate<? super T> predicate) {
+        assertPredicateEventuallyTrue(Maps.newLinkedHashMap(), entity, predicate);
+    }
+
+    public static <T extends Entity> void assertPredicateEventuallyTrue(Map<?,?> flags, final T entity, final Predicate<? super T> predicate) {
+        Asserts.succeedsEventually((Map)flags, new Runnable() {
+            @Override public void run() {
+                Asserts.assertTrue(predicate.apply(entity), "predicate unsatisfied");
+            }});
+    }
+
+    public static <T> void assertAttributeEqualsContinually(final Entity entity, final AttributeSensor<T> attribute, final T expected) {
+        assertAttributeEqualsContinually(Maps.newLinkedHashMap(), entity, attribute, expected);
+    }
+
+    public static <T> void assertAttributeEqualsContinually(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, final T expected) {
+        Asserts.succeedsContinually(flags, new Runnable() {
+            @Override public void run() {
+                assertAttributeEquals(entity, attribute, expected);
+            }});
+    }
+
+    public static void assertGroupSizeEqualsEventually(final Group group, int expected) {
+        assertGroupSizeEqualsEventually(ImmutableMap.of(), group, expected);
+    }
+
+    public static void assertGroupSizeEqualsEventually(Map<?,?> flags, final Group group, final int expected) {
+        Asserts.succeedsEventually((Map)flags, new Runnable() {
+            @Override public void run() {
+                Collection<Entity> members = group.getMembers();
+                assertEquals(members.size(), expected, "members=" + members);
+            }});
+    }
+
+
+    /**
+     * Asserts that the entity's value for this attribute changes, by registering a subscription and checking the value.
+     *
+     * @param entity The entity whose attribute will be checked.
+     * @param attribute The attribute to check on the entity.
+     *
+     * @throws AssertionError if the assertion fails.
+     */
+    public static void assertAttributeChangesEventually(final Entity entity, final AttributeSensor<?> attribute) {
+        final Object origValue = entity.getAttribute(attribute);
+        final AtomicBoolean changed = new AtomicBoolean();
+        SubscriptionHandle handle = entity.subscriptions().subscribe(entity, attribute, new SensorEventListener<Object>() {
+            @Override public void onEvent(SensorEvent<Object> event) {
+                if (!Objects.equal(origValue, event.getValue())) {
+                    changed.set(true);
+                }
+            }});
+        try {
+            Asserts.succeedsEventually(new Runnable() {
+                @Override public void run() {
+                    Asserts.assertTrue(changed.get(), entity + " -> " + attribute + " not changed");
+                }});
+        } finally {
+            entity.subscriptions().unsubscribe(entity, handle);
+        }
+    }
+
+
+    @Beta @SafeVarargs
+    public static <T> void assertAttributeNever(final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
+        final Set<T> reject = Sets.newHashSet(disallowed);
+        Asserts.succeedsContinually(new Runnable() {
+            @Override
+            public void run() {
+                T val = entity.getAttribute(attribute);
+                Asserts.assertFalse(reject.contains(val),
+                        "Attribute " + attribute + " on " + entity + " has disallowed value " + val);
+            }
+        });
+    }
+
+    @Beta @SafeVarargs
+    public static <T> void assertAttributeNever(final Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
+        final Set<T> reject = Sets.newHashSet(disallowed);
+        Asserts.succeedsContinually(flags, new Runnable() {
+            @Override
+            public void run() {
+                T val = entity.getAttribute(attribute);
+                Asserts.assertFalse(reject.contains(val),
+                        "Attribute " + attribute + " on " + entity + " has disallowed value " + val);
+            }
+        });
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
index 2bd0c00..006b95a 100644
--- a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
+++ b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
@@ -1415,5 +1415,5 @@ brooklyn.management.internal.UsageManager
 brooklyn.policy.basic.ConfigMapImpl                                              : org.apache.brooklyn.core.objs.AdjunctConfigMap
 brooklyn.util.internal.Repeater                                                  : org.apache.brooklyn.util.core.internal.Repeater
 brooklyn.entity.nosql.redis.RedisClusterImpl                                     : org.apache.brooklyn.entity.nosql.redis.RedisClusterImpl
-brooklyn.test.TrustingSslSocketFactory                                           : org.apache.brooklyn.test.TrustingSslSocketFactory
+brooklyn.test.TrustingSslSocketFactory                                           : org.apache.brooklyn.util.http.TrustingSslSocketFactory
 brooklyn.util.crypto.TrustingSslSocketFactory                                    : org.apache.brooklyn.util.crypto.TrustingSslSocketFactory

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
new file mode 100644
index 0000000..563b0ea
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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 org.apache.brooklyn.core.entity;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.entity.group.DynamicGroup;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests on {@link EntityAsserts}.
+ */
+public class EntityAssertsTest extends BrooklynAppUnitTestSupport {
+
+    private static final int TIMEOUT_MS = 10*1000;
+    private static final String STOOGE = "stooge";
+
+    private SimulatedLocation loc;
+    private TestEntity entity;
+    private ScheduledExecutorService executor;
+    private DynamicGroup stooges;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        loc = app.getManagementContext().getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        stooges = app.createAndManageChild(EntitySpec.create(DynamicGroup.class));
+        final EntitySpec<TestEntity> stooge =
+                EntitySpec.create(TestEntity.class).configure(TestEntity.CONF_NAME, STOOGE);
+        app.createAndManageChild(stooge);
+        app.createAndManageChild(stooge);
+        app.createAndManageChild(stooge);
+        app.start(ImmutableList.of(loc));
+        executor = Executors.newScheduledThreadPool(3);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (executor != null) executor.shutdownNow();
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+        super.tearDown();
+    }
+
+
+    @Test
+    public void shouldAssertAttributeEquals() {
+        final String myName = "myname";
+        entity.sensors().set(TestEntity.NAME, myName);
+        EntityAsserts.assertAttributeEquals(entity, TestEntity.NAME, myName);
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldFailToAssertAttributeEquals() {
+        final String myName = "myname";
+        entity.sensors().set(TestEntity.NAME, myName);
+        EntityAsserts.assertAttributeEquals(entity, TestEntity.NAME, "bogus");
+    }
+
+    @Test
+    public void shouldAssertConfigEquals() {
+        EntityAsserts.assertConfigEquals(entity, TestEntity.CONF_NAME, "defaultval");
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldFailToAssertConfigEquals() {
+        EntityAsserts.assertConfigEquals(entity, TestEntity.CONF_NAME, "bogus");
+    }
+
+    @Test
+    public void shouldAssertAttributeEqualsEventually() {
+        entity.sensors().set(TestEntity.NAME, "before");
+        final String after = "after";
+        setSensorValueLater(TestEntity.NAME, after, Duration.seconds(2));
+        EntityAsserts.assertAttributeEqualsEventually(entity, TestEntity.NAME, after);
+    }
+
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldFailToAssertAttributeEqualsEventually() {
+        entity.sensors().set(TestEntity.NAME, "before");
+        final String after = "after";
+        setSensorValueLater(TestEntity.NAME, after, Duration.seconds(2));
+        EntityAsserts.assertAttributeEqualsEventually(ImmutableMap.of("timeout", "1s"), entity, TestEntity.NAME, after);
+    }
+
+    private <T> void setSensorValueLater(final AttributeSensor<T> sensor, final T value, final Duration delay) {
+        executor.schedule(new Runnable() {
+            @Override
+            public void run() {
+                entity.sensors().set(sensor, value);
+            }
+        }, delay.toUnit(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
+    }
+
+    @Test
+    public void shouldAssertAttributeEventuallyNonNull() {
+        EntityAsserts.assertAttributeEquals(entity, TestEntity.NAME, null);
+        setSensorValueLater(TestEntity.NAME, "something", Duration.seconds(1));
+        EntityAsserts.assertAttributeEventuallyNonNull(entity, TestEntity.NAME);
+    }
+
+    @Test
+    public void shouldAssertAttributeEventually() {
+        setSensorValueLater(TestEntity.NAME, "testing testing 123", Duration.seconds(1));
+        EntityAsserts.assertAttributeEventually(entity, TestEntity.NAME, new Predicate<String>() {
+            @Override
+            public boolean apply(String input) {
+                return input.matches(".*\\d+");
+            }
+        });
+    }
+
+    @Test
+    public void shouldAssertAttribute() {
+        final String before = "before";
+        entity.sensors().set(TestEntity.NAME, before);
+        EntityAsserts.assertAttribute(entity, TestEntity.NAME, Predicates.equalTo(before));
+    }
+
+    @Test
+    public void shouldAssertPredicateEventuallyTrue() {
+        final int testVal = 987654321;
+        executor.schedule(new Runnable() {
+            @Override
+            public void run() {
+                entity.setSequenceValue(testVal);
+            }
+        }, 1, TimeUnit.SECONDS);
+        EntityAsserts.assertPredicateEventuallyTrue(entity, new Predicate<TestEntity>() {
+            @Override
+            public boolean apply(TestEntity input) {
+                return testVal == input.getSequenceValue() ;
+            }
+        });
+    }
+
+    @Test
+    public void shouldAssertAttributeEqualsContinually() {
+        final String myName = "myname";
+        entity.sensors().set(TestEntity.NAME, myName);
+        EntityAsserts.assertAttributeEqualsContinually(
+                ImmutableMap.of("timeout", "2s"), entity, TestEntity.NAME, myName);
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldFailAssertAttributeEqualsContinually() {
+        final String myName = "myname";
+        entity.sensors().set(TestEntity.NAME, myName);
+        setSensorValueLater(TestEntity.NAME, "something", Duration.seconds(1));
+        EntityAsserts.assertAttributeEqualsContinually(
+                ImmutableMap.of("timeout", "2s"), entity, TestEntity.NAME, myName);
+    }
+
+    @Test
+    public void shouldAssertGroupSizeEqualsEventually() {
+        setGroupFilterLater(STOOGE, 1);
+        EntityAsserts.assertGroupSizeEqualsEventually(ImmutableMap.of("timeout", "2s"), stooges, 3);
+        setGroupFilterLater("Marx Brother", 1);
+        EntityAsserts.assertGroupSizeEqualsEventually(stooges, 0);
+    }
+
+    private void setGroupFilterLater(final String conf, long delaySeconds) {
+        executor.schedule(new Runnable() {
+            @Override
+            public void run() {
+                stooges.setEntityFilter(EntityPredicates.configEqualTo(TestEntity.CONF_NAME, conf));
+            }
+        }, delaySeconds, TimeUnit.SECONDS);
+    }
+
+    @Test
+    public void shouldAssertAttributeChangesEventually () {
+        entity.sensors().set(TestEntity.NAME, "before");
+        setSensorValueLater(TestEntity.NAME, "after", Duration.seconds(2));
+        EntityAsserts.assertAttributeChangesEventually(entity, TestEntity.NAME);
+    }
+
+    @Test
+    public void shouldAssertAttributeNever() {
+        entity.sensors().set(TestEntity.NAME, "ever");
+        EntityAsserts.assertAttributeNever(ImmutableMap.of("timeout", "5s"), entity, TestEntity.NAME, "after");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
index 3baa26d..6a72324 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
@@ -36,7 +36,6 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.test.Asserts;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
@@ -46,6 +45,12 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+/**
+ * A utility class containing tests on Entities.
+ *
+ * @deprecated Prefer core assertions org.apache.brooklyn.entity.EntityAsserts.
+ */
+@Deprecated
 public class EntityTestUtils {
 
     // TODO would be nice to have this... perhaps moving this class, or perhaps this whole project, to core/src/test ?
@@ -55,11 +60,11 @@ public class EntityTestUtils {
     // and deprecate methods in TestUtils until deleted).
     
     public static <T> void assertAttributeEquals(Entity entity, AttributeSensor<T> attribute, T expected) {
-        assertEquals(entity.getAttribute(attribute), expected, "entity="+entity+"; attribute="+attribute);
+        assertEquals(entity.getAttribute(attribute), expected, "entity=" + entity + "; attribute=" + attribute);
     }
     
     public static <T> void assertConfigEquals(Entity entity, ConfigKey<T> configKey, T expected) {
-        assertEquals(entity.getConfig(configKey), expected, "entity="+entity+"; configKey="+configKey);
+        assertEquals(entity.getConfig(configKey), expected, "entity=" + entity + "; configKey=" + configKey);
     }
     
     public static <T> void assertAttributeEqualsEventually(final Entity entity, final AttributeSensor<T> attribute, final T expected) {
@@ -68,10 +73,12 @@ public class EntityTestUtils {
 
     public static <T> void assertAttributeEqualsEventually(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, final T expected) {
         // Not using assertAttributeEventually(predicate) so get nicer error message
-        Asserts.succeedsEventually((Map)flags, new Runnable() {
-            @Override public void run() {
+        Asserts.succeedsEventually((Map) flags, new Runnable() {
+            @Override
+            public void run() {
                 assertAttributeEquals(entity, attribute, expected);
-            }});
+            }
+        });
     }
 
     public static <T> T assertAttributeEventuallyNonNull(final Entity entity, final AttributeSensor<T> attribute) {
@@ -108,10 +115,12 @@ public class EntityTestUtils {
     }
 
     public static <T extends Entity> void assertPredicateEventuallyTrue(Map<?,?> flags, final T entity, final Predicate<? super T> predicate) {
-        Asserts.succeedsEventually((Map)flags, new Runnable() {
-                @Override public void run() {
-                    assertTrue(predicate.apply(entity));
-                }});
+        Asserts.succeedsEventually((Map) flags, new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(predicate.apply(entity));
+            }
+        });
     }
 
     public static <T> void assertAttributeEqualsContinually(final Entity entity, final AttributeSensor<T> attribute, final T expected) {
@@ -120,9 +129,11 @@ public class EntityTestUtils {
     
     public static <T> void assertAttributeEqualsContinually(Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, final T expected) {
         Asserts.succeedsContinually(flags, new Runnable() {
-                @Override public void run() {
-                    assertAttributeEquals(entity, attribute, expected);
-                }});
+            @Override
+            public void run() {
+                assertAttributeEquals(entity, attribute, expected);
+            }
+        });
     }
 
     public static void assertGroupSizeEqualsEventually(final Group group, int expected) {
@@ -130,11 +141,13 @@ public class EntityTestUtils {
     }
     
     public static void assertGroupSizeEqualsEventually(Map<?,?> flags, final Group group, final int expected) {
-        Asserts.succeedsEventually((Map)flags, new Runnable() {
-            @Override public void run() {
+        Asserts.succeedsEventually((Map) flags, new Runnable() {
+            @Override
+            public void run() {
                 Collection<Entity> members = group.getMembers();
-                assertEquals(members.size(), expected, "members="+members);
-            }});
+                assertEquals(members.size(), expected, "members=" + members);
+            }
+        });
     }
 
     /** checks that the entity's value for this attribute changes, by registering a subscription and checking the value */
@@ -161,8 +174,8 @@ public class EntityTestUtils {
      * with simpler code, for comparison */
     @Beta
     public static <T> void assertAttributeChangesEventually2(final Entity entity, final AttributeSensor<T> attribute) {
-        assertAttributeEventually(entity, attribute, 
-            Predicates.not(Predicates.equalTo(entity.getAttribute(attribute))));
+        assertAttributeEventually(entity, attribute,
+                Predicates.not(Predicates.equalTo(entity.getAttribute(attribute))));
     }
 
     @Beta

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
index eed5ef4..c0089bd 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.crypto.SslTrustUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.http.TrustingSslSocketFactory;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.time.Time;
 import org.slf4j.Logger;
@@ -59,7 +60,10 @@ import com.google.common.util.concurrent.ListeningExecutorService;
  * Utility methods to aid testing HTTP.
  * 
  * @author aled
+ *
+ * @deprecated Prefer org.apache.brooklyn.util.http.HttpUtils which has no TestNG dependencies.
  */
+@Deprecated
 public class HttpTestUtils {
 
     // TODO Delete methods from TestUtils, to just have them here (or switch so TestUtils delegates here,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/usage/test-support/src/main/java/org/apache/brooklyn/test/TrustingSslSocketFactory.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/TrustingSslSocketFactory.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/TrustingSslSocketFactory.java
deleted file mode 100644
index 58fb76c..0000000
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/TrustingSslSocketFactory.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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 org.apache.brooklyn.test;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URLConnection;
-import java.net.UnknownHostException;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Throwables;
-
-// FIXME copied from brooklyn-core because core not visible here
-
-public class TrustingSslSocketFactory extends SSLSocketFactory {
-    
-    private static final Logger logger = LoggerFactory.getLogger(TrustingSslSocketFactory.class);
-
-    private static TrustingSslSocketFactory INSTANCE;
-    public synchronized static TrustingSslSocketFactory getInstance() {
-        if (INSTANCE==null) INSTANCE = new TrustingSslSocketFactory();
-        return INSTANCE;
-    }
-    
-    private static SSLContext sslContext; 
-    static {
-        try {
-            sslContext = SSLContext.getInstance("TLS");
-        } catch (Exception e) {
-            logger.error("Unable to set up SSLContext with TLS. Https activity will likely fail.", e);
-        }
-    }
-
-    /** configures a connection to accept all certificates, if it is for https */
-    public static <T extends URLConnection> T configure(T connection) {
-        if (connection instanceof HttpsURLConnection) {
-            ((HttpsURLConnection)connection).setSSLSocketFactory(getInstance());
-        }
-        return connection;
-    }
-    
-    /** trusts all SSL certificates */
-    public static final TrustManager TRUST_ALL = new X509TrustManager() {
-        public X509Certificate[] getAcceptedIssuers() {
-            return new X509Certificate[0];
-        }
-        @Override
-        public void checkClientTrusted(X509Certificate[] chain, String authType)
-                throws java.security.cert.CertificateException {
-            
-        }
-        @Override
-        public void checkServerTrusted(X509Certificate[] chain, String authType)
-                throws java.security.cert.CertificateException {
-        }
-    };
-
-    // no reason this can't be public, but no reason it should be necessary;
-    // just use getInstance to get the shared INSTANCE
-    protected TrustingSslSocketFactory() {
-        super();
-        try {
-            sslContext.init(null, new TrustManager[] { TRUST_ALL }, null);
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    @Override
-    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
-        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
-    }
-
-    @Override
-    public Socket createSocket() throws IOException {
-        return sslContext.getSocketFactory().createSocket();
-    }
-
-    @Override
-    public String[] getDefaultCipherSuites() {
-        return sslContext.getSocketFactory().getDefaultCipherSuites();
-    }
-
-    @Override
-    public String[] getSupportedCipherSuites() {
-        return sslContext.getSocketFactory().getSupportedCipherSuites();
-    }
-
-    @Override
-    public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
-        return sslContext.getSocketFactory().createSocket(arg0, arg1);
-    }
-
-    @Override
-    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
-        return sslContext.getSocketFactory().createSocket(arg0, arg1);
-    }
-
-    @Override
-    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException {
-        return sslContext.getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
-    }
-
-    @Override
-    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
-        return sslContext.getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
index 0bf6936..678a181 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.test;
 
 import groovy.lang.Closure;
 
+import java.lang.reflect.Array;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
@@ -52,8 +53,14 @@ import com.google.common.collect.Sets;
  * TODO should move this to new package brooklyn.util.assertions
  * and TODO should add a repeating() method which returns an AssertingRepeater extending Repeater
  * and:
+ * <ul>
  * <li> adds support for requireAllIterationsTrue
  * <li> convenience run methods equivalent to succeedsEventually and succeedsContinually
+ * </ul>
+ * <p>
+ * NOTE Selected routines in this class are originally copied from <a href="http://testng.org">TestNG</a>, to allow us to make assertions without having to
+ * introduce a runtime dependency on TestNG.
+ * </p>
  */
 @Beta
 public class Asserts {
@@ -67,9 +74,608 @@ public class Asserts {
     private static final Logger log = LoggerFactory.getLogger(Asserts.class);
 
     private Asserts() {}
+
+    private static final Character OPENING_CHARACTER = '[';
+    private static final Character CLOSING_CHARACTER = ']';
+
+    private static final String ASSERT_LEFT = "expected " + OPENING_CHARACTER;
+    private static final String ASSERT_MIDDLE = CLOSING_CHARACTER + " but found " + OPENING_CHARACTER;
+    private static final String ASSERT_RIGHT = Character.toString(CLOSING_CHARACTER);
+
+    static String format(Object actual, Object expected, String message) {
+        String formatted = "";
+        if (null != message) {
+            formatted = message + " ";
+        }
+
+        return formatted + ASSERT_LEFT + expected + ASSERT_MIDDLE + actual + ASSERT_RIGHT;
+    }
+
+    static private void failNotEquals(Object actual , Object expected, String message ) {
+        fail(format(actual, expected, message));
+    }
+
+    /**
+     * Assert that an object reference is null.
+     *
+     * @param object The object reference.
+     *
+     * @throws AssertionError if the assertion fails.
+     */
+    static public void assertNull(final Object object) {
+        assertNull(object, null);
+    }
+
+    /**
+     * Assert that an object reference is not null.
+     *
+     * @param object The object reference.
+     *
+     * @throws AssertionError if the assertion fails.
+     */
+    static public void assertNotNull(final Object object) {
+        assertNotNull(object, null);
+    }
+
+    /**
+     * Assert that an object reference is null.
+     *
+     * @param object The object reference.
+     * @param message The assertion error message.
+     *
+     * @throws AssertionError if the assertion fails.
+     */
+    static public void assertNull(final Object object, final String message) {
+        if (null != object) {
+            throw new AssertionError(message == null ? "object reference is not null" : message);
+        }
+    }
+
+    /**
+     * Assert that an object reference is not null.
+     *
+     * @param object The object reference.
+     * @param message The assertion error message.
+     *
+     * @throws AssertionError if the assertion fails.
+     */
+    static public void assertNotNull(final Object object, final String message) {
+        if (null == object) {
+            throw new AssertionError(message == null ? "object reference is null" : message);
+        }
+    }
+
+    /**
+     * Asserts that two collections contain the same elements in the same order. If they do not,
+     * an AssertionError is thrown.
+     *
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(Collection<?> actual, Collection<?> expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two collections contain the same elements in the same order. If they do not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(Collection<?> actual, Collection<?> expected, String message) {
+        if(actual == expected) {
+            return;
+        }
+
+        if (actual == null || expected == null) {
+            if (message != null) {
+                fail(message);
+            } else {
+                fail("Collections not equal: expected: " + expected + " and actual: " + actual);
+            }
+        }
+
+        assertEquals(actual.size(), expected.size(), message + ": lists don't have the same size");
+
+        Iterator<?> actIt = actual.iterator();
+        Iterator<?> expIt = expected.iterator();
+        int i = -1;
+        while(actIt.hasNext() && expIt.hasNext()) {
+            i++;
+            Object e = expIt.next();
+            Object a = actIt.next();
+            String explanation = "Lists differ at element [" + i + "]: " + e + " != " + a;
+            String errorMessage = message == null ? explanation : message + ": " + explanation;
+
+            assertEquals(a, e, errorMessage);
+        }
+    }
+
+    /** Asserts that two iterators return the same elements in the same order. If they do not,
+     * an AssertionError is thrown.
+     * Please note that this assert iterates over the elements and modifies the state of the iterators.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(Iterator<?> actual, Iterator<?> expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /** Asserts that two iterators return the same elements in the same order. If they do not,
+     * an AssertionError, with the given message, is thrown.
+     * Please note that this assert iterates over the elements and modifies the state of the iterators.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(Iterator<?> actual, Iterator<?> expected, String message) {
+        if(actual == expected) {
+            return;
+        }
+
+        if(actual == null || expected == null) {
+            if(message != null) {
+                fail(message);
+            } else {
+                fail("Iterators not equal: expected: " + expected + " and actual: " + actual);
+            }
+        }
+
+        int i = -1;
+        while(actual.hasNext() && expected.hasNext()) {
+
+            i++;
+            Object e = expected.next();
+            Object a = actual.next();
+            String explanation = "Iterators differ at element [" + i + "]: " + e + " != " + a;
+            String errorMessage = message == null ? explanation : message + ": " + explanation;
+
+            assertEquals(a, e, errorMessage);
+
+        }
+
+        if(actual.hasNext()) {
+
+            String explanation = "Actual iterator returned more elements than the expected iterator.";
+            String errorMessage = message == null ? explanation : message + ": " + explanation;
+            fail(errorMessage);
+
+        } else if(expected.hasNext()) {
+
+            String explanation = "Expected iterator returned more elements than the actual iterator.";
+            String errorMessage = message == null ? explanation : message + ": " + explanation;
+            fail(errorMessage);
+
+        }
+
+    }
+
+    /** Asserts that two iterables return iterators with the same elements in the same order. If they do not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(Iterable<?> actual, Iterable<?> expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /** Asserts that two iterables return iterators with the same elements in the same order. If they do not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(Iterable<?> actual, Iterable<?> expected, String message) {
+        if(actual == expected) {
+            return;
+        }
+
+        if(actual == null || expected == null) {
+            if(message != null) {
+                fail(message);
+            } else {
+                fail("Iterables not equal: expected: " + expected + " and actual: " + actual);
+            }
+        }
+
+        Iterator<?> actIt = actual.iterator();
+        Iterator<?> expIt = expected.iterator();
+
+        assertEquals(actIt, expIt, message);
+    }
+
+
+
+    /**
+     * Asserts that two sets are equal.
+     */
+    static public void assertEquals(Set<?> actual, Set<?> expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Assert set equals
+     */
+    static public void assertEquals(Set<?> actual, Set<?> expected, String message) {
+        if (actual == expected) {
+            return;
+        }
+
+        if (actual == null || expected == null) {
+            // Keep the back compatible
+            if (message == null) {
+                fail("Sets not equal: expected: " + expected + " and actual: " + actual);
+            } else {
+                failNotEquals(actual, expected, message);
+            }
+        }
+
+        if (!actual.equals(expected)) {
+            if (message == null) {
+                fail("Sets differ: expected " + expected + " but got " + actual);
+            } else {
+                failNotEquals(actual, expected, message);
+            }
+        }
+    }
+
+    /**
+     * Asserts that two maps are equal.
+     */
+    static public void assertEquals(Map<?, ?> actual, Map<?, ?> expected) {
+        if (actual == expected) {
+            return;
+        }
+
+        if (actual == null || expected == null) {
+            fail("Maps not equal: expected: " + expected + " and actual: " + actual);
+        }
+
+        if (actual.size() != expected.size()) {
+            fail("Maps do not have the same size:" + actual.size() + " != " + expected.size());
+        }
+
+        Set<?> entrySet = actual.entrySet();
+        for (Iterator<?> iterator = entrySet.iterator(); iterator.hasNext();) {
+            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) iterator.next();
+            Object key = entry.getKey();
+            Object value = entry.getValue();
+            Object expectedValue = expected.get(key);
+            assertEquals(value, expectedValue, "Maps do not match for key:" + key + " actual:" + value
+                    + " expected:" + expectedValue);
+        }
+
+    }
+
+
+    /**
+     * Asserts that two arrays contain the same elements in the same order. If they do not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(Object[] actual, Object[] expected, String message) {
+        if(actual == expected) {
+            return;
+        }
+
+        if ((actual == null && expected != null) || (actual != null && expected == null)) {
+            if (message != null) {
+                fail(message);
+            } else {
+                fail("Arrays not equal: " + Arrays.toString(expected) + " and " + Arrays.toString(actual));
+            }
+        }
+        assertEquals(Arrays.asList(actual), Arrays.asList(expected), message);
+    }
+
+    /**
+     * Asserts that two arrays contain the same elements in the same order. If they do not,
+     * an AssertionError is thrown.
+     *
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(Object[] actual, Object[] expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two objects are equal. 
+     * @param actual the actual value
+     * @param expected the expected value
+     *                 
+     * @throws AssertionError if the values are not equal.
+     */
+    static public void assertEquals(Object actual, Object expected) {
+        assertEquals(actual, expected, null);
+    }
     
-    // --- selected routines from testng.Assert for visibility without needing that package
-    
+    /**
+     * Asserts that two objects are equal. 
+     * 
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     *
+     * @throws AssertionError if the values are not equal.
+     */
+    static public void assertEquals(Object actual, Object expected, String message) {
+        if((expected == null) && (actual == null)) {
+            return;
+        }
+        if(expected != null) {
+            if (expected.getClass().isArray()) {
+                assertArrayEquals(actual, expected, message);
+                return;
+            } else if (expected.equals(actual)) {
+                return;
+            }
+        }
+        failNotEquals(actual, expected, message);
+    }
+
+
+    /**
+     * Asserts that two objects are equal. It they are not, an AssertionError,
+     * with given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value (should be an non-null array value)
+     * @param message the assertion error message
+     */
+    private static void assertArrayEquals(Object actual, Object expected, String message) {
+        //is called only when expected is an array
+        if (actual.getClass().isArray()) {
+            int expectedLength = Array.getLength(expected);
+            if (expectedLength == Array.getLength(actual)) {
+                for (int i = 0 ; i < expectedLength ; i++) {
+                    Object _actual = Array.get(actual, i);
+                    Object _expected = Array.get(expected, i);
+                    try {
+                        assertEquals(_actual, _expected);
+                    } catch (AssertionError ae) {
+                        failNotEquals(actual, expected, message == null ? "" : message
+                                + " (values at index " + i + " are not the same)");
+                    }
+                }
+                //array values matched
+                return;
+            } else {
+                failNotEquals(Array.getLength(actual), expectedLength, message == null ? "" : message
+                        + " (Array lengths are not the same)");
+            }
+        }
+        failNotEquals(actual, expected, message);
+    }
+
+
+    /**
+     * Asserts that two Strings are equal. If they are not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(String actual, String expected, String message) {
+        assertEquals((Object) actual, (Object) expected, message);
+    }
+
+    /**
+     * Asserts that two Strings are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(String actual, String expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two doubles are equal within a delta.  If they are not,
+     * an AssertionError, with the given message, is thrown.  If the expected
+     * value is infinity then the delta value is ignored.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param delta the absolute tolerable difference between the actual and expected values
+     * @param message the assertion error message
+     */
+    static public void assertEquals(double actual, double expected, double delta, String message) {
+        // handle infinity specially since subtracting to infinite values gives NaN and the
+        // the following test fails
+        if(Double.isInfinite(expected)) {
+            if(!(expected == actual)) {
+                failNotEquals(new Double(actual), new Double(expected), message);
+            }
+        }
+        else if(!(Math.abs(expected - actual) <= delta)) { // Because comparison with NaN always returns false
+            failNotEquals(new Double(actual), new Double(expected), message);
+        }
+    }
+
+    /**
+     * Asserts that two doubles are equal within a delta. If they are not,
+     * an AssertionError is thrown. If the expected value is infinity then the
+     * delta value is ignored.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param delta the absolute tolerable difference between the actual and expected values
+     */
+    static public void assertEquals(double actual, double expected, double delta) {
+        assertEquals(actual, expected, delta, null);
+    }
+
+    /**
+     * Asserts that two floats are equal within a delta. If they are not,
+     * an AssertionError, with the given message, is thrown.  If the expected
+     * value is infinity then the delta value is ignored.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param delta the absolute tolerable difference between the actual and expected values
+     * @param message the assertion error message
+     */
+    static public void assertEquals(float actual, float expected, float delta, String message) {
+        // handle infinity specially since subtracting to infinite values gives NaN and the
+        // the following test fails
+        if(Float.isInfinite(expected)) {
+            if(!(expected == actual)) {
+                failNotEquals(new Float(actual), new Float(expected), message);
+            }
+        }
+        else if(!(Math.abs(expected - actual) <= delta)) {
+            failNotEquals(new Float(actual), new Float(expected), message);
+        }
+    }
+
+    /**
+     * Asserts that two floats are equal within a delta. If they are not,
+     * an AssertionError is thrown. If the expected
+     * value is infinity then the delta value is ignored.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param delta the absolute tolerable difference between the actual and expected values
+     */
+    static public void assertEquals(float actual, float expected, float delta) {
+        assertEquals(actual, expected, delta, null);
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(long actual, long expected, String message) {
+        assertEquals(Long.valueOf(actual), Long.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two longs are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(long actual, long expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two booleans are equal. If they are not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(boolean actual, boolean expected, String message) {
+        assertEquals( Boolean.valueOf(actual), Boolean.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two booleans are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(boolean actual, boolean expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two bytes are equal. If they are not,
+     * an AssertionError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(byte actual, byte expected, String message) {
+        assertEquals(Byte.valueOf(actual), Byte.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two bytes are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(byte actual, byte expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two chars are equal. If they are not,
+     * an AssertionFailedError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(char actual, char expected, String message) {
+        assertEquals(Character.valueOf(actual), Character.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two chars are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(char actual, char expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two shorts are equal. If they are not,
+     * an AssertionFailedError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(short actual, short expected, String message) {
+        assertEquals(Short.valueOf(actual), Short.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two shorts are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(short actual, short expected) {
+        assertEquals(actual, expected, null);
+    }
+
+    /**
+     * Asserts that two ints are equal. If they are not,
+     * an AssertionFailedError, with the given message, is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     * @param message the assertion error message
+     */
+    static public void assertEquals(int actual,  int expected, String message) {
+        assertEquals(Integer.valueOf(actual), Integer.valueOf(expected), message);
+    }
+
+    /**
+     * Asserts that two ints are equal. If they are not,
+     * an AssertionError is thrown.
+     * @param actual the actual value
+     * @param expected the expected value
+     */
+    static public void assertEquals(int actual, int expected) {
+        assertEquals(actual, expected, null);
+    }
+
+
+
+    /**
+     * Asserts that a condition is true. If it isn't, an AssertionError is thrown.
+     * @param condition the condition to evaluate
+     */
+    public static void assertTrue(boolean condition) {
+        if (!condition) fail(null);
+    }
+
     /**
      * Asserts that a condition is true. If it isn't,
      * an AssertionError, with the given message, is thrown.
@@ -214,7 +820,7 @@ public class Asserts {
     /**
      * Convenience method for cases where we need to test until something is true.
      *
-     * The runnable will be invoked periodically until it succesfully concludes.
+     * The Callable will be invoked periodically until it succesfully concludes.
      * <p>
      * The following flags are supported:
      * <ul>
@@ -233,8 +839,7 @@ public class Asserts {
      * </ul>
      * 
      * @param flags, accepts the flags listed above
-     * @param r
-     * @param finallyBlock
+     * @param c The callable to invoke
      */
     public static <T> T succeedsEventually(Map<String,?> flags, Callable<T> c) {
         boolean abortOnException = get(flags, "abortOnException", false);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
new file mode 100644
index 0000000..8eeef19
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
@@ -0,0 +1,387 @@
+/*
+ * 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 org.apache.brooklyn.util.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.crypto.SslTrustUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * Utility methods to aid testing HTTP.
+ * 
+ * @author aled
+ */
+public class HttpUtils {
+
+    // TODO Delete methods from TestUtils, to just have them here (or switch so TestUtils delegates here,
+    // and deprecate methods in TestUtils until deleted).
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class);
+
+    static final ExecutorService executor = Executors.newCachedThreadPool();
+    
+    /**
+     * Connects to the given url and returns the connection.
+     * Caller should {@code connection.getInputStream().close()} the result of this
+     * (especially if they are making heavy use of this method).
+     */
+    public static URLConnection connectToUrl(String u) throws Exception {
+        final URL url = new URL(u);
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+        
+        // sometimes openConnection hangs, so run in background
+        Future<URLConnection> f = executor.submit(new Callable<URLConnection>() {
+            public URLConnection call() {
+                try {
+                    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+                        @Override public boolean verify(String s, SSLSession sslSession) {
+                            return true;
+                        }
+                    });
+                    URLConnection connection = url.openConnection();
+                    TrustingSslSocketFactory.configure(connection);
+                    connection.connect();
+    
+                    connection.getContentLength(); // Make sure the connection is made.
+                    return connection;
+                } catch (Exception e) {
+                    exception.set(e);
+                    LOG.debug("Error connecting to url "+url+" (propagating): "+e, e);
+                }
+                return null;
+            }
+        });
+        try {
+            URLConnection result = null;
+            try {
+                result = f.get(60, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                throw e;
+            } catch (Exception e) {
+                LOG.debug("Error connecting to url "+url+", probably timed out (rethrowing): "+e);
+                throw new IllegalStateException("Connect to URL not complete within 60 seconds, for url "+url+": "+e);
+            }
+            if (exception.get() != null) {
+                LOG.debug("Error connecting to url "+url+", thread caller of "+exception, new Throwable("source of rethrown error "+exception));
+                throw exception.get();
+            } else {
+                return result;
+            }
+        } finally {
+            f.cancel(true);
+        }
+    }
+
+    public static void assertHealthyStatusCode(int code) {
+        if (code>=200 && code<=299) return;
+        Asserts.fail("Wrong status code: " + code);
+    }
+    
+    public static int getHttpStatusCode(String url) throws Exception {
+        URLConnection connection = connectToUrl(url);
+        long startTime = System.currentTimeMillis();
+        int status = ((HttpURLConnection) connection).getResponseCode();
+        
+        // read fully if possible, then close everything, trying to prevent cached threads at server
+        consumeAndCloseQuietly((HttpURLConnection) connection);
+        
+        if (LOG.isDebugEnabled())
+            LOG.debug("connection to {} ({}ms) gives {}", new Object[] { url, (System.currentTimeMillis()-startTime), status });
+        return status;
+    }
+
+    /**
+     * Asserts that gets back any "valid" response - i.e. not an exception. This could be an unauthorized,
+     * a redirect, a 404, or anything else that implies there is web-server listening on that port.
+     */
+    public static void assertUrlReachable(String url) {
+        try {
+            getHttpStatusCode(url);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that is reachable)", e);
+        } catch (Exception e) {
+            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that is reachable): "+e, e);
+        }
+    }
+
+    public static void assertUrlUnreachable(String url) {
+        try {
+            int statusCode = getHttpStatusCode(url);
+            Asserts.fail("Expected url " + url + " unreachable, but got status code " + statusCode);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that unreachable)", e);
+        } catch (Exception e) {
+            IOException cause = Exceptions.getFirstThrowableOfType(e, IOException.class);
+            if (cause != null) {
+                // success; clean shutdown transitioning from 400 to error
+            } else {
+                Throwables.propagate(e);
+            }                        
+        }
+    }
+
+    public static void assertUrlUnreachableEventually(final String url) {
+        assertUrlUnreachableEventually(Maps.newLinkedHashMap(), url);
+    }
+    
+    public static void assertUrlUnreachableEventually(Map flags, final String url) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertUrlUnreachable(url);
+            }
+         });
+    }
+
+    public static void assertHttpStatusCodeEquals(String url, int... acceptableReturnCodes) {
+        List<Integer> acceptableCodes = Lists.newArrayList();
+        for (int code : acceptableReturnCodes) {
+            acceptableCodes.add((Integer)code);
+        }
+        try {
+            int actualCode = getHttpStatusCode(url);
+            Asserts.assertTrue(acceptableCodes.contains(actualCode), "code=" + actualCode + "; expected=" + acceptableCodes + "; url=" + url);
+            
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that result code is "+acceptableCodes+")", e);
+        } catch (Exception e) {
+            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that result code is "+acceptableCodes+"): "+e, e);
+        }
+    }
+
+    public static void assertHttpStatusCodeEventuallyEquals(final String url, final int expectedCode) {
+        assertHttpStatusCodeEventuallyEquals(Maps.newLinkedHashMap(),  url, expectedCode);
+    }
+
+    public static void assertHttpStatusCodeEventuallyEquals(Map flags, final String url, final int expectedCode) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertHttpStatusCodeEquals(url, expectedCode);
+            }
+         });
+    }
+
+    public static void assertContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = getContent(url);
+            Asserts.assertTrue(contents != null && contents.length() > 0);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (!contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" does not contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public static void assertContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = getContent(url);
+            Asserts.assertTrue(contents != null);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public static void assertErrorContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = getErrorContent(url);
+            Asserts.assertTrue(contents != null && contents.length() > 0);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (!contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" does not contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+
+    public static void assertErrorContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String err = getErrorContent(url);
+            Asserts.assertTrue(err != null);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (err.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+err);
+                    Asserts.fail("URL "+url+" contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+    
+    public static void assertContentEventuallyContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        assertContentEventuallyContainsText(MutableMap.of(), url, phrase, additionalPhrases);
+    }
+    
+    public static void assertContentEventuallyContainsText(Map flags, final String url, final String phrase, final String ...additionalPhrases) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertContentContainsText(url, phrase, additionalPhrases);
+            }
+         });
+    }
+    
+    public static void assertContentMatches(String url, String regex) {
+        String contents = getContent(url);
+        Asserts.assertNotNull(contents);
+        Asserts.assertTrue(contents.matches(regex), "Contents does not match expected regex ("+regex+"): "+contents);
+    }
+
+    public static void assertContentEventuallyMatches(final String url, final String regex) {
+        Asserts.succeedsEventually(new Runnable() {
+            @Override
+            public void run() {
+                assertContentMatches(url, regex);
+            }
+        });
+    }
+    
+    public static String getErrorContent(String url) {
+        try {
+            HttpURLConnection connection = (HttpURLConnection) connectToUrl(url);
+            long startTime = System.currentTimeMillis();
+            
+            String err;
+            int status;
+            try {
+                InputStream errStream = connection.getErrorStream();
+                err = Streams.readFullyString(errStream);
+                status = connection.getResponseCode();
+            } finally {
+                closeQuietly(connection);
+            }
+            
+            if (LOG.isDebugEnabled())
+                LOG.debug("read of err {} ({}ms) complete; http code {}", new Object[] { url, Time.makeTimeStringRounded(System.currentTimeMillis()-startTime), status});
+            return err;
+
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+    
+    public static String getContent(String url) {
+        try {
+            return Streams.readFullyString(SslTrustUtils.trustAll(new URL(url).openConnection()).getInputStream());
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /**
+     * Schedules (with the given executor) a poller that repeatedly accesses the given url, to confirm it always gives
+     * back the expected status code.
+     * 
+     * Expected usage is to query the future, such as:
+     * 
+     * <pre>
+     * {@code
+     * Future<?> future = assertAsyncHttpStatusCodeContinuallyEquals(executor, url, 200);
+     * // do other stuff...
+     * if (future.isDone()) future.get(); // get exception if it's Asserts.failed
+     * }
+     * </pre>
+     * 
+     * For stopping it, you can either do future.cancel(true), or you can just do executor.shutdownNow().
+     * 
+     * TODO Look at difference between this and WebAppMonitor, to decide if this should be kept.
+     */
+    public static ListenableFuture<?> assertAsyncHttpStatusCodeContinuallyEquals(ListeningExecutorService executor, final String url, final int expectedStatusCode) {
+        return executor.submit(new Runnable() {
+            @Override public void run() {
+                // TODO Need to drop logging; remove sleep when that's done.
+                while (!Thread.currentThread().isInterrupted()) {
+                    assertHttpStatusCodeEquals(url, expectedStatusCode);
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        return; // graceful return
+                    }
+                }
+            }
+        });
+    }
+    
+    /**
+     * Consumes the input stream entirely and then cleanly closes the connection.
+     * Ignores all exceptions completely, not even logging them!
+     * 
+     * Consuming the stream fully is useful for preventing idle TCP connections.
+     * @see <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html">Persistent Connections</a>
+     */
+    public static void consumeAndCloseQuietly(HttpURLConnection connection) {
+        try { Streams.readFully(connection.getInputStream()); } catch (Exception e) {}
+        closeQuietly(connection);
+    }
+    
+    /**
+     * Closes all streams of the connection, and disconnects it. Ignores all exceptions completely,
+     * not even logging them!
+     */
+    public static void closeQuietly(HttpURLConnection connection) {
+        try { connection.disconnect(); } catch (Exception e) {}
+        try { connection.getInputStream().close(); } catch (Exception e) {}
+        try { connection.getOutputStream().close(); } catch (Exception e) {}
+        try { connection.getErrorStream().close(); } catch (Exception e) {}
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c316e217/utils/common/src/main/java/org/apache/brooklyn/util/http/TrustingSslSocketFactory.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/TrustingSslSocketFactory.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/TrustingSslSocketFactory.java
new file mode 100644
index 0000000..41b753a
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/TrustingSslSocketFactory.java
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.brooklyn.util.http;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Throwables;
+
+// FIXME copied from brooklyn-core because core not visible here
+
+public class TrustingSslSocketFactory extends SSLSocketFactory {
+    
+    private static final Logger logger = LoggerFactory.getLogger(TrustingSslSocketFactory.class);
+
+    private static TrustingSslSocketFactory INSTANCE;
+    public synchronized static TrustingSslSocketFactory getInstance() {
+        if (INSTANCE==null) INSTANCE = new TrustingSslSocketFactory();
+        return INSTANCE;
+    }
+    
+    private static SSLContext sslContext; 
+    static {
+        try {
+            sslContext = SSLContext.getInstance("TLS");
+        } catch (Exception e) {
+            logger.error("Unable to set up SSLContext with TLS. Https activity will likely fail.", e);
+        }
+    }
+
+    /** configures a connection to accept all certificates, if it is for https */
+    public static <T extends URLConnection> T configure(T connection) {
+        if (connection instanceof HttpsURLConnection) {
+            ((HttpsURLConnection)connection).setSSLSocketFactory(getInstance());
+        }
+        return connection;
+    }
+    
+    /** trusts all SSL certificates */
+    public static final TrustManager TRUST_ALL = new X509TrustManager() {
+        public X509Certificate[] getAcceptedIssuers() {
+            return new X509Certificate[0];
+        }
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+                throws java.security.cert.CertificateException {
+            
+        }
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+                throws java.security.cert.CertificateException {
+        }
+    };
+
+    // no reason this can't be public, but no reason it should be necessary;
+    // just use getInstance to get the shared INSTANCE
+    protected TrustingSslSocketFactory() {
+        super();
+        try {
+            sslContext.init(null, new TrustManager[] { TRUST_ALL }, null);
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    @Override
+    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
+        return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+    }
+
+    @Override
+    public Socket createSocket() throws IOException {
+        return sslContext.getSocketFactory().createSocket();
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites() {
+        return sslContext.getSocketFactory().getDefaultCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites() {
+        return sslContext.getSocketFactory().getSupportedCipherSuites();
+    }
+
+    @Override
+    public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
+        return sslContext.getSocketFactory().createSocket(arg0, arg1);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
+        return sslContext.getSocketFactory().createSocket(arg0, arg1);
+    }
+
+    @Override
+    public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) throws IOException, UnknownHostException {
+        return sslContext.getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
+        return sslContext.getSocketFactory().createSocket(arg0, arg1, arg2, arg3);
+    }
+}
\ No newline at end of file


[6/9] incubator-brooklyn git commit: Add unit tests for HttpAsserts.

Posted by he...@apache.org.
Add unit tests for HttpAsserts.


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

Branch: refs/heads/master
Commit: 885b6ac47c4a72a400ef16c9a11555f1e980eb64
Parents: 70a7189
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Tue Nov 3 17:13:44 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Tue Nov 3 17:38:11 2015 +0000

----------------------------------------------------------------------
 .../core/sensor/http/HttpRequestSensorTest.java |   5 +-
 .../core/test/TestHttpRequestHandler.java       |  72 -----
 .../brooklyn/core/test/TestHttpServer.java      | 143 ---------
 .../util/core/ResourceUtilsHttpTest.java        |   5 +-
 .../rest/resources/CatalogResetTest.java        |   4 +-
 utils/common/pom.xml                            |   8 +-
 .../test/http/TestHttpRequestHandler.java       |  72 +++++
 .../brooklyn/test/http/TestHttpServer.java      | 146 +++++++++
 .../apache/brooklyn/util/http/HttpAsserts.java  | 108 +++++--
 .../apache/brooklyn/util/HttpAssertsTest.java   | 293 +++++++++++++++++++
 10 files changed, 600 insertions(+), 256 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/core/src/test/java/org/apache/brooklyn/core/sensor/http/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/sensor/http/HttpRequestSensorTest.java b/core/src/test/java/org/apache/brooklyn/core/sensor/http/HttpRequestSensorTest.java
index 0e7495f..20169a9 100644
--- a/core/src/test/java/org/apache/brooklyn/core/sensor/http/HttpRequestSensorTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/sensor/http/HttpRequestSensorTest.java
@@ -25,9 +25,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.sensor.http.HttpRequestSensor;
-import org.apache.brooklyn.core.test.TestHttpRequestHandler;
-import org.apache.brooklyn.core.test.TestHttpServer;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.test.EntityTestUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/core/src/test/java/org/apache/brooklyn/core/test/TestHttpRequestHandler.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/TestHttpRequestHandler.java b/core/src/test/java/org/apache/brooklyn/core/test/TestHttpRequestHandler.java
deleted file mode 100644
index d4ab712..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/TestHttpRequestHandler.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 org.apache.brooklyn.core.test;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpRequestHandler;
-
-public class TestHttpRequestHandler implements HttpRequestHandler {
-    private HttpEntity entity;
-    private int responseCode = HttpStatus.SC_OK;
-    private Collection<Header> headers = new ArrayList<Header>();
-
-    public TestHttpRequestHandler response(String response) {
-        try {
-            this.entity = new StringEntity(response);
-        } catch (UnsupportedEncodingException e) {
-            throw Exceptions.propagate(e);
-        }
-        return this;
-    }
-
-    public TestHttpRequestHandler code(int responseCode) {
-        this.responseCode = responseCode;
-        return this;
-    }
-
-    public TestHttpRequestHandler header(String name, String value) {
-        headers.add(new BasicHeader(name, value));
-        return this;
-    }
-
-    @Override
-    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
-        for (Header h : headers) {
-            response.setHeader(h);
-        }
-
-        response.setStatusCode(responseCode);
-        response.setEntity(entity);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/core/src/test/java/org/apache/brooklyn/core/test/TestHttpServer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/TestHttpServer.java b/core/src/test/java/org/apache/brooklyn/core/test/TestHttpServer.java
deleted file mode 100644
index a9eb7df..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/test/TestHttpServer.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 org.apache.brooklyn.core.test;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.net.Networking;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponseInterceptor;
-import org.apache.http.impl.bootstrap.HttpServer;
-import org.apache.http.impl.bootstrap.ServerBootstrap;
-import org.apache.http.protocol.HttpProcessor;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.ImmutableHttpProcessor;
-import org.apache.http.protocol.ResponseConnControl;
-import org.apache.http.protocol.ResponseContent;
-
-public class TestHttpServer {
-    private static class HandlerTuple {
-        String path;
-        HttpRequestHandler handler;
-        public HandlerTuple(String path, HttpRequestHandler handler) {
-            this.path = path;
-            this.handler = handler;
-        }
-    }
-    private HttpServer server;
-    private List<HttpRequestInterceptor> requestInterceptors = MutableList.of();
-    private List<HttpResponseInterceptor> responseInterceptors = MutableList.of(new ResponseContent(), new ResponseConnControl());
-    private int basePort = 50505;
-    private Collection<HandlerTuple> handlers = MutableList.of();
-
-    public TestHttpServer interceptor(HttpResponseInterceptor interceptor) {
-        checkNotStarted();
-        responseInterceptors.add(interceptor);
-        return this;
-    }
-
-    public TestHttpServer requestInterceptors(List<HttpResponseInterceptor> interceptors) {
-        checkNotStarted();
-        this.responseInterceptors = interceptors;
-        return this;
-    }
-
-    public TestHttpServer interceptor(HttpRequestInterceptor interceptor) {
-        checkNotStarted();
-        requestInterceptors.add(interceptor);
-        return this;
-    }
-
-    public TestHttpServer responseInterceptors(List<HttpRequestInterceptor> interceptors) {
-        checkNotStarted();
-        this.requestInterceptors = interceptors;
-        return this;
-    }
-
-    public TestHttpServer basePort(int basePort) {
-        checkNotStarted();
-        this.basePort = basePort;
-        return this;
-    }
-
-    public TestHttpServer handler(String path, HttpRequestHandler handler) {
-        checkNotStarted();
-        handlers.add(new HandlerTuple(path, handler));
-        return this;
-    }
-
-    public TestHttpServer start() {
-        checkNotStarted();
-
-        HttpProcessor httpProcessor = new ImmutableHttpProcessor(requestInterceptors, responseInterceptors);
-        int port = Networking.nextAvailablePort(basePort);
-        ServerBootstrap bootstrap = ServerBootstrap.bootstrap()
-            .setListenerPort(port)
-            .setLocalAddress(getLocalAddress())
-            .setHttpProcessor(httpProcessor);
-
-        for (HandlerTuple tuple : handlers) {
-            bootstrap.registerHandler(tuple.path, tuple.handler);
-        }
-        server = bootstrap.create();
-
-        try {
-            server.start();
-        } catch (IOException e) {
-            throw Exceptions.propagate(e);
-        }
-
-        return this;
-    }
-
-    public void stop() {
-        server.stop();
-    }
-
-    private void checkNotStarted() {
-        if (server != null) {
-            throw new IllegalStateException("Server already started");
-        }
-    }
-
-    private InetAddress getLocalAddress() {
-        try {
-            return InetAddress.getLocalHost();
-        } catch (UnknownHostException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    public String getUrl() {
-        try {
-            return new URL("http", server.getInetAddress().getHostAddress(), server.getLocalPort(), "").toExternalForm();
-        } catch (MalformedURLException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/core/src/test/java/org/apache/brooklyn/util/core/ResourceUtilsHttpTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/ResourceUtilsHttpTest.java b/core/src/test/java/org/apache/brooklyn/util/core/ResourceUtilsHttpTest.java
index c1cebb8..0952707 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/ResourceUtilsHttpTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/ResourceUtilsHttpTest.java
@@ -24,9 +24,8 @@ import static org.testng.Assert.assertFalse;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.brooklyn.core.test.TestHttpRequestHandler;
-import org.apache.brooklyn.core.test.TestHttpServer;
-import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.http.HttpException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
index 6adfdb5..c0e0089 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
@@ -27,8 +27,8 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
-import org.apache.brooklyn.core.test.TestHttpRequestHandler;
-import org.apache.brooklyn.core.test.TestHttpServer;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
 import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
 import org.apache.brooklyn.util.core.ResourceUtils;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/utils/common/pom.xml
----------------------------------------------------------------------
diff --git a/utils/common/pom.xml b/utils/common/pom.xml
index 8bc0ae9..037dcd9 100644
--- a/utils/common/pom.xml
+++ b/utils/common/pom.xml
@@ -66,7 +66,13 @@
             <artifactId>snakeyaml</artifactId>
             <version>${snakeyaml.version}</version>
         </dependency>
-        
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
new file mode 100644
index 0000000..18f5c44
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
@@ -0,0 +1,72 @@
+/*
+ * 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 org.apache.brooklyn.test.http;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+
+public class TestHttpRequestHandler implements HttpRequestHandler {
+    private HttpEntity entity;
+    private int responseCode = HttpStatus.SC_OK;
+    private Collection<Header> headers = new ArrayList<Header>();
+
+    public TestHttpRequestHandler response(String response) {
+        try {
+            this.entity = new StringEntity(response);
+        } catch (UnsupportedEncodingException e) {
+            throw Exceptions.propagate(e);
+        }
+        return this;
+    }
+
+    public TestHttpRequestHandler code(int responseCode) {
+        this.responseCode = responseCode;
+        return this;
+    }
+
+    public TestHttpRequestHandler header(String name, String value) {
+        headers.add(new BasicHeader(name, value));
+        return this;
+    }
+
+    @Override
+    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
+        for (Header h : headers) {
+            response.setHeader(h);
+        }
+
+        response.setStatusCode(responseCode);
+        response.setEntity(entity);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
new file mode 100644
index 0000000..75f5e60
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
@@ -0,0 +1,146 @@
+/*
+ * 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 org.apache.brooklyn.test.http;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.net.Networking;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.impl.bootstrap.HttpServer;
+import org.apache.http.impl.bootstrap.ServerBootstrap;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+
+public class TestHttpServer {
+    private static class HandlerTuple {
+        String path;
+        HttpRequestHandler handler;
+        public HandlerTuple(String path, HttpRequestHandler handler) {
+            this.path = path;
+            this.handler = handler;
+        }
+    }
+    private HttpServer server;
+    private List<HttpRequestInterceptor> requestInterceptors = MutableList.of();
+    private List<HttpResponseInterceptor> responseInterceptors = MutableList.of(new ResponseContent(), new ResponseConnControl());
+    private int basePort = 50505;
+    private Collection<HandlerTuple> handlers = MutableList.of();
+
+    public TestHttpServer interceptor(HttpResponseInterceptor interceptor) {
+        checkNotStarted();
+        responseInterceptors.add(interceptor);
+        return this;
+    }
+
+    public TestHttpServer requestInterceptors(List<HttpResponseInterceptor> interceptors) {
+        checkNotStarted();
+        this.responseInterceptors = interceptors;
+        return this;
+    }
+
+    public TestHttpServer interceptor(HttpRequestInterceptor interceptor) {
+        checkNotStarted();
+        requestInterceptors.add(interceptor);
+        return this;
+    }
+
+    public TestHttpServer responseInterceptors(List<HttpRequestInterceptor> interceptors) {
+        checkNotStarted();
+        this.requestInterceptors = interceptors;
+        return this;
+    }
+
+    public TestHttpServer basePort(int basePort) {
+        checkNotStarted();
+        this.basePort = basePort;
+        return this;
+    }
+
+    public TestHttpServer handler(String path, HttpRequestHandler handler) {
+        checkNotStarted();
+        handlers.add(new HandlerTuple(path, handler));
+        return this;
+    }
+
+    public TestHttpServer start() {
+        checkNotStarted();
+
+        HttpProcessor httpProcessor = new ImmutableHttpProcessor(requestInterceptors, responseInterceptors);
+        int port = Networking.nextAvailablePort(basePort);
+        ServerBootstrap bootstrap = ServerBootstrap.bootstrap()
+            .setListenerPort(port)
+            .setLocalAddress(getLocalAddress())
+            .setHttpProcessor(httpProcessor);
+
+        for (HandlerTuple tuple : handlers) {
+            bootstrap.registerHandler(tuple.path, tuple.handler);
+        }
+        server = bootstrap.create();
+
+        try {
+            server.start();
+        } catch (IOException e) {
+            throw Exceptions.propagate(e);
+        }
+
+        return this;
+    }
+
+    public void stop() {
+        if (null != server) {
+            server.stop();
+            server = null;
+        }
+    }
+
+    private void checkNotStarted() {
+        if (server != null) {
+            throw new IllegalStateException("Server already started");
+        }
+    }
+
+    private InetAddress getLocalAddress() {
+        try {
+            return InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    public String getUrl() {
+        try {
+            return new URL("http", server.getInetAddress().getHostAddress(), server.getLocalPort(), "").toExternalForm();
+        } catch (MalformedURLException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
index 35d8252..0479b79 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
@@ -52,7 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
- * Utility methods to aid testing HTTP.
+ * Utility assertions on HTTP.
  * 
  * @author aled
  */
@@ -63,31 +63,26 @@ public class HttpAsserts {
 
     private static final Logger LOG = LoggerFactory.getLogger(HttpAsserts.class);
 
+    /**
+     * Assert that a 'successful' (2xx) status code has been provided.
+     *
+     * @param code The status code.
+     */
     public static void assertHealthyStatusCode(int code) {
         if (code>=200 && code<=299) return;
         Asserts.fail("Wrong status code: " + code);
     }
     
-    public static int getHttpStatusCode(String url) throws Exception {
-        URLConnection connection = HttpTool.connectToUrl(url);
-        long startTime = System.currentTimeMillis();
-        int status = ((HttpURLConnection) connection).getResponseCode();
-        
-        // read fully if possible, then close everything, trying to prevent cached threads at server
-        HttpTool.consumeAndCloseQuietly((HttpURLConnection) connection);
-        
-        if (LOG.isDebugEnabled())
-            LOG.debug("connection to {} ({}ms) gives {}", new Object[] { url, (System.currentTimeMillis()-startTime), status });
-        return status;
-    }
 
     /**
      * Asserts that gets back any "valid" response - i.e. not an exception. This could be an unauthorized,
      * a redirect, a 404, or anything else that implies there is web-server listening on that port.
+     *
+     * @param url The URL to connect to.
      */
     public static void assertUrlReachable(String url) {
         try {
-            getHttpStatusCode(url);
+            HttpTool.getHttpStatusCode(url);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new RuntimeException("Interrupted for "+url+" (in assertion that is reachable)", e);
@@ -96,9 +91,15 @@ public class HttpAsserts {
         }
     }
 
+    /**
+     * Asserts that the URL could not be reached, detected as an IOException.
+     *
+     * @param url The URL to connect to.
+     */
+
     public static void assertUrlUnreachable(String url) {
         try {
-            int statusCode = getHttpStatusCode(url);
+            int statusCode = HttpTool.getHttpStatusCode(url);
             Asserts.fail("Expected url " + url + " unreachable, but got status code " + statusCode);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
@@ -108,30 +109,49 @@ public class HttpAsserts {
             if (cause != null) {
                 // success; clean shutdown transitioning from 400 to error
             } else {
-                Throwables.propagate(e);
+                propagateAsAssertionError(e);
             }                        
         }
     }
 
+    /**
+     * Asserts that the URL becomes unreachable within a default time period.
+     *
+     * @param url The URL
+     */
     public static void assertUrlUnreachableEventually(final String url) {
         assertUrlUnreachableEventually(Maps.newLinkedHashMap(), url);
     }
-    
+
+
+    /**
+     * Asserts that the URL becomes unreachable within a configurable time period.
+     *
+     * @param flags The flags controlling the timeout.
+     *              For details see {@link org.apache.brooklyn.test.Asserts#succeedsEventually(java.util.Map, java.util.concurrent.Callable)}
+     * @param url The URL
+     */
     public static void assertUrlUnreachableEventually(Map flags, final String url) {
-        Asserts.succeedsEventually(flags, new Runnable() {
+        assertEventually(flags, new Runnable() {
             public void run() {
                 assertUrlUnreachable(url);
             }
-         });
+        });
     }
 
+    /**
+     * Assert that the status code returned from the URL is in the given codes.
+     *
+     * @param url The URL to get.
+     * @param acceptableReturnCodes The return codes that are expected.
+     */
     public static void assertHttpStatusCodeEquals(String url, int... acceptableReturnCodes) {
         List<Integer> acceptableCodes = Lists.newArrayList();
         for (int code : acceptableReturnCodes) {
             acceptableCodes.add((Integer)code);
         }
         try {
-            int actualCode = getHttpStatusCode(url);
+            int actualCode = HttpTool.getHttpStatusCode(url);
             Asserts.assertTrue(acceptableCodes.contains(actualCode), "code=" + actualCode + "; expected=" + acceptableCodes + "; url=" + url);
             
         } catch (InterruptedException e) {
@@ -147,11 +167,11 @@ public class HttpAsserts {
     }
 
     public static void assertHttpStatusCodeEventuallyEquals(Map flags, final String url, final int expectedCode) {
-        Asserts.succeedsEventually(flags, new Runnable() {
+        assertEventually(flags, new Runnable() {
             public void run() {
                 assertHttpStatusCodeEquals(url, expectedCode);
             }
-         });
+        });
     }
 
     public static void assertContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
@@ -165,7 +185,7 @@ public class HttpAsserts {
                 }
             }
         } catch (Exception e) {
-            throw Throwables.propagate(e);
+            throw propagateAsAssertionError(e);
         }
     }
 
@@ -180,7 +200,7 @@ public class HttpAsserts {
                 }
             }
         } catch (Exception e) {
-            throw Throwables.propagate(e);
+            throw propagateAsAssertionError(e);
         }
     }
 
@@ -195,7 +215,7 @@ public class HttpAsserts {
                 }
             }
         } catch (Exception e) {
-            throw Throwables.propagate(e);
+            throw propagateAsAssertionError(e);
         }
     }
 
@@ -211,22 +231,43 @@ public class HttpAsserts {
                 }
             }
         } catch (Exception e) {
-            throw Throwables.propagate(e);
+            throw propagateAsAssertionError(e);
         }
     }
-    
+
+    private static AssertionError propagateAsAssertionError(Exception e) {
+        final AssertionError assertionError = new AssertionError("Assertion failed", e);
+        return assertionError;
+    }
+
     public static void assertContentEventuallyContainsText(final String url, final String phrase, final String ...additionalPhrases) {
         assertContentEventuallyContainsText(MutableMap.of(), url, phrase, additionalPhrases);
     }
     
     public static void assertContentEventuallyContainsText(Map flags, final String url, final String phrase, final String ...additionalPhrases) {
-        Asserts.succeedsEventually(flags, new Runnable() {
+        assertEventually(flags, new Runnable() {
             public void run() {
                 assertContentContainsText(url, phrase, additionalPhrases);
             }
-         });
+        });
     }
-    
+
+    private static void assertEventually(Map flags, Runnable r) {
+        try {
+            Asserts.succeedsEventually(flags, r);
+        } catch (Exception e) {
+            throw propagateAsAssertionError(e);
+        }
+    }
+
+    private static void assertEventually(Runnable r) {
+        try {
+            Asserts.succeedsEventually(r);
+        } catch (Exception e) {
+            throw propagateAsAssertionError(e);
+        }
+    }
+
     public static void assertContentMatches(String url, String regex) {
         String contents = HttpTool.getContent(url);
         Asserts.assertNotNull(contents);
@@ -234,7 +275,7 @@ public class HttpAsserts {
     }
 
     public static void assertContentEventuallyMatches(final String url, final String regex) {
-        Asserts.succeedsEventually(new Runnable() {
+        assertEventually(new Runnable() {
             @Override
             public void run() {
                 assertContentMatches(url, regex);
@@ -243,7 +284,7 @@ public class HttpAsserts {
     }
 
     public static void assertContentEventuallyMatches(Map<String,?> flags, final String url, final String regex) {
-        Asserts.succeedsEventually(flags, new Runnable() {
+        assertEventually(flags, new Runnable() {
             @Override
             public void run() {
                 assertContentMatches(url, regex);
@@ -266,6 +307,9 @@ public class HttpAsserts {
      * if (future.isDone()) future.get(); // get exception if it's Asserts.failed
      * }
      * </pre>
+     *
+     * NOTE that the exception thrown by future.get() is a java.util.concurrent.ExecutionException,
+     * not an AssertionError.
      * 
      * For stopping it, you can either do future.cancel(true), or you can just do executor.shutdownNow().
      * 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/885b6ac4/utils/common/src/test/java/org/apache/brooklyn/util/HttpAssertsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/HttpAssertsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/HttpAssertsTest.java
new file mode 100644
index 0000000..3b0c7c1
--- /dev/null
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/HttpAssertsTest.java
@@ -0,0 +1,293 @@
+/*
+ * 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 org.apache.brooklyn.util;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.http.HttpAsserts;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.localserver.RequestBasicAuth;
+import org.apache.http.localserver.ResponseBasicUnauthorized;
+import org.apache.http.protocol.ResponseServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.*;
+
+import java.net.URI;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by geoff on 03/11/2015.
+ */
+public class HttpAssertsTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpAssertsTest.class);
+    HttpClient httpClient;
+    URI baseUri;
+    private TestHttpServer server;
+    private String baseUrl;
+    private ScheduledExecutorService executor;
+
+
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        server = initializeServer();
+        baseUrl = server.getUrl();
+        httpClient = HttpTool.httpClientBuilder()
+            .uri(baseUrl)
+            .build();
+        baseUri = URI.create(baseUrl);
+        executor = Executors.newScheduledThreadPool(3);
+        TimeUnit.SECONDS.sleep(2);
+    }
+
+    private TestHttpServer initializeServer() {
+        return new TestHttpServer()
+            .interceptor(new ResponseServer())
+            .interceptor(new ResponseBasicUnauthorized())
+            .interceptor(new RequestBasicAuth())
+            .handler("/simple", new TestHttpRequestHandler().response("OK"))
+            .handler("/empty", new TestHttpRequestHandler().code(HttpStatus.SC_NO_CONTENT))
+            .handler("/missing", new TestHttpRequestHandler().code(HttpStatus.SC_NOT_FOUND).response("Missing"))
+            .handler("/redirect", new TestHttpRequestHandler().code(HttpStatus.SC_MOVED_TEMPORARILY).response("Redirect").header("Location", "/simple"))
+            .handler("/cycle", new TestHttpRequestHandler().code(HttpStatus.SC_MOVED_TEMPORARILY).response("Redirect").header("Location", "/cycle"))
+            .handler("/secure", new TestHttpRequestHandler().code(HttpStatus.SC_MOVED_TEMPORARILY).response("Redirect").header("Location", "https://0.0.0.0/"))
+            .start();
+    }
+
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws Exception {
+        if (executor != null) executor.shutdownNow();
+        server.stop();
+        TimeUnit.SECONDS.sleep(2);
+    }
+
+    // schedule a stop of server after n seconds
+    private void stopAfter(int delay) {
+        executor.schedule(new Runnable() {
+            @Override
+            public void run() {
+                server.stop();
+            }
+        }, delay, TimeUnit.SECONDS);
+    }
+
+    // stop server and pause to wait for it to finish
+    private void stopServer() {
+        server.stop();
+        try {
+            TimeUnit.SECONDS.sleep(2);
+        } catch (InterruptedException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    // schedule a start of server after n seconds
+    private void startAfter(int delay) {
+        executor.schedule(new Runnable() {
+            @Override
+            public void run() {
+                server = initializeServer();
+            }
+        }, delay, TimeUnit.SECONDS);
+    }
+
+    private HttpToolResponse doGet(String str) {
+        final URI address = baseUri.resolve(str);
+        return HttpTool.httpGet(httpClient, address,
+            ImmutableMap.<String, String>of());
+    }
+
+    @Test
+    public void shouldAssertHealthyStatusCode() {
+        final HttpToolResponse response = doGet("/simple");
+        HttpAsserts.assertHealthyStatusCode(response.getResponseCode());
+    }
+
+    @Test
+    public void shouldAssertUrlReachable() {
+        HttpAsserts.assertUrlReachable(baseUrl);
+    }
+
+    @Test
+    public void shouldAssertUrlUnreachable() {
+        stopServer();
+        HttpAsserts.assertUrlUnreachable(testUri("/simple"));
+    }
+
+    @Test
+    public void shouldAssertUrlUnreachableEventually() {
+        HttpAsserts.assertUrlReachable(baseUrl);
+        stopAfter(1);
+        HttpAsserts.assertUrlUnreachableEventually(baseUrl);
+    }
+
+    @Test
+    public void shouldAssertUrlUnreachableEventuallyWithFlags() throws Exception {
+        stopAfter(5);
+        TimeUnit.SECONDS.sleep(3);
+        HttpAsserts.assertUrlReachable(baseUrl);
+        HttpAsserts.assertUrlUnreachableEventually(ImmutableMap.of("timeout", "10s"), baseUrl);
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldAssertUrlUnreachableEventuallyWithTimeout() throws Exception {
+        HttpAsserts.assertUrlReachable(baseUrl);
+        HttpAsserts.assertUrlUnreachableEventually(ImmutableMap.of("timeout", "3s"), baseUrl);
+    }
+
+
+    @Test
+    public void shouldAssertHttpStatusCodeEquals() {
+        HttpAsserts.assertHttpStatusCodeEquals(baseUrl, 500, 501);
+        HttpAsserts.assertHttpStatusCodeEquals(testUri("/simple"), 201, 200);
+        HttpAsserts.assertHttpStatusCodeEquals(testUri("/missing"), 400, 404);
+    }
+
+    @Test
+    public void shouldAssertHttpStatusCodeEventuallyEquals() throws Exception {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(2);
+        HttpAsserts.assertHttpStatusCodeEventuallyEquals(simple, 200);
+    }
+
+    private String testUri(String str) {
+        return baseUri.resolve(str).toString();
+    }
+
+    @Test
+    public void shouldAssertContentContainsText() {
+        HttpAsserts.assertContentContainsText(testUri("/simple"), "OK");
+    }
+
+    @Test
+    public void shouldAssertContentNotContainsText() {
+        HttpAsserts.assertContentNotContainsText(testUri("/simple"), "Bad");
+    }
+
+    @Test
+    public void shouldAssertErrorContentsContainsText() {
+        HttpAsserts.assertErrorContentContainsText(testUri("/missing"), "Missing");
+    }
+
+    @Test
+    public void shouldAssertErrorContentNotContainsText() {
+        HttpAsserts.assertErrorContentNotContainsText(testUri("/missing"), "Bogus");
+    }
+
+    @Test
+    public void shouldAssertContentEventuallyContainsText() {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(2);
+        HttpAsserts.assertContentEventuallyContainsText(simple, "OK");
+    }
+
+    @Test
+    public void shouldAssertContentEventuallyContainsTextWithFlags() {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(2);
+        HttpAsserts.assertContentEventuallyContainsText(ImmutableMap.of("timeout", "3s"), simple, "OK");
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldAssertContentEventuallyContainsTextWithTimeout() {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(4);
+        HttpAsserts.assertContentEventuallyContainsText(ImmutableMap.of("timeout", "3s"), simple, "OK");
+    }
+
+
+    @Test
+    public void shouldAssertContentMatches() {
+        HttpAsserts.assertContentMatches(testUri("/simple"), "[Oo][Kk]");
+    }
+
+    @Test
+    public void shouldAssertContentEventuallyMatches() throws Exception {
+        stopServer();
+        TimeUnit.SECONDS.sleep(2);
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        TimeUnit.SECONDS.sleep(2);
+        startAfter(2);
+        HttpAsserts.assertContentEventuallyMatches(testUri("/simple"), "[Oo][Kk]");
+    }
+
+    @Test
+    public void shouldAssertContentEventuallyMatchesWithFlags() {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(2);
+        HttpAsserts.assertContentEventuallyMatches(ImmutableMap.of("timeout", "3s"), testUri("/simple"), "[Oo][Kk]");
+    }
+
+    @Test(expectedExceptions = AssertionError.class)
+    public void shouldAssertContentEventuallyMatchesWithTimeout() {
+        stopServer();
+        final String simple = testUri("/simple");
+        HttpAsserts.assertUrlUnreachable(simple);
+        startAfter(4);
+        HttpAsserts.assertContentEventuallyMatches(ImmutableMap.of("timeout", "3s"), testUri("/simple"), "[Oo][Kk]");
+    }
+
+    @Test
+    public void shouldAssertAsyncHttpStatusCodeContinuallyEquals() throws Exception {
+        ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+        final ListenableFuture<?> future =
+            HttpAsserts.assertAsyncHttpStatusCodeContinuallyEquals(listeningExecutor, testUri("/simple"), 200);
+        TimeUnit.SECONDS.sleep(3);
+        if (future.isDone()) {
+            future.get(); // should not throw exception
+        }
+        future.cancel(true);
+    }
+
+    @Test(expectedExceptions = ExecutionException.class)
+    public void shouldAssertAsyncHttpStatusCodeContinuallyEqualsFails() throws Exception {
+        ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+        final ListenableFuture<?> future =
+            HttpAsserts.assertAsyncHttpStatusCodeContinuallyEquals(listeningExecutor, testUri("/missing"), 200);
+        TimeUnit.SECONDS.sleep(3);
+        if (future.isDone()) {
+            future.get(); // should throw exception
+        }
+        future.cancel(true);
+    }
+}



[4/9] incubator-brooklyn git commit: Merge remote-tracking branch 'mccabe/eventualregex' into decouple-test-utils

Posted by he...@apache.org.
Merge remote-tracking branch 'mccabe/eventualregex' into decouple-test-utils


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

Branch: refs/heads/master
Commit: a1e21b3a2eec6281961044656dcf890dd3744329
Parents: 03dbd28 e1edc98
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Mon Nov 2 20:00:03 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Mon Nov 2 20:00:03 2015 +0000

----------------------------------------------------------------------
 .../org/apache/brooklyn/test/HttpTestUtils.java | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1e21b3a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
----------------------------------------------------------------------


[8/9] incubator-brooklyn git commit: Further updates in response to additional comments on pull request.

Posted by he...@apache.org.
Further updates in response to additional comments on pull request.

Added TrustingSslSocketFactory to deserializingClassRenames.properties (https://github.com/apache/incubator-brooklyn/pull/994#commitcomment-14139640)

Added back an HttpTool and HttpToolResponse in the old location, with @Deprecated markers, for backward compatibility (https://github.com/apache/incubator-brooklyn/pull/994#issuecomment-153171583)

Added "since 0.9.0" to classes I have deprecated (https://github.com/apache/incubator-brooklyn/pull/994#discussion_r43803617)


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

Branch: refs/heads/master
Commit: c46624060c72aacd50b640d7744af93f791efce8
Parents: 019666c
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Tue Nov 3 21:02:13 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Tue Nov 3 21:02:13 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/util/core/http/HttpTool.java       | 85 ++++++++++++++++++++
 .../util/core/http/HttpToolResponse.java        | 35 ++++++++
 .../deserializingClassRenames.properties        |  4 +-
 .../apache/brooklyn/test/EntityTestUtils.java   |  2 +-
 .../org/apache/brooklyn/test/HttpTestUtils.java |  2 +-
 .../org/apache/brooklyn/util/http/HttpTool.java |  3 +
 .../brooklyn/util/http/HttpToolResponse.java    |  3 +
 7 files changed, 131 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
new file mode 100644
index 0000000..f2ed019
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.brooklyn.util.core.http;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.net.URI;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.brooklyn.util.crypto.SslTrustUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.net.URLParamEncoder;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeSocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.LaxRedirectStrategy;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+
+/**
+ * @deprecated since 0.9.0. Prefer org.apache.brooklyn.util.http.HttpTool
+ */
+@Deprecated
+public class HttpTool extends org.apache.brooklyn.util.http.HttpTool {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
new file mode 100644
index 0000000..2b3f73f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.brooklyn.util.core.http;
+
+
+import org.apache.brooklyn.feed.http.HttpPollValue;
+import org.apache.http.HttpResponse;
+
+/**
+ * @deprecated since 0.9.0 Prefer org.apache.brooklyn.util.http.HttpToolResponse
+ */
+@Deprecated
+public class HttpToolResponse extends org.apache.brooklyn.util.http.HttpToolResponse
+    implements HttpPollValue {
+
+    public HttpToolResponse(HttpResponse response, long startTime) {
+        super(response, startTime);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
index 2503425..a5801c9 100644
--- a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
+++ b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
@@ -1418,4 +1418,6 @@ brooklyn.entity.nosql.redis.RedisClusterImpl
 brooklyn.test.TrustingSslSocketFactory                                           : org.apache.brooklyn.util.http.TrustingSslSocketFactory
 brooklyn.util.crypto.TrustingSslSocketFactory                                    : org.apache.brooklyn.util.crypto.TrustingSslSocketFactory
 
-org.apache.brooklyn.test.TrustingSslSocketFactory                                : org.apache.brooklyn.util.http.TrustingSslSocketFactory
\ No newline at end of file
+org.apache.brooklyn.test.TrustingSslSocketFactory                                : org.apache.brooklyn.util.http.TrustingSslSocketFactory
+org.apache.brooklyn.util.core.http.HttpTool                                      : org.apache.brooklyn.util.http.HttpTool
+org.apache.brooklyn.util.core.http.HttpToolResponse                              : org.apache.brooklyn.util.http.HttpToolResponse

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
index 5b1e22b..71c2f64 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
@@ -48,7 +48,7 @@ import com.google.common.collect.Sets;
 /**
  * A utility class containing tests on Entities.
  *
- * @deprecated Prefer core assertions class org.apache.brooklyn.core.entity.EntityAsserts.
+ * @deprecated since 0.9.0. Prefer core assertions class org.apache.brooklyn.core.entity.EntityAsserts.
  */
 @Deprecated
 public class EntityTestUtils {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
index 869cb1e..91a1f0e 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
@@ -59,7 +59,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
  * 
  * @author aled
  *
- * @deprecated Prefer org.apache.brooklyn.util.http.HttpAsserts which has no TestNG dependencies.
+ * @deprecated since 0.9.0. Prefer org.apache.brooklyn.util.http.HttpAsserts which has no TestNG dependencies.
  */
 @Deprecated
 public class HttpTestUtils {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
index 8811a32..b9167c7 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
@@ -89,6 +89,9 @@ import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLSession;
 
+/**
+ * A utility tool for HTTP operations.
+ */
 public class HttpTool {
 
     private static final Logger LOG = LoggerFactory.getLogger(HttpTool.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c4662406/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
index 70bcb17..811b3e1 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
@@ -42,6 +42,9 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.common.io.ByteStreams;
 
+/**
+ * A response class for use with {@link HttpTool}.
+ */
 public class HttpToolResponse {
 
     private static final Logger log = LoggerFactory.getLogger(HttpToolResponse.class);


[9/9] incubator-brooklyn git commit: This closes #994

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


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

Branch: refs/heads/master
Commit: a5040934de597c7057314400347e82533d4d0cac
Parents: 48e4fe3 c466240
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Nov 4 10:47:32 2015 -0500
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Nov 4 10:47:32 2015 -0500

----------------------------------------------------------------------
 .../brooklyn/core/entity/EntityAsserts.java     | 228 +++++++
 .../org/apache/brooklyn/feed/http/HttpFeed.java |   6 +-
 .../brooklyn/feed/http/HttpPollConfig.java      |   4 +-
 .../brooklyn/feed/http/HttpPollValue.java       |   2 +-
 .../apache/brooklyn/feed/http/HttpPolls.java    |   4 +-
 .../brooklyn/feed/http/HttpValueFunctions.java  |   2 +-
 .../brooklyn/util/core/ResourceUtils.java       |   5 +-
 .../brooklyn/util/core/http/HttpTool.java       | 313 +---------
 .../util/core/http/HttpToolResponse.java        | 163 +----
 .../deserializingClassRenames.properties        |  10 +-
 .../brooklyn/core/entity/EntityAssertsTest.java | 217 +++++++
 .../core/sensor/http/HttpRequestSensorTest.java |   5 +-
 .../core/test/TestHttpRequestHandler.java       |  72 ---
 .../brooklyn/core/test/TestHttpServer.java      | 143 -----
 .../apache/brooklyn/feed/http/HttpFeedTest.java |   5 +-
 .../feed/http/HttpValueFunctionsTest.java       |   3 +-
 .../util/core/ResourceUtilsHttpTest.java        |   5 +-
 .../util/core/http/HttpToolIntegrationTest.java |   4 +-
 .../persist/jclouds/BlobStoreExpiryTest.java    |   4 +-
 .../brooklynnode/BrooklynEntityMirrorImpl.java  |   2 +-
 .../entity/brooklynnode/BrooklynNodeImpl.java   |   2 +-
 .../entity/brooklynnode/EntityHttpClient.java   |   4 +-
 .../brooklynnode/EntityHttpClientImpl.java      |   4 +-
 .../brooklynnode/RemoteEffectorBuilder.java     |   2 +-
 .../SetHighAvailabilityModeEffectorBody.java    |   2 +-
 ...SetHighAvailabilityPriorityEffectorBody.java |   2 +-
 .../BrooklynNodeIntegrationTest.java            |   8 +-
 .../brooklynnode/CallbackEntityHttpClient.java  |   5 +-
 .../nosql/couchbase/CouchbaseClusterImpl.java   |   5 +-
 .../nosql/couchbase/CouchbaseNodeImpl.java      |   4 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |   4 +-
 .../elasticsearch/ElasticSearchNodeImpl.java    |   2 +-
 .../ElasticSearchClusterIntegrationTest.java    |   4 +-
 .../ElasticSearchNodeIntegrationTest.java       |   4 +-
 .../geoscaling/GeoscalingDnsServiceImpl.java    |   2 +-
 .../dns/geoscaling/GeoscalingWebClient.java     |   2 +-
 .../entity/proxy/nginx/NginxControllerImpl.java |   4 +-
 .../dns/geoscaling/GeoscalingWebClientTest.java |   3 +-
 .../webapp/WebAppConcurrentDeployTest.java      |   5 +-
 .../brooklynnode/BrooklynNodeRestTest.java      |   8 +-
 .../launcher/BrooklynWebServerTest.java         |   5 +-
 .../brooklyn/qa/longevity/MonitorUtils.java     |   4 +-
 .../BrooklynPropertiesSecurityFilterTest.java   |   4 +-
 .../brooklyn/rest/HaMasterCheckFilterTest.java  |   4 +-
 .../rest/resources/CatalogResetTest.java        |   4 +-
 .../SensorResourceIntegrationTest.java          |   4 +-
 .../ServerResourceIntegrationTest.java          |   6 +-
 .../json/BrooklynJacksonSerializerTest.java     |   2 +-
 .../apache/brooklyn/test/EntityTestUtils.java   |  52 +-
 .../org/apache/brooklyn/test/HttpTestUtils.java |   4 +
 .../brooklyn/test/TrustingSslSocketFactory.java | 134 ----
 utils/common/pom.xml                            |  12 +-
 .../java/org/apache/brooklyn/test/Asserts.java  | 615 ++++++++++++++++++-
 .../test/http/TestHttpRequestHandler.java       |  72 +++
 .../brooklyn/test/http/TestHttpServer.java      | 146 +++++
 .../apache/brooklyn/util/http/HttpAsserts.java  | 335 ++++++++++
 .../org/apache/brooklyn/util/http/HttpTool.java | 528 ++++++++++++++++
 .../brooklyn/util/http/HttpToolResponse.java    | 186 ++++++
 .../util/http/TrustingSslSocketFactory.java     | 134 ++++
 .../apache/brooklyn/util/HttpAssertsTest.java   | 293 +++++++++
 60 files changed, 2887 insertions(+), 930 deletions(-)
----------------------------------------------------------------------



[7/9] incubator-brooklyn git commit: Merge branch 'master' into decouple-test-utils

Posted by he...@apache.org.
Merge branch 'master' into decouple-test-utils


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

Branch: refs/heads/master
Commit: 019666c7c1211f5f52752a8b224ed9f188fb1b47
Parents: 885b6ac 48e4fe3
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Tue Nov 3 17:46:35 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Tue Nov 3 17:46:35 2015 +0000

----------------------------------------------------------------------
 .../basic/relations/RelationshipType.java       |  38 ---
 .../brooklyn/api/catalog/BrooklynCatalog.java   |  47 +--
 .../brooklyn/api/catalog/CatalogItem.java       |  12 +-
 .../org/apache/brooklyn/api/entity/Entity.java  |   6 +
 .../internal/AbstractBrooklynObjectSpec.java    |  14 +-
 .../apache/brooklyn/api/mgmt/EntityManager.java |   2 +-
 .../brooklyn/api/mgmt/ManagementContext.java    |   4 +
 .../brooklyn/api/objs/BrooklynObject.java       |   3 +-
 .../brooklyn/api/objs/BrooklynObjectType.java   |  30 +-
 .../apache/brooklyn/api/objs/BrooklynType.java  |   3 +
 .../api/relations/RelationshipType.java         |  38 +++
 .../api/typereg/BrooklynTypeRegistry.java       |  68 ++++
 .../brooklyn/api/typereg/OsgiBundleWithUrl.java |  36 +++
 .../brooklyn/api/typereg/RegisteredType.java    |  65 ++++
 .../api/typereg/RegisteredTypeConstraint.java   |  45 +++
 .../catalog/internal/BasicBrooklynCatalog.java  | 141 +++------
 .../core/catalog/internal/CatalogBundleDto.java |   5 +-
 .../internal/CatalogItemDtoAbstract.java        |   2 +-
 .../core/catalog/internal/CatalogUtils.java     |  69 ++++-
 .../internal/JavaCatalogToSpecTransformer.java  |  23 +-
 .../brooklyn/core/entity/AbstractEntity.java    |  26 ++
 .../apache/brooklyn/core/entity/Entities.java   |  27 +-
 .../brooklyn/core/entity/EntityRelations.java   |   3 +-
 .../core/entity/factory/ApplicationBuilder.java |  10 +-
 .../core/location/BasicLocationRegistry.java    |  37 ++-
 .../core/location/CatalogLocationResolver.java  |   6 +-
 .../core/mgmt/EntityManagementUtils.java        |  25 +-
 .../OsgiBrooklynClassLoadingContext.java        |  17 +-
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |  47 +--
 .../internal/AbstractManagementContext.java     |  14 +-
 .../core/mgmt/internal/LocalEntityManager.java  |   1 +
 .../mgmt/internal/ManagementTransitionMode.java |   2 +-
 .../NonDeploymentManagementContext.java         |  12 +-
 .../BrooklynMementoPersisterToObjectStore.java  |  10 +-
 .../core/mgmt/persist/XmlMementoSerializer.java |   3 +-
 .../AbstractBrooklynObjectRebindSupport.java    |   3 +-
 .../mgmt/rebind/RebindContextLookupContext.java |   9 +-
 .../core/mgmt/rebind/RebindIteration.java       |  30 +-
 .../mgmt/rebind/dto/MementosGenerators.java     |   3 +-
 .../relations/AbstractBasicRelationSupport.java |   3 +-
 .../relations/ByObjectBasicRelationSupport.java |   3 +-
 .../core/relations/EmptyRelationSupport.java    |   3 +-
 .../core/relations/RelationshipTypes.java       |   4 +-
 .../brooklyn/core/resolve/ResolveUtils.java     |  87 ------
 .../entity/CatalogEntitySpecResolver.java       |  60 ++--
 .../resolve/entity/JavaEntitySpecResolver.java  |   8 +
 .../core/typereg/BasicBrooklynTypeRegistry.java | 120 +++++++
 .../core/typereg/BasicOsgiBundleWithUrl.java    | 101 ++++++
 .../core/typereg/RegisteredTypeConstraints.java | 156 ++++++++++
 .../core/typereg/RegisteredTypePredicates.java  | 182 +++++++++++
 .../brooklyn/core/typereg/RegisteredTypes.java  | 245 +++++++++++++++
 .../brooklyn/enricher/stock/Aggregator.java     |   3 +-
 .../apache/brooklyn/util/core/osgi/Osgis.java   |   2 +-
 .../core/catalog/internal/CatalogDtoTest.java   |   6 +-
 .../core/catalog/internal/CatalogScanTest.java  |   3 +-
 .../core/catalog/internal/CatalogTestUtils.java |  47 ---
 .../catalog/internal/CatalogVersioningTest.java |   2 +-
 .../mgmt/osgi/OsgiVersionMoreEntityTest.java    |  89 +++---
 .../mgmt/persist/XmlMementoSerializerTest.java  |   6 +-
 .../rebind/ActivePartialRebindVersionTest.java  |  22 +-
 .../core/mgmt/rebind/RebindCatalogItemTest.java |   6 +-
 .../core/mgmt/rebind/RebindTestFixture.java     |  22 +-
 .../core/relations/RelationshipTest.java        |   3 +-
 .../typereg/RegisteredTypePredicatesTest.java   | 172 ++++++++++
 .../BrooklynAssemblyTemplateInstantiator.java   |   9 +-
 .../BrooklynComponentTemplateResolver.java      |  24 +-
 .../BrooklynEntityDecorationResolver.java       |  31 +-
 .../spi/creation/CampToSpecTransformer.java     |   8 +-
 .../camp/brooklyn/spi/creation/CampUtils.java   |  53 +++-
 .../lookup/AbstractTemplateBrooklynLookup.java  |  14 +-
 .../lookup/AssemblyTemplateBrooklynLookup.java  |   3 +-
 ...PlatformComponentTemplateBrooklynLookup.java |   3 +-
 .../brooklyn/JavaWebAppsIntegrationTest.java    |   2 +-
 .../camp/brooklyn/PoliciesYamlTest.java         |  14 +-
 .../camp/brooklyn/TestEntityWithInitConfig.java |   3 +-
 .../TestSensorAndEffectorInitializer.java       |   1 -
 .../camp/brooklyn/WindowsYamlLiveTest.java      |   4 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |  72 ++---
 .../brooklyn/catalog/CatalogXmlOsgiTest.java    |  20 +-
 .../brooklyn/catalog/CatalogYamlCombiTest.java  |  16 +-
 .../brooklyn/catalog/CatalogYamlEntityTest.java |  41 ++-
 .../catalog/CatalogYamlLocationTest.java        |  27 +-
 .../brooklyn/catalog/CatalogYamlPolicyTest.java |   8 +-
 .../brooklyn/catalog/CatalogYamlRebindTest.java |  37 +--
 .../catalog/CatalogYamlTemplateTest.java        |  44 +--
 .../catalog/CatalogYamlVersioningTest.java      |  58 ++--
 .../brooklyn/test/lite/CampYamlLiteTest.java    |  22 +-
 .../test/lite/TestAppAssemblyInstantiator.java  |   1 -
 .../apache/brooklyn/rest/BrooklynWebConfig.java |   2 +-
 .../resources/AbstractBrooklynRestResource.java |   1 -
 .../rest/resources/ApplicationResource.java     |  21 +-
 .../rest/resources/CatalogResource.java         |  42 +--
 .../rest/resources/EffectorResource.java        |  19 +-
 .../rest/resources/EntityConfigResource.java    |  17 +-
 .../brooklyn/rest/resources/EntityResource.java |  17 +-
 .../rest/resources/LocationResource.java        |   4 +-
 .../rest/resources/PolicyConfigResource.java    |   3 +-
 .../brooklyn/rest/resources/SensorResource.java |  22 +-
 .../brooklyn/rest/resources/ServerResource.java |  14 +-
 .../rest/transform/CatalogTransformer.java      |   1 +
 .../rest/transform/EffectorTransformer.java     |   3 +-
 .../rest/transform/EntityTransformer.java       |   3 +-
 .../rest/transform/PolicyTransformer.java       |   5 +-
 .../rest/util/BrooklynRestResourceUtils.java    | 310 +++++++++++--------
 .../brooklyn/rest/util/WebResourceUtils.java    |   2 +-
 .../brooklyn/rest/domain/ApplicationTest.java   |   3 +-
 .../rest/resources/ApplicationResourceTest.java |  11 +-
 .../rest/resources/CatalogResetTest.java        |   7 +-
 .../rest/resources/CatalogResourceTest.java     |   8 +-
 .../rest/resources/DescendantsTest.java         |  15 +-
 .../rest/resources/ScriptResourceTest.java      |  12 +-
 .../rest/resources/UsageResourceTest.java       |   9 +-
 .../brooklynnode/DeployBlueprintTest.java       |   3 +-
 .../rest/testing/mocks/CapitalizePolicy.java    |   1 +
 .../util/BrooklynRestResourceUtilsTest.java     |   4 -
 .../guava/IllegalStateExceptionSupplier.java    |  24 +-
 116 files changed, 2274 insertions(+), 1115 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/019666c7/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
----------------------------------------------------------------------
diff --cc usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
index c0e0089,0b5daf5..cadea54
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResetTest.java
@@@ -27,8 -27,9 +27,9 @@@ import org.testng.annotations.AfterClas
  import org.testng.annotations.BeforeClass;
  import org.testng.annotations.Test;
  import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+ import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 -import org.apache.brooklyn.core.test.TestHttpRequestHandler;
 -import org.apache.brooklyn.core.test.TestHttpServer;
 +import org.apache.brooklyn.test.http.TestHttpRequestHandler;
 +import org.apache.brooklyn.test.http.TestHttpServer;
  import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
  import org.apache.brooklyn.util.core.ResourceUtils;
  


[3/9] incubator-brooklyn git commit: Updates in response to review comments on the pull request.

Posted by he...@apache.org.
Updates in response to review comments on the pull request.

Renamed assertAttributeNever to assertAttributeContinuallyNotEqualTo (https://github.com/apache/incubator-brooklyn/pull/994#discussion_r43643555).

Updates as noted to deserializingClassRenames.properties (https://github.com/apache/incubator-brooklyn/pull/994#discussion-diff-43643649)

Fix package name in comment in EntityTestUtils (https://github.com/apache/incubator-brooklyn/pull/994#discussion-diff-43643773)

Removed a TODO in EntityTestUtils (https://github.com/apache/incubator-brooklyn/pull/994#discussion-diff-43643799)

Renamed HttpUtils to HttpAsserts; moved methods that weren't assertions to HttpTool, which involved bringing it out of core and into the utils module (https://github.com/apache/incubator-brooklyn/pull/994#discussion_r43644119)


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

Branch: refs/heads/master
Commit: 03dbd2816ba1a3ce9849014638aa429b40b1f476
Parents: c316e21
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Mon Nov 2 18:59:01 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Mon Nov 2 18:59:01 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/core/entity/EntityAsserts.java     |  40 +-
 .../org/apache/brooklyn/feed/http/HttpFeed.java |   6 +-
 .../brooklyn/feed/http/HttpPollConfig.java      |   4 +-
 .../brooklyn/feed/http/HttpPollValue.java       |   2 +-
 .../apache/brooklyn/feed/http/HttpPolls.java    |   4 +-
 .../brooklyn/feed/http/HttpValueFunctions.java  |   2 +-
 .../brooklyn/util/core/ResourceUtils.java       |   5 +-
 .../brooklyn/util/core/http/HttpTool.java       | 386 --------------
 .../util/core/http/HttpToolResponse.java        | 184 -------
 .../deserializingClassRenames.properties        |   6 +-
 .../brooklyn/core/entity/EntityAssertsTest.java |   2 +-
 .../apache/brooklyn/feed/http/HttpFeedTest.java |   5 +-
 .../feed/http/HttpValueFunctionsTest.java       |   3 +-
 .../util/core/http/HttpToolIntegrationTest.java |   4 +-
 .../persist/jclouds/BlobStoreExpiryTest.java    |   4 +-
 .../brooklynnode/BrooklynEntityMirrorImpl.java  |   2 +-
 .../entity/brooklynnode/BrooklynNodeImpl.java   |   2 +-
 .../entity/brooklynnode/EntityHttpClient.java   |   4 +-
 .../brooklynnode/EntityHttpClientImpl.java      |   4 +-
 .../brooklynnode/RemoteEffectorBuilder.java     |   2 +-
 .../SetHighAvailabilityModeEffectorBody.java    |   2 +-
 ...SetHighAvailabilityPriorityEffectorBody.java |   2 +-
 .../BrooklynNodeIntegrationTest.java            |   8 +-
 .../brooklynnode/CallbackEntityHttpClient.java  |   5 +-
 .../nosql/couchbase/CouchbaseClusterImpl.java   |   5 +-
 .../nosql/couchbase/CouchbaseNodeImpl.java      |   4 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |   4 +-
 .../elasticsearch/ElasticSearchNodeImpl.java    |   2 +-
 .../ElasticSearchClusterIntegrationTest.java    |   4 +-
 .../ElasticSearchNodeIntegrationTest.java       |   4 +-
 .../geoscaling/GeoscalingDnsServiceImpl.java    |   2 +-
 .../dns/geoscaling/GeoscalingWebClient.java     |   2 +-
 .../entity/proxy/nginx/NginxControllerImpl.java |   4 +-
 .../dns/geoscaling/GeoscalingWebClientTest.java |   3 +-
 .../webapp/WebAppConcurrentDeployTest.java      |   5 +-
 .../brooklynnode/BrooklynNodeRestTest.java      |   8 +-
 .../launcher/BrooklynWebServerTest.java         |   5 +-
 .../brooklyn/qa/longevity/MonitorUtils.java     |   4 +-
 .../BrooklynPropertiesSecurityFilterTest.java   |   4 +-
 .../brooklyn/rest/HaMasterCheckFilterTest.java  |   4 +-
 .../SensorResourceIntegrationTest.java          |   4 +-
 .../ServerResourceIntegrationTest.java          |   6 +-
 .../json/BrooklynJacksonSerializerTest.java     |   2 +-
 .../apache/brooklyn/test/EntityTestUtils.java   |   3 +-
 .../org/apache/brooklyn/test/HttpTestUtils.java |   2 +-
 utils/common/pom.xml                            |   4 +
 .../apache/brooklyn/util/http/HttpAsserts.java  | 282 ++++++++++
 .../org/apache/brooklyn/util/http/HttpTool.java | 525 +++++++++++++++++++
 .../brooklyn/util/http/HttpToolResponse.java    | 183 +++++++
 .../apache/brooklyn/util/http/HttpUtils.java    | 387 --------------
 50 files changed, 1104 insertions(+), 1046 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
index 046ac52..4641447 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityAsserts.java
@@ -33,10 +33,12 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.time.Duration;
 
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -163,8 +165,21 @@ public class EntityAsserts {
     }
 
 
+    /**
+     * Assert that the given attribute of an entity does not take any of the disallowed values during a given period.
+     *
+     * This method relies on {@link Asserts#succeedsContinually(Runnable)}, therefore it loops comparing the value
+     * of the attribute to the disallowed values, rather than setting up a subscription.  It may therefore miss a
+     * situation where the attribute temporarily takes a disallowed value. This method is therefore suited for use
+     * where the attribute will take on a value permanently, which may or may not be disallowed.
+     *
+     * @param entity      The entity owning the attribute to check.
+     * @param attribute   The attribute on the entity.
+     * @param disallowed  The disallowed values for the entity.
+     * @param <T>         Type of the sensor.
+     */
     @Beta @SafeVarargs
-    public static <T> void assertAttributeNever(final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
+    public static <T> void assertAttributeContinuallyNotEqualTo(final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
         final Set<T> reject = Sets.newHashSet(disallowed);
         Asserts.succeedsContinually(new Runnable() {
             @Override
@@ -176,8 +191,29 @@ public class EntityAsserts {
         });
     }
 
+
+
+    /**
+     * Assert that the given attribute of an entity does not take any of the disallowed values during a given period.
+     *
+     * This method relies on {@link Asserts#succeedsContinually(Runnable)}, therefore it loops comparing the value
+     * of the attribute to the disallowed values, rather than setting up a subscription.  It may therefore miss a
+     * situation where the attribute temporarily takes a disallowed value. This method is therefore suited for use
+     * where the attribute will take on a value permanently, which may or may not be disallowed.
+     *
+     * @param flags       Flags controlling the loop, with keys: <ul>
+     *                    <li>timeout: a {@link Duration} specification String for the duration for which to test the
+     *                    assertion. Default 1 second.</li>
+     *                    <li>period: a {@link Duration} specification String for the interval at which to perform polls
+     *                    on the attribute value. Default 10ms.</li>
+     *                   </ul>
+     * @param entity      The entity owning the attribute to check.
+     * @param attribute   The attribute on the entity.
+     * @param disallowed  The disallowed values for the entity.
+     * @param <T>         Type of the sensor.
+     */
     @Beta @SafeVarargs
-    public static <T> void assertAttributeNever(final Map<?,?> flags, final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
+    public static <T> void assertAttributeContinuallyNotEqualTo(final Map<?, ?> flags, final Entity entity, final AttributeSensor<T> attribute, T... disallowed) {
         final Set<T> reject = Sets.newHashSet(disallowed);
         Asserts.succeedsContinually(flags, new Runnable() {
             @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
index e8cfc9f..d3556be 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
@@ -36,9 +36,9 @@ import org.apache.brooklyn.core.feed.AbstractFeed;
 import org.apache.brooklyn.core.feed.AttributePollHandler;
 import org.apache.brooklyn.core.feed.DelegatingPollHandler;
 import org.apache.brooklyn.core.feed.Poller;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool.HttpClientBuilder;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.UsernamePasswordCredentials;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
index e019293..a6a37bb 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.core.feed.PollConfig;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
index 5414cc4..de3a4b5 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.feed.http;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 
 /** @deprecated since 0.7.0, use {@link HttpToolResponse}.
  * the old {@link HttpPollValue} concrete class has been renamed {@link HttpToolResponse}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
index 10c3b3e..ecc33ed 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.feed.http;
 
 import java.net.URI;
 
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.http.impl.client.DefaultHttpClient;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
index 0fec133..5e3f99f 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.feed.http;
 
 import java.util.List;
 
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.guava.Functionals;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
index a53b8e4..35bdb68 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourceUtils.java
@@ -26,7 +26,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.InetAddress;
-import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -55,8 +54,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpTool.HttpClientBuilder;
 import org.apache.brooklyn.util.core.text.DataUriSchemeParser;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.javalang.Threads;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
deleted file mode 100644
index 1b8b10f..0000000
--- a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpTool.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * 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 org.apache.brooklyn.util.core.http;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.net.URI;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.brooklyn.util.crypto.SslTrustUtils;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.net.URLParamEncoder;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeSocketFactory;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
-import org.apache.http.conn.ssl.TrustStrategy;
-import org.apache.http.conn.ssl.X509HostnameVerifier;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.LaxRedirectStrategy;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EntityUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-
-public class HttpTool {
-
-    private static final Logger LOG = LoggerFactory.getLogger(HttpTool.class);
-
-    /** Apache HTTP commons utility for trusting all.
-     * <p>
-     * For generic java HTTP usage, see {@link SslTrustUtils#trustAll(java.net.URLConnection)} 
-     * and static constants in the same class. */
-    public static class TrustAllStrategy implements TrustStrategy {
-        @Override
-        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
-            return true;
-        }
-    }
-
-    public static HttpClientBuilder httpClientBuilder() {
-        return new HttpClientBuilder();
-    }
-    
-    public static class HttpClientBuilder {
-        private ClientConnectionManager clientConnectionManager;
-        private HttpParams httpParams;
-        private URI uri;
-        private Integer port;
-        private Credentials credentials;
-        private boolean laxRedirect;
-        private Boolean https;
-        private SchemeSocketFactory socketFactory;
-        private ConnectionReuseStrategy reuseStrategy;
-        private boolean trustAll;
-        private boolean trustSelfSigned;
-
-        public HttpClientBuilder clientConnectionManager(ClientConnectionManager val) {
-            this.clientConnectionManager = checkNotNull(val, "clientConnectionManager");
-            return this;
-        }
-        public HttpClientBuilder httpParams(HttpParams val) {
-            checkState(httpParams == null, "Must not call httpParams multiple times, or after other methods like connectionTimeout");
-            this.httpParams = checkNotNull(val, "httpParams");
-            return this;
-        }
-        public HttpClientBuilder connectionTimeout(Duration val) {
-            if (httpParams == null) httpParams = new BasicHttpParams();
-            long millis = checkNotNull(val, "connectionTimeout").toMilliseconds();
-            if (millis > Integer.MAX_VALUE) throw new IllegalStateException("HttpClient only accepts upto max-int millis for connectionTimeout, but given "+val);
-            HttpConnectionParams.setConnectionTimeout(httpParams, (int) millis);
-            return this;
-        }
-        public HttpClientBuilder socketTimeout(Duration val) {
-            if (httpParams == null) httpParams = new BasicHttpParams();
-            long millis = checkNotNull(val, "socketTimeout").toMilliseconds();
-            if (millis > Integer.MAX_VALUE) throw new IllegalStateException("HttpClient only accepts upto max-int millis for socketTimeout, but given "+val);
-            HttpConnectionParams.setSoTimeout(httpParams, (int) millis);
-            return this;
-        }
-        public HttpClientBuilder reuseStrategy(ConnectionReuseStrategy val) {
-            this.reuseStrategy = checkNotNull(val, "reuseStrategy");
-            return this;
-        }
-        public HttpClientBuilder uri(String val) {
-            return uri(URI.create(checkNotNull(val, "uri")));
-        }
-        public HttpClientBuilder uri(URI val) {
-            this.uri = checkNotNull(val, "uri");
-            if (https == null) https = ("https".equalsIgnoreCase(uri.getScheme()));
-            return this;
-        }
-        public HttpClientBuilder port(int val) {
-            this.port = val;
-            return this;
-        }
-        public HttpClientBuilder credentials(Credentials val) {
-            this.credentials = checkNotNull(val, "credentials");
-            return this;
-        }
-        public void credential(Optional<Credentials> val) {
-            if (val.isPresent()) credentials = val.get();
-        }
-        /** similar to curl --post301 -L` */
-        public HttpClientBuilder laxRedirect(boolean val) {
-            this.laxRedirect = val;
-            return this;
-        }
-        public HttpClientBuilder https(boolean val) {
-            this.https = val;
-            return this;
-        }
-        public HttpClientBuilder socketFactory(SchemeSocketFactory val) {
-            this.socketFactory = checkNotNull(val, "socketFactory");
-            return this;
-        }
-        public HttpClientBuilder trustAll() {
-            this.trustAll = true;
-            return this;
-        }
-        public HttpClientBuilder trustSelfSigned() {
-            this.trustSelfSigned = true;
-            return this;
-        }
-        public HttpClient build() {
-            final DefaultHttpClient httpClient = new DefaultHttpClient(clientConnectionManager);
-            httpClient.setParams(httpParams);
-    
-            // support redirects for POST (similar to `curl --post301 -L`)
-            // http://stackoverflow.com/questions/3658721/httpclient-4-error-302-how-to-redirect
-            if (laxRedirect) {
-                httpClient.setRedirectStrategy(new LaxRedirectStrategy());
-            }
-            if (reuseStrategy != null) {
-                httpClient.setReuseStrategy(reuseStrategy);
-            }
-            if (https == Boolean.TRUE || (uri!=null && uri.toString().startsWith("https:"))) {
-                try {
-                    if (port == null) {
-                        port = (uri != null && uri.getPort() >= 0) ? uri.getPort() : 443;
-                    }
-                    if (socketFactory == null) {
-                        if (trustAll) {
-                            TrustStrategy trustStrategy = new TrustAllStrategy();
-                            X509HostnameVerifier hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
-                            socketFactory = new SSLSocketFactory(trustStrategy, hostnameVerifier);
-                        } else if (trustSelfSigned) {
-                            TrustStrategy trustStrategy = new TrustSelfSignedStrategy();
-                            X509HostnameVerifier hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
-                            socketFactory = new SSLSocketFactory(trustStrategy, hostnameVerifier);
-                        } else {
-                            // Using default https scheme: based on default java truststore, which is pretty strict!
-                        }
-                    }
-                    if (socketFactory != null) {
-                        Scheme sch = new Scheme("https", port, socketFactory);
-                        httpClient.getConnectionManager().getSchemeRegistry().register(sch);
-                    }
-                } catch (Exception e) {
-                    LOG.warn("Error setting trust for uri {}", uri);
-                    throw Exceptions.propagate(e);
-                }
-            }
-    
-            // Set credentials
-            if (uri != null && credentials != null) {
-                String hostname = uri.getHost();
-                int port = uri.getPort();
-                httpClient.getCredentialsProvider().setCredentials(new AuthScope(hostname, port), credentials);
-            }
-            if (uri==null && credentials!=null) {
-                LOG.warn("credentials have no effect in builder unless URI for host is specified");
-            }
-    
-            return httpClient;
-        }
-    }
-
-    protected static abstract class HttpRequestBuilder<B extends HttpRequestBuilder<B, R>, R extends HttpRequest> {
-        protected R req;
-        
-        protected HttpRequestBuilder(R req) {
-            this.req = req;
-        }
-        @SuppressWarnings("unchecked")
-        protected B self() {
-            return (B) this;
-        }
-        public B headers(Map<String,String> headers) {
-            if (headers!=null) {
-                for (Map.Entry<String,String> entry : headers.entrySet()) {
-                    req.addHeader(entry.getKey(), entry.getValue());
-                }
-            }
-            return self();
-        }
-        public B headers(Multimap<String,String> headers) {
-            if (headers!=null) {
-                for (Map.Entry<String,String> entry : headers.entries()) {
-                    req.addHeader(entry.getKey(), entry.getValue());
-                }
-            }
-            return self();
-        }
-        public R build() {
-            return req;
-        }
-    }
-    
-    protected static abstract class HttpEntityEnclosingRequestBaseBuilder<B extends HttpEntityEnclosingRequestBaseBuilder<B,R>, R extends HttpEntityEnclosingRequestBase> extends HttpRequestBuilder<B, R> {
-        protected HttpEntityEnclosingRequestBaseBuilder(R req) {
-            super(req);
-        }
-        public B body(byte[] body) {
-            if (body != null) {
-                HttpEntity httpEntity = new ByteArrayEntity(body);
-                req.setEntity(httpEntity);
-            }
-            return self();
-        }
-    }
-    
-    public static class HttpGetBuilder extends HttpRequestBuilder<HttpGetBuilder, HttpGet> {
-        public HttpGetBuilder(URI uri) {
-            super(new HttpGet(uri));
-        }
-    }
-    
-    public static class HttpHeadBuilder extends HttpRequestBuilder<HttpHeadBuilder, HttpHead> {
-        public HttpHeadBuilder(URI uri) {
-            super(new HttpHead(uri));
-        }
-    }
-    
-    public static class HttpDeleteBuilder extends HttpRequestBuilder<HttpDeleteBuilder, HttpDelete> {
-        public HttpDeleteBuilder(URI uri) {
-            super(new HttpDelete(uri));
-        }
-    }
-    
-    public static class HttpPostBuilder extends HttpEntityEnclosingRequestBaseBuilder<HttpPostBuilder, HttpPost> {
-        HttpPostBuilder(URI uri) {
-            super(new HttpPost(uri));
-        }
-    }
-
-    public static class HttpFormPostBuilder extends HttpRequestBuilder<HttpFormPostBuilder, HttpPost> {
-        HttpFormPostBuilder(URI uri) {
-            super(new HttpPost(uri));
-        }
-
-        public HttpFormPostBuilder params(Map<String, String> params) {
-            if (params != null) {
-                Collection<NameValuePair> httpParams = new ArrayList<NameValuePair>(params.size());
-                for (Entry<String, String> param : params.entrySet()) {
-                    httpParams.add(new BasicNameValuePair(param.getKey(), param.getValue()));
-                }
-                req.setEntity(new UrlEncodedFormEntity(httpParams));
-            }
-            return self();
-        }
-    }
-
-    public static class HttpPutBuilder extends HttpEntityEnclosingRequestBaseBuilder<HttpPutBuilder, HttpPut> {
-        public HttpPutBuilder(URI uri) {
-            super(new HttpPut(uri));
-        }
-    }
-    
-    public static HttpToolResponse httpGet(HttpClient httpClient, URI uri, Map<String,String> headers) {
-        HttpGet req = new HttpGetBuilder(uri).headers(headers).build();
-        return execAndConsume(httpClient, req);
-    }
-
-    public static HttpToolResponse httpPost(HttpClient httpClient, URI uri, Map<String,String> headers, byte[] body) {
-        HttpPost req = new HttpPostBuilder(uri).headers(headers).body(body).build();
-        return execAndConsume(httpClient, req);
-    }
-
-    public static HttpToolResponse httpPut(HttpClient httpClient, URI uri, Map<String, String> headers, byte[] body) {
-        HttpPut req = new HttpPutBuilder(uri).headers(headers).body(body).build();
-        return execAndConsume(httpClient, req);
-    }
-
-    public static HttpToolResponse httpPost(HttpClient httpClient, URI uri, Map<String,String> headers, Map<String, String> params) {
-        HttpPost req = new HttpFormPostBuilder(uri).headers(headers).params(params).build();
-        return execAndConsume(httpClient, req);
-    }
-
-    public static HttpToolResponse httpDelete(HttpClient httpClient, URI uri, Map<String,String> headers) {
-        HttpDelete req = new HttpDeleteBuilder(uri).headers(headers).build();
-        return execAndConsume(httpClient, req);
-    }
-    
-    public static HttpToolResponse httpHead(HttpClient httpClient, URI uri, Map<String,String> headers) {
-        HttpHead req = new HttpHeadBuilder(uri).headers(headers).build();
-        return execAndConsume(httpClient, req);
-    }
-    
-    public static HttpToolResponse execAndConsume(HttpClient httpClient, HttpUriRequest req) {
-        long startTime = System.currentTimeMillis();
-        try {
-            HttpResponse httpResponse = httpClient.execute(req);
-            
-            try {
-                return new HttpToolResponse(httpResponse, startTime);
-            } finally {
-                EntityUtils.consume(httpResponse.getEntity());
-            }
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    public static boolean isStatusCodeHealthy(int code) { return (code>=200 && code<=299); }
-
-    public static String toBasicAuthorizationValue(UsernamePasswordCredentials credentials) {
-        return "Basic "+Base64.encodeBase64String( (credentials.getUserName()+":"+credentials.getPassword()).getBytes() );
-    }
-
-    public static String encodeUrlParams(Map<?,?> data) {
-        if (data==null) return "";
-        Iterable<String> args = Iterables.transform(data.entrySet(), 
-            new Function<Map.Entry<?,?>,String>() {
-            @Override public String apply(Map.Entry<?,?> entry) {
-                Object k = entry.getKey();
-                Object v = entry.getValue();
-                return URLParamEncoder.encode(Strings.toString(k)) + (v != null ? "=" + URLParamEncoder.encode(Strings.toString(v)) : "");
-            }
-        });
-        return Joiner.on("&").join(args);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
deleted file mode 100644
index ad768f7..0000000
--- a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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 org.apache.brooklyn.util.core.http;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.feed.http.HttpPollValue;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.io.ByteStreams;
-
-public class HttpToolResponse implements HttpPollValue {
-
-    private static final Logger log = LoggerFactory.getLogger(HttpToolResponse.class);
-    
-    private final Object mutex = new Object();
-    private final HttpResponse response;
-    private final long startTime;
-    private final long durationMillisOfFirstResponse;
-    private final long durationMillisOfFullContent;
-    private int responseCode;
-    private String reasonPhrase;
-    private Map<String,List<String>> headerLists;
-    private byte[] content;
-
-
-    public HttpToolResponse(HttpResponse response, long startTime) {
-        this.response = response;
-        this.startTime = startTime; 
-        
-        try {
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            HttpEntity entity = response.getEntity();
-            if (entity != null) {
-                entity.getContentLength();
-                durationMillisOfFirstResponse = Duration.sinceUtc(startTime).toMilliseconds();
-
-                ByteStreams.copy(entity.getContent(), out);
-                content = out.toByteArray();
-
-                entity.getContentLength();
-            } else {
-                durationMillisOfFirstResponse = Duration.sinceUtc(startTime).toMilliseconds();
-                content = new byte[0];
-            }
-            durationMillisOfFullContent = Duration.sinceUtc(startTime).toMilliseconds();
-            if (log.isTraceEnabled())
-                log.trace("HttpPollValue latency "+Time.makeTimeStringRounded(durationMillisOfFirstResponse)+" / "+Time.makeTimeStringRounded(durationMillisOfFullContent)+", content size "+content.length);
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    public HttpToolResponse(int responseCode, Map<String,? extends List<String>> headers, byte[] content,
-            long startTime, long durationMillisOfFirstResponse, long durationMillisOfFullContent) {
-        this.response = null;
-        this.responseCode = responseCode;
-        this.headerLists = ImmutableMap.copyOf(headers);
-        this.content = content;
-        this.startTime = startTime;
-        this.durationMillisOfFirstResponse = durationMillisOfFirstResponse;
-        this.durationMillisOfFullContent = durationMillisOfFullContent;
-    }
-    
-    public int getResponseCode() {
-        synchronized (mutex) {
-            if (responseCode == 0) {
-                responseCode = response.getStatusLine().getStatusCode();
-            }
-        }
-        return responseCode;
-    }
-
-    public String getReasonPhrase() {
-        synchronized (mutex) {
-            if (reasonPhrase == null) {
-                reasonPhrase = response.getStatusLine().getReasonPhrase();
-            }
-        }
-        return reasonPhrase;
-    }
-
-    /** returns the timestamp (millis since 1970) when this request was started */ 
-    public long getStartTime() {
-        return startTime;
-    }
-    
-    /** returns latency, in milliseconds, if value was initialized with a start time */
-    public long getLatencyFullContent() {
-        return durationMillisOfFullContent;
-    }
-    
-    /** returns latency, in milliseconds, before response started coming in */
-    public long getLatencyFirstResponse() {
-        return durationMillisOfFirstResponse;
-    }
-    
-    public Map<String, List<String>> getHeaderLists() {
-        synchronized (mutex) {
-            if (headerLists == null) {
-                Map<String, List<String>> headerListsMutable = Maps.newLinkedHashMap();
-                for (Header header : response.getAllHeaders()) {
-                    List<String> vals = headerListsMutable.get(header.getName());
-                    if (vals == null) {
-                        vals = new ArrayList<String>();
-                        headerListsMutable.put(header.getName(), vals);
-                    }
-                    vals.add(header.getValue());
-                }
-                headerLists = Collections.unmodifiableMap(headerListsMutable);
-            }
-        }
-        return headerLists;
-    }
-    
-    public byte[] getContent() {
-        synchronized (mutex) {
-            if (content == null) {
-                InputStream in = null;
-                try {
-                    in = response.getEntity().getContent();
-                    ByteArrayOutputStream out = new ByteArrayOutputStream();
-                    ByteStreams.copy(in, out);
-                    content = out.toByteArray();
-                } catch (IOException e) {
-                    throw Throwables.propagate(e);
-                } finally {
-                    Streams.closeQuietly(in);
-                }
-            }
-        }
-        return content;
-    }
-
-    public String getContentAsString() {
-        return new String(getContent());
-    }
-    
-    public Maybe<HttpResponse> getResponse() {
-        return Maybe.fromNullable(response);
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(getClass())
-                .add("responseCode", responseCode)
-                .toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
index 006b95a..2503425 100644
--- a/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
+++ b/core/src/main/resources/org/apache/brooklyn/core/mgmt/persist/deserializingClassRenames.properties
@@ -609,8 +609,8 @@ brooklyn.util.flags.FlagUtils
 brooklyn.util.flags.MethodCoercions                                              : org.apache.brooklyn.util.core.flags.MethodCoercions
 brooklyn.util.flags.SetFromFlag                                                  : org.apache.brooklyn.util.core.flags.SetFromFlag
 brooklyn.util.flags.TypeCoercions                                                : org.apache.brooklyn.util.core.flags.TypeCoercions
-brooklyn.util.http.HttpTool                                                      : org.apache.brooklyn.util.core.http.HttpTool
-brooklyn.util.http.HttpToolResponse                                              : org.apache.brooklyn.util.core.http.HttpToolResponse
+brooklyn.util.http.HttpTool                                                      : org.apache.brooklyn.util.http.HttpTool
+brooklyn.util.http.HttpToolResponse                                              : org.apache.brooklyn.util.http.HttpToolResponse
 brooklyn.util.internal.ConfigKeySelfExtracting                                   : org.apache.brooklyn.util.core.internal.ConfigKeySelfExtracting
 brooklyn.util.internal.ssh.BackoffLimitedRetryHandler                            : org.apache.brooklyn.util.core.internal.ssh.BackoffLimitedRetryHandler
 brooklyn.util.internal.ssh.ShellAbstractTool                                     : org.apache.brooklyn.util.core.internal.ssh.ShellAbstractTool
@@ -1417,3 +1417,5 @@ brooklyn.util.internal.Repeater
 brooklyn.entity.nosql.redis.RedisClusterImpl                                     : org.apache.brooklyn.entity.nosql.redis.RedisClusterImpl
 brooklyn.test.TrustingSslSocketFactory                                           : org.apache.brooklyn.util.http.TrustingSslSocketFactory
 brooklyn.util.crypto.TrustingSslSocketFactory                                    : org.apache.brooklyn.util.crypto.TrustingSslSocketFactory
+
+org.apache.brooklyn.test.TrustingSslSocketFactory                                : org.apache.brooklyn.util.http.TrustingSslSocketFactory
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
index 563b0ea..8a9d480 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityAssertsTest.java
@@ -211,7 +211,7 @@ public class EntityAssertsTest extends BrooklynAppUnitTestSupport {
     @Test
     public void shouldAssertAttributeNever() {
         entity.sensors().set(TestEntity.NAME, "ever");
-        EntityAsserts.assertAttributeNever(ImmutableMap.of("timeout", "5s"), entity, TestEntity.NAME, "after");
+        EntityAsserts.assertAttributeContinuallyNotEqualTo(ImmutableMap.of("timeout", "5s"), entity, TestEntity.NAME, "after");
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
index 3ba426e..63c3c5b 100644
--- a/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
@@ -38,14 +38,11 @@ import org.apache.brooklyn.core.feed.PollConfig;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.feed.http.HttpFeed;
-import org.apache.brooklyn.feed.http.HttpPollConfig;
-import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.http.BetterMockWebServer;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.guava.Functionals;
 import org.apache.brooklyn.util.net.Networking;
 import org.apache.brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
index 23ffae3..84c7993 100644
--- a/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
@@ -25,8 +25,7 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.NoSuchElementException;
 
-import org.apache.brooklyn.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/core/src/test/java/org/apache/brooklyn/util/core/http/HttpToolIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/http/HttpToolIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/util/core/http/HttpToolIntegrationTest.java
index 2c12357..8a5f4f3 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/http/HttpToolIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/http/HttpToolIntegrationTest.java
@@ -28,8 +28,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.core.location.PortRanges;
 import org.apache.brooklyn.core.test.HttpService;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 
 import com.google.common.collect.ImmutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/locations/jclouds/src/test/java/org/apache/brooklyn/core/mgmt/persist/jclouds/BlobStoreExpiryTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/core/mgmt/persist/jclouds/BlobStoreExpiryTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/core/mgmt/persist/jclouds/BlobStoreExpiryTest.java
index fd425fc..db09c84 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/core/mgmt/persist/jclouds/BlobStoreExpiryTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/core/mgmt/persist/jclouds/BlobStoreExpiryTest.java
@@ -34,8 +34,8 @@ import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
index 747aeab..8b28607 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
@@ -38,7 +38,7 @@ import org.apache.brooklyn.feed.http.HttpPollConfig;
 import org.apache.brooklyn.util.collections.Jsonya;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index e85b335..e9a116f 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -63,7 +63,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.collections.Jsonya;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskTags;
 import org.apache.brooklyn.util.core.task.Tasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClient.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClient.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClient.java
index dd2db70..200141b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClient.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClient.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.brooklynnode;
 
 import java.util.Map;
 
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
index 8d8a396..ab08924 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/EntityHttpClientImpl.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
index cf68641..23d5f6c 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.effector.Effectors.EffectorBuilder;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirrorImpl.RemoteEffector;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 
 import com.google.common.base.Function;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
index 17baf37..36bee5a 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.SetHighAvailabilityM
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.feed.http.JsonFunctions;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.guava.Functionals;
 import org.apache.brooklyn.util.javalang.Enums;
 import org.apache.http.HttpStatus;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
index 3560d49..690f1a9 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
 import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.SetHighAvailabilityPriorityEffector;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.http.HttpStatus;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index 92ec962..16c1e9c 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -43,10 +43,6 @@ import org.apache.brooklyn.core.location.Locations;
 import org.apache.brooklyn.core.location.PortRanges;
 import org.apache.brooklyn.core.objs.proxy.EntityProxyImpl;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirror;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeImpl;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeSshDriver;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.DeployBlueprintEffector;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.StopNodeAndKillAppsEffector;
@@ -59,8 +55,8 @@ import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Functionals;
 import org.apache.brooklyn.util.javalang.JavaClassNames;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
index c933b9d..c6a7120 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/CallbackEntityHttpClient.java
@@ -23,9 +23,8 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;
+import org.apache.brooklyn.util.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool.HttpClientBuilder;
 import org.apache.http.HttpStatus;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index 6e39f7d..4396ed1 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -50,6 +50,7 @@ import org.apache.brooklyn.feed.http.HttpFeed;
 import org.apache.brooklyn.feed.http.HttpPollConfig;
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.feed.http.JsonFunctions;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.collections.CollectionFunctionals;
@@ -562,8 +563,8 @@ public class CouchbaseClusterImpl extends DynamicClusterImpl implements Couchbas
                                         .onFailureOrException(new Function<Object, Boolean>() {
                                             @Override
                                             public Boolean apply(Object input) {
-                                                if (input instanceof org.apache.brooklyn.util.core.http.HttpToolResponse) {
-                                                    if (((org.apache.brooklyn.util.core.http.HttpToolResponse) input).getResponseCode() == 404) {
+                                                if (input instanceof HttpToolResponse) {
+                                                    if (((HttpToolResponse) input).getResponseCode() == 404) {
                                                         return true;
                                                     }
                                                 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
index d227a4a..049253f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
@@ -45,8 +45,8 @@ import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Functionals;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index fe2c788..915f06a 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -46,8 +46,8 @@ import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.TaskTags;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
index 413b82c..c707ee6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.feed.http.HttpFeed;
 import org.apache.brooklyn.feed.http.HttpPollConfig;
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.feed.http.JsonFunctions;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.guava.Functionals;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.guava.MaybeFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
index 211c754..eacc57f 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
@@ -34,8 +34,8 @@ import org.apache.brooklyn.entity.group.DynamicCluster;
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.bouncycastle.util.Strings;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
index a908886..e6412f8 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
@@ -32,8 +32,8 @@ import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.bouncycastle.util.Strings;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
index 3e88805..4273dac 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.SmartSubdom
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.Strings;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
index ac0b934..f882e57 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
@@ -28,7 +28,7 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.http.HttpEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index 2326228..94b9732 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -46,8 +46,8 @@ import org.apache.brooklyn.feed.http.HttpPollConfig;
 import org.apache.brooklyn.feed.http.HttpValueFunctions;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.file.ArchiveUtils;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.guava.Functionals;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
index e8b452e..8dc566b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
@@ -26,10 +26,9 @@ import static org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.PROV
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 
-import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.Domain;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.SmartSubdomain;
-import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.http.client.HttpClient;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
index fae555b..17b3954 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
@@ -35,7 +35,6 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.apache.brooklyn.test.Asserts;
@@ -43,8 +42,8 @@ import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
index 37b45c3..14970e9 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.util.collections.Jsonya;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.repeat.Repeater;
 import org.apache.brooklyn.util.time.Duration;
@@ -48,10 +48,6 @@ import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirror;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
-import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeTest;
-import org.apache.brooklyn.entity.brooklynnode.SameBrooklynNodeImpl;
 import org.apache.brooklyn.launcher.SimpleYamlLauncherForTests;
 import org.apache.brooklyn.launcher.camp.SimpleYamlLauncher;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynWebServerTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynWebServerTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynWebServerTest.java
index a7ce92a..a241a9b 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynWebServerTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynWebServerTest.java
@@ -22,7 +22,6 @@ import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.launcher.BrooklynWebServer;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -51,8 +50,8 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.rest.BrooklynWebConfig;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
index 9ca771b..c9ce875 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
@@ -35,8 +35,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
 
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.stream.StreamGobbler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
index 26d8aae..312d240 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynPropertiesSecurityFilterTest.java
@@ -37,8 +37,8 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.rest.security.provider.AnyoneSecurityProvider;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.time.Time;
 
 import com.fasterxml.jackson.databind.ObjectMapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/rest-server/src/test/java/org/apache/brooklyn/rest/HaMasterCheckFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/HaMasterCheckFilterTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/HaMasterCheckFilterTest.java
index 2e84c49..424c0c1 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/HaMasterCheckFilterTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/HaMasterCheckFilterTest.java
@@ -42,8 +42,8 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.rest.security.provider.AnyoneSecurityProvider;
 import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceIntegrationTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceIntegrationTest.java
index 3cc1920..f90b677 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceIntegrationTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceIntegrationTest.java
@@ -32,8 +32,8 @@ import org.apache.brooklyn.rest.BrooklynRestApiLauncherTestFixture;
 import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.http.client.HttpClient;
 import org.eclipse.jetty.server.Server;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceIntegrationTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceIntegrationTest.java
index d771236..ce3fd37 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceIntegrationTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ServerResourceIntegrationTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.rest.resources;
 
-import static org.apache.brooklyn.util.core.http.HttpTool.httpClientBuilder;
+import static org.apache.brooklyn.util.http.HttpTool.httpClientBuilder;
 import static org.testng.Assert.assertEquals;
 
 import java.net.URI;
@@ -33,8 +33,8 @@ import org.apache.brooklyn.rest.BrooklynRestApiLauncher;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncherTestFixture;
 import org.apache.brooklyn.rest.security.provider.TestSecurityProvider;
 import org.apache.brooklyn.test.HttpTestUtils;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpToolResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.HttpClient;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java
index d4bee91..6280cb0 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java
@@ -47,7 +47,7 @@ import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncher;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
index 6a72324..5b1e22b 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/EntityTestUtils.java
@@ -48,12 +48,11 @@ import com.google.common.collect.Sets;
 /**
  * A utility class containing tests on Entities.
  *
- * @deprecated Prefer core assertions org.apache.brooklyn.entity.EntityAsserts.
+ * @deprecated Prefer core assertions class org.apache.brooklyn.core.entity.EntityAsserts.
  */
 @Deprecated
 public class EntityTestUtils {
 
-    // TODO would be nice to have this... perhaps moving this class, or perhaps this whole project, to core/src/test ?
 //    public static LocalManagementContext newManagementContext() { return new LocalManagementContextForTests(); }
     
     // TODO Delete methods from TestUtils, to just have them here (or switch so TestUtils delegates here,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
index c0089bd..b5a1536 100644
--- a/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
+++ b/usage/test-support/src/main/java/org/apache/brooklyn/test/HttpTestUtils.java
@@ -61,7 +61,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
  * 
  * @author aled
  *
- * @deprecated Prefer org.apache.brooklyn.util.http.HttpUtils which has no TestNG dependencies.
+ * @deprecated Prefer org.apache.brooklyn.util.http.HttpAsserts which has no TestNG dependencies.
  */
 @Deprecated
 public class HttpTestUtils {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/utils/common/pom.xml
----------------------------------------------------------------------
diff --git a/utils/common/pom.xml b/utils/common/pom.xml
index c973003..8bc0ae9 100644
--- a/utils/common/pom.xml
+++ b/utils/common/pom.xml
@@ -58,6 +58,10 @@
             <artifactId>commons-io</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
             <version>${snakeyaml.version}</version>



[5/9] incubator-brooklyn git commit: Update HttpAsserts with equivalent change to that merged in a1e21b3a2

Posted by he...@apache.org.
Update HttpAsserts with equivalent change to that merged in a1e21b3a2


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

Branch: refs/heads/master
Commit: 70a718911ca7800bcff4a5ab8aeef20763a3974a
Parents: a1e21b3
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Mon Nov 2 20:26:18 2015 +0000
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Mon Nov 2 20:26:18 2015 +0000

----------------------------------------------------------------------
 .../java/org/apache/brooklyn/util/http/HttpAsserts.java     | 9 +++++++++
 1 file changed, 9 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/70a71891/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
index bbfdbfb..35d8252 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
@@ -242,6 +242,15 @@ public class HttpAsserts {
         });
     }
 
+    public static void assertContentEventuallyMatches(Map<String,?> flags, final String url, final String regex) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            @Override
+            public void run() {
+                assertContentMatches(url, regex);
+            }
+        });
+    }
+
 
 
     /**


[2/9] incubator-brooklyn git commit: Updates in response to review comments on the pull request.

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
new file mode 100644
index 0000000..bbfdbfb
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpAsserts.java
@@ -0,0 +1,282 @@
+/*
+ * 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 org.apache.brooklyn.util.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.crypto.SslTrustUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * Utility methods to aid testing HTTP.
+ * 
+ * @author aled
+ */
+public class HttpAsserts {
+
+    // TODO Delete methods from TestUtils, to just have them here (or switch so TestUtils delegates here,
+    // and deprecate methods in TestUtils until deleted).
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpAsserts.class);
+
+    public static void assertHealthyStatusCode(int code) {
+        if (code>=200 && code<=299) return;
+        Asserts.fail("Wrong status code: " + code);
+    }
+    
+    public static int getHttpStatusCode(String url) throws Exception {
+        URLConnection connection = HttpTool.connectToUrl(url);
+        long startTime = System.currentTimeMillis();
+        int status = ((HttpURLConnection) connection).getResponseCode();
+        
+        // read fully if possible, then close everything, trying to prevent cached threads at server
+        HttpTool.consumeAndCloseQuietly((HttpURLConnection) connection);
+        
+        if (LOG.isDebugEnabled())
+            LOG.debug("connection to {} ({}ms) gives {}", new Object[] { url, (System.currentTimeMillis()-startTime), status });
+        return status;
+    }
+
+    /**
+     * Asserts that gets back any "valid" response - i.e. not an exception. This could be an unauthorized,
+     * a redirect, a 404, or anything else that implies there is web-server listening on that port.
+     */
+    public static void assertUrlReachable(String url) {
+        try {
+            getHttpStatusCode(url);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that is reachable)", e);
+        } catch (Exception e) {
+            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that is reachable): "+e, e);
+        }
+    }
+
+    public static void assertUrlUnreachable(String url) {
+        try {
+            int statusCode = getHttpStatusCode(url);
+            Asserts.fail("Expected url " + url + " unreachable, but got status code " + statusCode);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that unreachable)", e);
+        } catch (Exception e) {
+            IOException cause = Exceptions.getFirstThrowableOfType(e, IOException.class);
+            if (cause != null) {
+                // success; clean shutdown transitioning from 400 to error
+            } else {
+                Throwables.propagate(e);
+            }                        
+        }
+    }
+
+    public static void assertUrlUnreachableEventually(final String url) {
+        assertUrlUnreachableEventually(Maps.newLinkedHashMap(), url);
+    }
+    
+    public static void assertUrlUnreachableEventually(Map flags, final String url) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertUrlUnreachable(url);
+            }
+         });
+    }
+
+    public static void assertHttpStatusCodeEquals(String url, int... acceptableReturnCodes) {
+        List<Integer> acceptableCodes = Lists.newArrayList();
+        for (int code : acceptableReturnCodes) {
+            acceptableCodes.add((Integer)code);
+        }
+        try {
+            int actualCode = getHttpStatusCode(url);
+            Asserts.assertTrue(acceptableCodes.contains(actualCode), "code=" + actualCode + "; expected=" + acceptableCodes + "; url=" + url);
+            
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException("Interrupted for "+url+" (in assertion that result code is "+acceptableCodes+")", e);
+        } catch (Exception e) {
+            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that result code is "+acceptableCodes+"): "+e, e);
+        }
+    }
+
+    public static void assertHttpStatusCodeEventuallyEquals(final String url, final int expectedCode) {
+        assertHttpStatusCodeEventuallyEquals(Maps.newLinkedHashMap(),  url, expectedCode);
+    }
+
+    public static void assertHttpStatusCodeEventuallyEquals(Map flags, final String url, final int expectedCode) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertHttpStatusCodeEquals(url, expectedCode);
+            }
+         });
+    }
+
+    public static void assertContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = HttpTool.getContent(url);
+            Asserts.assertTrue(contents != null && contents.length() > 0);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (!contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" does not contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public static void assertContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = HttpTool.getContent(url);
+            Asserts.assertTrue(contents != null);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public static void assertErrorContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String contents = HttpTool.getErrorContent(url);
+            Asserts.assertTrue(contents != null && contents.length() > 0);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (!contents.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
+                    Asserts.fail("URL "+url+" does not contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+
+    public static void assertErrorContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        try {
+            String err = HttpTool.getErrorContent(url);
+            Asserts.assertTrue(err != null);
+            for (String text: Lists.asList(phrase, additionalPhrases)) {
+                if (err.contains(text)) {
+                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+err);
+                    Asserts.fail("URL "+url+" contain text: "+text);
+                }
+            }
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+    
+    public static void assertContentEventuallyContainsText(final String url, final String phrase, final String ...additionalPhrases) {
+        assertContentEventuallyContainsText(MutableMap.of(), url, phrase, additionalPhrases);
+    }
+    
+    public static void assertContentEventuallyContainsText(Map flags, final String url, final String phrase, final String ...additionalPhrases) {
+        Asserts.succeedsEventually(flags, new Runnable() {
+            public void run() {
+                assertContentContainsText(url, phrase, additionalPhrases);
+            }
+         });
+    }
+    
+    public static void assertContentMatches(String url, String regex) {
+        String contents = HttpTool.getContent(url);
+        Asserts.assertNotNull(contents);
+        Asserts.assertTrue(contents.matches(regex), "Contents does not match expected regex ("+regex+"): "+contents);
+    }
+
+    public static void assertContentEventuallyMatches(final String url, final String regex) {
+        Asserts.succeedsEventually(new Runnable() {
+            @Override
+            public void run() {
+                assertContentMatches(url, regex);
+            }
+        });
+    }
+
+
+
+    /**
+     * Schedules (with the given executor) a poller that repeatedly accesses the given url, to confirm it always gives
+     * back the expected status code.
+     * 
+     * Expected usage is to query the future, such as:
+     * 
+     * <pre>
+     * {@code
+     * Future<?> future = assertAsyncHttpStatusCodeContinuallyEquals(executor, url, 200);
+     * // do other stuff...
+     * if (future.isDone()) future.get(); // get exception if it's Asserts.failed
+     * }
+     * </pre>
+     * 
+     * For stopping it, you can either do future.cancel(true), or you can just do executor.shutdownNow().
+     * 
+     * TODO Look at difference between this and WebAppMonitor, to decide if this should be kept.
+     */
+    public static ListenableFuture<?> assertAsyncHttpStatusCodeContinuallyEquals(ListeningExecutorService executor, final String url, final int expectedStatusCode) {
+        return executor.submit(new Runnable() {
+            @Override public void run() {
+                // TODO Need to drop logging; remove sleep when that's done.
+                while (!Thread.currentThread().isInterrupted()) {
+                    assertHttpStatusCodeEquals(url, expectedStatusCode);
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        return; // graceful return
+                    }
+                }
+            }
+        });
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
new file mode 100644
index 0000000..8811a32
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpTool.java
@@ -0,0 +1,525 @@
+/*
+ * 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 org.apache.brooklyn.util.http;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.google.common.base.Throwables;
+import org.apache.brooklyn.util.crypto.SslTrustUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.net.URLParamEncoder;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeSocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.LaxRedirectStrategy;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+public class HttpTool {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpTool.class);
+
+    static final ExecutorService executor = Executors.newCachedThreadPool();
+
+    /**
+     * Connects to the given url and returns the connection.
+     * Caller should {@code connection.getInputStream().close()} the result of this
+     * (especially if they are making heavy use of this method).
+     */
+    public static URLConnection connectToUrl(String u) throws Exception {
+        final URL url = new URL(u);
+        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+
+        // sometimes openConnection hangs, so run in background
+        Future<URLConnection> f = executor.submit(new Callable<URLConnection>() {
+            public URLConnection call() {
+                try {
+                    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+                        @Override
+                        public boolean verify(String s, SSLSession sslSession) {
+                            return true;
+                        }
+                    });
+                    URLConnection connection = url.openConnection();
+                    TrustingSslSocketFactory.configure(connection);
+                    connection.connect();
+
+                    connection.getContentLength(); // Make sure the connection is made.
+                    return connection;
+                } catch (Exception e) {
+                    exception.set(e);
+                    LOG.debug("Error connecting to url "+url+" (propagating): "+e, e);
+                }
+                return null;
+            }
+        });
+        try {
+            URLConnection result = null;
+            try {
+                result = f.get(60, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                throw e;
+            } catch (Exception e) {
+                LOG.debug("Error connecting to url "+url+", probably timed out (rethrowing): "+e);
+                throw new IllegalStateException("Connect to URL not complete within 60 seconds, for url "+url+": "+e);
+            }
+            if (exception.get() != null) {
+                LOG.debug("Error connecting to url "+url+", thread caller of "+exception, new Throwable("source of rethrown error "+exception));
+                throw exception.get();
+            } else {
+                return result;
+            }
+        } finally {
+            f.cancel(true);
+        }
+    }
+
+
+
+    public static int getHttpStatusCode(String url) throws Exception {
+        URLConnection connection = connectToUrl(url);
+        long startTime = System.currentTimeMillis();
+        int status = ((HttpURLConnection) connection).getResponseCode();
+
+        // read fully if possible, then close everything, trying to prevent cached threads at server
+        consumeAndCloseQuietly((HttpURLConnection) connection);
+
+        if (LOG.isDebugEnabled())
+            LOG.debug("connection to {} ({}ms) gives {}", new Object[] { url, (System.currentTimeMillis()-startTime), status });
+        return status;
+    }
+
+
+    public static String getContent(String url) {
+        try {
+            return Streams.readFullyString(SslTrustUtils.trustAll(new URL(url).openConnection()).getInputStream());
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public static String getErrorContent(String url) {
+        try {
+            HttpURLConnection connection = (HttpURLConnection) connectToUrl(url);
+            long startTime = System.currentTimeMillis();
+
+            String err;
+            int status;
+            try {
+                InputStream errStream = connection.getErrorStream();
+                err = Streams.readFullyString(errStream);
+                status = connection.getResponseCode();
+            } finally {
+                closeQuietly(connection);
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("read of err {} ({}ms) complete; http code {}", new Object[] { url, Time.makeTimeStringRounded(System.currentTimeMillis() - startTime), status});
+            return err;
+
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    /**
+     * Consumes the input stream entirely and then cleanly closes the connection.
+     * Ignores all exceptions completely, not even logging them!
+     *
+     * Consuming the stream fully is useful for preventing idle TCP connections.
+     * @see <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html">Persistent Connections</a>
+     */
+    public static void consumeAndCloseQuietly(HttpURLConnection connection) {
+        try { Streams.readFully(connection.getInputStream()); } catch (Exception e) {}
+        closeQuietly(connection);
+    }
+
+    /**
+     * Closes all streams of the connection, and disconnects it. Ignores all exceptions completely,
+     * not even logging them!
+     */
+    public static void closeQuietly(HttpURLConnection connection) {
+        try { connection.disconnect(); } catch (Exception e) {}
+        try { connection.getInputStream().close(); } catch (Exception e) {}
+        try { connection.getOutputStream().close(); } catch (Exception e) {}
+        try { connection.getErrorStream().close(); } catch (Exception e) {}
+    }
+
+    /** Apache HTTP commons utility for trusting all.
+     * <p>
+     * For generic java HTTP usage, see {@link SslTrustUtils#trustAll(java.net.URLConnection)} 
+     * and static constants in the same class. */
+    public static class TrustAllStrategy implements TrustStrategy {
+        @Override
+        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+            return true;
+        }
+    }
+
+    public static HttpClientBuilder httpClientBuilder() {
+        return new HttpClientBuilder();
+    }
+    
+    public static class HttpClientBuilder {
+        private ClientConnectionManager clientConnectionManager;
+        private HttpParams httpParams;
+        private URI uri;
+        private Integer port;
+        private Credentials credentials;
+        private boolean laxRedirect;
+        private Boolean https;
+        private SchemeSocketFactory socketFactory;
+        private ConnectionReuseStrategy reuseStrategy;
+        private boolean trustAll;
+        private boolean trustSelfSigned;
+
+        public HttpClientBuilder clientConnectionManager(ClientConnectionManager val) {
+            this.clientConnectionManager = checkNotNull(val, "clientConnectionManager");
+            return this;
+        }
+        public HttpClientBuilder httpParams(HttpParams val) {
+            checkState(httpParams == null, "Must not call httpParams multiple times, or after other methods like connectionTimeout");
+            this.httpParams = checkNotNull(val, "httpParams");
+            return this;
+        }
+        public HttpClientBuilder connectionTimeout(Duration val) {
+            if (httpParams == null) httpParams = new BasicHttpParams();
+            long millis = checkNotNull(val, "connectionTimeout").toMilliseconds();
+            if (millis > Integer.MAX_VALUE) throw new IllegalStateException("HttpClient only accepts upto max-int millis for connectionTimeout, but given "+val);
+            HttpConnectionParams.setConnectionTimeout(httpParams, (int) millis);
+            return this;
+        }
+        public HttpClientBuilder socketTimeout(Duration val) {
+            if (httpParams == null) httpParams = new BasicHttpParams();
+            long millis = checkNotNull(val, "socketTimeout").toMilliseconds();
+            if (millis > Integer.MAX_VALUE) throw new IllegalStateException("HttpClient only accepts upto max-int millis for socketTimeout, but given "+val);
+            HttpConnectionParams.setSoTimeout(httpParams, (int) millis);
+            return this;
+        }
+        public HttpClientBuilder reuseStrategy(ConnectionReuseStrategy val) {
+            this.reuseStrategy = checkNotNull(val, "reuseStrategy");
+            return this;
+        }
+        public HttpClientBuilder uri(String val) {
+            return uri(URI.create(checkNotNull(val, "uri")));
+        }
+        public HttpClientBuilder uri(URI val) {
+            this.uri = checkNotNull(val, "uri");
+            if (https == null) https = ("https".equalsIgnoreCase(uri.getScheme()));
+            return this;
+        }
+        public HttpClientBuilder port(int val) {
+            this.port = val;
+            return this;
+        }
+        public HttpClientBuilder credentials(Credentials val) {
+            this.credentials = checkNotNull(val, "credentials");
+            return this;
+        }
+        public void credential(Optional<Credentials> val) {
+            if (val.isPresent()) credentials = val.get();
+        }
+        /** similar to curl --post301 -L` */
+        public HttpClientBuilder laxRedirect(boolean val) {
+            this.laxRedirect = val;
+            return this;
+        }
+        public HttpClientBuilder https(boolean val) {
+            this.https = val;
+            return this;
+        }
+        public HttpClientBuilder socketFactory(SchemeSocketFactory val) {
+            this.socketFactory = checkNotNull(val, "socketFactory");
+            return this;
+        }
+        public HttpClientBuilder trustAll() {
+            this.trustAll = true;
+            return this;
+        }
+        public HttpClientBuilder trustSelfSigned() {
+            this.trustSelfSigned = true;
+            return this;
+        }
+        public HttpClient build() {
+            final DefaultHttpClient httpClient = new DefaultHttpClient(clientConnectionManager);
+            httpClient.setParams(httpParams);
+    
+            // support redirects for POST (similar to `curl --post301 -L`)
+            // http://stackoverflow.com/questions/3658721/httpclient-4-error-302-how-to-redirect
+            if (laxRedirect) {
+                httpClient.setRedirectStrategy(new LaxRedirectStrategy());
+            }
+            if (reuseStrategy != null) {
+                httpClient.setReuseStrategy(reuseStrategy);
+            }
+            if (https == Boolean.TRUE || (uri!=null && uri.toString().startsWith("https:"))) {
+                try {
+                    if (port == null) {
+                        port = (uri != null && uri.getPort() >= 0) ? uri.getPort() : 443;
+                    }
+                    if (socketFactory == null) {
+                        if (trustAll) {
+                            TrustStrategy trustStrategy = new TrustAllStrategy();
+                            X509HostnameVerifier hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
+                            socketFactory = new SSLSocketFactory(trustStrategy, hostnameVerifier);
+                        } else if (trustSelfSigned) {
+                            TrustStrategy trustStrategy = new TrustSelfSignedStrategy();
+                            X509HostnameVerifier hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
+                            socketFactory = new SSLSocketFactory(trustStrategy, hostnameVerifier);
+                        } else {
+                            // Using default https scheme: based on default java truststore, which is pretty strict!
+                        }
+                    }
+                    if (socketFactory != null) {
+                        Scheme sch = new Scheme("https", port, socketFactory);
+                        httpClient.getConnectionManager().getSchemeRegistry().register(sch);
+                    }
+                } catch (Exception e) {
+                    LOG.warn("Error setting trust for uri {}", uri);
+                    throw Exceptions.propagate(e);
+                }
+            }
+    
+            // Set credentials
+            if (uri != null && credentials != null) {
+                String hostname = uri.getHost();
+                int port = uri.getPort();
+                httpClient.getCredentialsProvider().setCredentials(new AuthScope(hostname, port), credentials);
+            }
+            if (uri==null && credentials!=null) {
+                LOG.warn("credentials have no effect in builder unless URI for host is specified");
+            }
+    
+            return httpClient;
+        }
+    }
+
+    protected static abstract class HttpRequestBuilder<B extends HttpRequestBuilder<B, R>, R extends HttpRequest> {
+        protected R req;
+        
+        protected HttpRequestBuilder(R req) {
+            this.req = req;
+        }
+        @SuppressWarnings("unchecked")
+        protected B self() {
+            return (B) this;
+        }
+        public B headers(Map<String,String> headers) {
+            if (headers!=null) {
+                for (Map.Entry<String,String> entry : headers.entrySet()) {
+                    req.addHeader(entry.getKey(), entry.getValue());
+                }
+            }
+            return self();
+        }
+        public B headers(Multimap<String,String> headers) {
+            if (headers!=null) {
+                for (Map.Entry<String,String> entry : headers.entries()) {
+                    req.addHeader(entry.getKey(), entry.getValue());
+                }
+            }
+            return self();
+        }
+        public R build() {
+            return req;
+        }
+    }
+    
+    protected static abstract class HttpEntityEnclosingRequestBaseBuilder<B extends HttpEntityEnclosingRequestBaseBuilder<B,R>, R extends HttpEntityEnclosingRequestBase> extends HttpRequestBuilder<B, R> {
+        protected HttpEntityEnclosingRequestBaseBuilder(R req) {
+            super(req);
+        }
+        public B body(byte[] body) {
+            if (body != null) {
+                HttpEntity httpEntity = new ByteArrayEntity(body);
+                req.setEntity(httpEntity);
+            }
+            return self();
+        }
+    }
+    
+    public static class HttpGetBuilder extends HttpRequestBuilder<HttpGetBuilder, HttpGet> {
+        public HttpGetBuilder(URI uri) {
+            super(new HttpGet(uri));
+        }
+    }
+    
+    public static class HttpHeadBuilder extends HttpRequestBuilder<HttpHeadBuilder, HttpHead> {
+        public HttpHeadBuilder(URI uri) {
+            super(new HttpHead(uri));
+        }
+    }
+    
+    public static class HttpDeleteBuilder extends HttpRequestBuilder<HttpDeleteBuilder, HttpDelete> {
+        public HttpDeleteBuilder(URI uri) {
+            super(new HttpDelete(uri));
+        }
+    }
+    
+    public static class HttpPostBuilder extends HttpEntityEnclosingRequestBaseBuilder<HttpPostBuilder, HttpPost> {
+        HttpPostBuilder(URI uri) {
+            super(new HttpPost(uri));
+        }
+    }
+
+    public static class HttpFormPostBuilder extends HttpRequestBuilder<HttpFormPostBuilder, HttpPost> {
+        HttpFormPostBuilder(URI uri) {
+            super(new HttpPost(uri));
+        }
+
+        public HttpFormPostBuilder params(Map<String, String> params) {
+            if (params != null) {
+                Collection<NameValuePair> httpParams = new ArrayList<NameValuePair>(params.size());
+                for (Entry<String, String> param : params.entrySet()) {
+                    httpParams.add(new BasicNameValuePair(param.getKey(), param.getValue()));
+                }
+                req.setEntity(new UrlEncodedFormEntity(httpParams));
+            }
+            return self();
+        }
+    }
+
+    public static class HttpPutBuilder extends HttpEntityEnclosingRequestBaseBuilder<HttpPutBuilder, HttpPut> {
+        public HttpPutBuilder(URI uri) {
+            super(new HttpPut(uri));
+        }
+    }
+    
+    public static HttpToolResponse httpGet(HttpClient httpClient, URI uri, Map<String,String> headers) {
+        HttpGet req = new HttpGetBuilder(uri).headers(headers).build();
+        return execAndConsume(httpClient, req);
+    }
+
+    public static HttpToolResponse httpPost(HttpClient httpClient, URI uri, Map<String,String> headers, byte[] body) {
+        HttpPost req = new HttpPostBuilder(uri).headers(headers).body(body).build();
+        return execAndConsume(httpClient, req);
+    }
+
+    public static HttpToolResponse httpPut(HttpClient httpClient, URI uri, Map<String, String> headers, byte[] body) {
+        HttpPut req = new HttpPutBuilder(uri).headers(headers).body(body).build();
+        return execAndConsume(httpClient, req);
+    }
+
+    public static HttpToolResponse httpPost(HttpClient httpClient, URI uri, Map<String,String> headers, Map<String, String> params) {
+        HttpPost req = new HttpFormPostBuilder(uri).headers(headers).params(params).build();
+        return execAndConsume(httpClient, req);
+    }
+
+    public static HttpToolResponse httpDelete(HttpClient httpClient, URI uri, Map<String,String> headers) {
+        HttpDelete req = new HttpDeleteBuilder(uri).headers(headers).build();
+        return execAndConsume(httpClient, req);
+    }
+    
+    public static HttpToolResponse httpHead(HttpClient httpClient, URI uri, Map<String,String> headers) {
+        HttpHead req = new HttpHeadBuilder(uri).headers(headers).build();
+        return execAndConsume(httpClient, req);
+    }
+    
+    public static HttpToolResponse execAndConsume(HttpClient httpClient, HttpUriRequest req) {
+        long startTime = System.currentTimeMillis();
+        try {
+            HttpResponse httpResponse = httpClient.execute(req);
+            
+            try {
+                return new HttpToolResponse(httpResponse, startTime);
+            } finally {
+                EntityUtils.consume(httpResponse.getEntity());
+            }
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+    
+    public static boolean isStatusCodeHealthy(int code) { return (code>=200 && code<=299); }
+
+    public static String toBasicAuthorizationValue(UsernamePasswordCredentials credentials) {
+        return "Basic "+Base64.encodeBase64String( (credentials.getUserName()+":"+credentials.getPassword()).getBytes() );
+    }
+
+    public static String encodeUrlParams(Map<?,?> data) {
+        if (data==null) return "";
+        Iterable<String> args = Iterables.transform(data.entrySet(), 
+            new Function<Map.Entry<?,?>,String>() {
+            @Override public String apply(Map.Entry<?,?> entry) {
+                Object k = entry.getKey();
+                Object v = entry.getValue();
+                return URLParamEncoder.encode(Strings.toString(k)) + (v != null ? "=" + URLParamEncoder.encode(Strings.toString(v)) : "");
+            }
+        });
+        return Joiner.on("&").join(args);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
new file mode 100644
index 0000000..70bcb17
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpToolResponse.java
@@ -0,0 +1,183 @@
+/*
+ * 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 org.apache.brooklyn.util.http;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.io.ByteStreams;
+
+public class HttpToolResponse {
+
+    private static final Logger log = LoggerFactory.getLogger(HttpToolResponse.class);
+    
+    private final Object mutex = new Object();
+    private final HttpResponse response;
+    private final long startTime;
+    private final long durationMillisOfFirstResponse;
+    private final long durationMillisOfFullContent;
+    private int responseCode;
+    private String reasonPhrase;
+    private Map<String,List<String>> headerLists;
+    private byte[] content;
+
+
+    public HttpToolResponse(HttpResponse response, long startTime) {
+        this.response = response;
+        this.startTime = startTime; 
+        
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            HttpEntity entity = response.getEntity();
+            if (entity != null) {
+                entity.getContentLength();
+                durationMillisOfFirstResponse = Duration.sinceUtc(startTime).toMilliseconds();
+
+                ByteStreams.copy(entity.getContent(), out);
+                content = out.toByteArray();
+
+                entity.getContentLength();
+            } else {
+                durationMillisOfFirstResponse = Duration.sinceUtc(startTime).toMilliseconds();
+                content = new byte[0];
+            }
+            durationMillisOfFullContent = Duration.sinceUtc(startTime).toMilliseconds();
+            if (log.isTraceEnabled())
+                log.trace("HttpPollValue latency "+Time.makeTimeStringRounded(durationMillisOfFirstResponse)+" / "+Time.makeTimeStringRounded(durationMillisOfFullContent)+", content size "+content.length);
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    public HttpToolResponse(int responseCode, Map<String,? extends List<String>> headers, byte[] content,
+            long startTime, long durationMillisOfFirstResponse, long durationMillisOfFullContent) {
+        this.response = null;
+        this.responseCode = responseCode;
+        this.headerLists = ImmutableMap.copyOf(headers);
+        this.content = content;
+        this.startTime = startTime;
+        this.durationMillisOfFirstResponse = durationMillisOfFirstResponse;
+        this.durationMillisOfFullContent = durationMillisOfFullContent;
+    }
+    
+    public int getResponseCode() {
+        synchronized (mutex) {
+            if (responseCode == 0) {
+                responseCode = response.getStatusLine().getStatusCode();
+            }
+        }
+        return responseCode;
+    }
+
+    public String getReasonPhrase() {
+        synchronized (mutex) {
+            if (reasonPhrase == null) {
+                reasonPhrase = response.getStatusLine().getReasonPhrase();
+            }
+        }
+        return reasonPhrase;
+    }
+
+    /** returns the timestamp (millis since 1970) when this request was started */ 
+    public long getStartTime() {
+        return startTime;
+    }
+    
+    /** returns latency, in milliseconds, if value was initialized with a start time */
+    public long getLatencyFullContent() {
+        return durationMillisOfFullContent;
+    }
+    
+    /** returns latency, in milliseconds, before response started coming in */
+    public long getLatencyFirstResponse() {
+        return durationMillisOfFirstResponse;
+    }
+    
+    public Map<String, List<String>> getHeaderLists() {
+        synchronized (mutex) {
+            if (headerLists == null) {
+                Map<String, List<String>> headerListsMutable = Maps.newLinkedHashMap();
+                for (Header header : response.getAllHeaders()) {
+                    List<String> vals = headerListsMutable.get(header.getName());
+                    if (vals == null) {
+                        vals = new ArrayList<String>();
+                        headerListsMutable.put(header.getName(), vals);
+                    }
+                    vals.add(header.getValue());
+                }
+                headerLists = Collections.unmodifiableMap(headerListsMutable);
+            }
+        }
+        return headerLists;
+    }
+    
+    public byte[] getContent() {
+        synchronized (mutex) {
+            if (content == null) {
+                InputStream in = null;
+                try {
+                    in = response.getEntity().getContent();
+                    ByteArrayOutputStream out = new ByteArrayOutputStream();
+                    ByteStreams.copy(in, out);
+                    content = out.toByteArray();
+                } catch (IOException e) {
+                    throw Throwables.propagate(e);
+                } finally {
+                    Streams.closeQuietly(in);
+                }
+            }
+        }
+        return content;
+    }
+
+    public String getContentAsString() {
+        return new String(getContent());
+    }
+    
+    public Maybe<HttpResponse> getResponse() {
+        return Maybe.fromNullable(response);
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(getClass())
+                .add("responseCode", responseCode)
+                .toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/03dbd281/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java b/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
deleted file mode 100644
index 8eeef19..0000000
--- a/utils/common/src/main/java/org/apache/brooklyn/util/http/HttpUtils.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * 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 org.apache.brooklyn.util.http;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSession;
-
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.crypto.SslTrustUtils;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-
-/**
- * Utility methods to aid testing HTTP.
- * 
- * @author aled
- */
-public class HttpUtils {
-
-    // TODO Delete methods from TestUtils, to just have them here (or switch so TestUtils delegates here,
-    // and deprecate methods in TestUtils until deleted).
-
-    private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class);
-
-    static final ExecutorService executor = Executors.newCachedThreadPool();
-    
-    /**
-     * Connects to the given url and returns the connection.
-     * Caller should {@code connection.getInputStream().close()} the result of this
-     * (especially if they are making heavy use of this method).
-     */
-    public static URLConnection connectToUrl(String u) throws Exception {
-        final URL url = new URL(u);
-        final AtomicReference<Exception> exception = new AtomicReference<Exception>();
-        
-        // sometimes openConnection hangs, so run in background
-        Future<URLConnection> f = executor.submit(new Callable<URLConnection>() {
-            public URLConnection call() {
-                try {
-                    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
-                        @Override public boolean verify(String s, SSLSession sslSession) {
-                            return true;
-                        }
-                    });
-                    URLConnection connection = url.openConnection();
-                    TrustingSslSocketFactory.configure(connection);
-                    connection.connect();
-    
-                    connection.getContentLength(); // Make sure the connection is made.
-                    return connection;
-                } catch (Exception e) {
-                    exception.set(e);
-                    LOG.debug("Error connecting to url "+url+" (propagating): "+e, e);
-                }
-                return null;
-            }
-        });
-        try {
-            URLConnection result = null;
-            try {
-                result = f.get(60, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                throw e;
-            } catch (Exception e) {
-                LOG.debug("Error connecting to url "+url+", probably timed out (rethrowing): "+e);
-                throw new IllegalStateException("Connect to URL not complete within 60 seconds, for url "+url+": "+e);
-            }
-            if (exception.get() != null) {
-                LOG.debug("Error connecting to url "+url+", thread caller of "+exception, new Throwable("source of rethrown error "+exception));
-                throw exception.get();
-            } else {
-                return result;
-            }
-        } finally {
-            f.cancel(true);
-        }
-    }
-
-    public static void assertHealthyStatusCode(int code) {
-        if (code>=200 && code<=299) return;
-        Asserts.fail("Wrong status code: " + code);
-    }
-    
-    public static int getHttpStatusCode(String url) throws Exception {
-        URLConnection connection = connectToUrl(url);
-        long startTime = System.currentTimeMillis();
-        int status = ((HttpURLConnection) connection).getResponseCode();
-        
-        // read fully if possible, then close everything, trying to prevent cached threads at server
-        consumeAndCloseQuietly((HttpURLConnection) connection);
-        
-        if (LOG.isDebugEnabled())
-            LOG.debug("connection to {} ({}ms) gives {}", new Object[] { url, (System.currentTimeMillis()-startTime), status });
-        return status;
-    }
-
-    /**
-     * Asserts that gets back any "valid" response - i.e. not an exception. This could be an unauthorized,
-     * a redirect, a 404, or anything else that implies there is web-server listening on that port.
-     */
-    public static void assertUrlReachable(String url) {
-        try {
-            getHttpStatusCode(url);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException("Interrupted for "+url+" (in assertion that is reachable)", e);
-        } catch (Exception e) {
-            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that is reachable): "+e, e);
-        }
-    }
-
-    public static void assertUrlUnreachable(String url) {
-        try {
-            int statusCode = getHttpStatusCode(url);
-            Asserts.fail("Expected url " + url + " unreachable, but got status code " + statusCode);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException("Interrupted for "+url+" (in assertion that unreachable)", e);
-        } catch (Exception e) {
-            IOException cause = Exceptions.getFirstThrowableOfType(e, IOException.class);
-            if (cause != null) {
-                // success; clean shutdown transitioning from 400 to error
-            } else {
-                Throwables.propagate(e);
-            }                        
-        }
-    }
-
-    public static void assertUrlUnreachableEventually(final String url) {
-        assertUrlUnreachableEventually(Maps.newLinkedHashMap(), url);
-    }
-    
-    public static void assertUrlUnreachableEventually(Map flags, final String url) {
-        Asserts.succeedsEventually(flags, new Runnable() {
-            public void run() {
-                assertUrlUnreachable(url);
-            }
-         });
-    }
-
-    public static void assertHttpStatusCodeEquals(String url, int... acceptableReturnCodes) {
-        List<Integer> acceptableCodes = Lists.newArrayList();
-        for (int code : acceptableReturnCodes) {
-            acceptableCodes.add((Integer)code);
-        }
-        try {
-            int actualCode = getHttpStatusCode(url);
-            Asserts.assertTrue(acceptableCodes.contains(actualCode), "code=" + actualCode + "; expected=" + acceptableCodes + "; url=" + url);
-            
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException("Interrupted for "+url+" (in assertion that result code is "+acceptableCodes+")", e);
-        } catch (Exception e) {
-            throw new IllegalStateException("Server at "+url+" Asserts.failed to respond (in assertion that result code is "+acceptableCodes+"): "+e, e);
-        }
-    }
-
-    public static void assertHttpStatusCodeEventuallyEquals(final String url, final int expectedCode) {
-        assertHttpStatusCodeEventuallyEquals(Maps.newLinkedHashMap(),  url, expectedCode);
-    }
-
-    public static void assertHttpStatusCodeEventuallyEquals(Map flags, final String url, final int expectedCode) {
-        Asserts.succeedsEventually(flags, new Runnable() {
-            public void run() {
-                assertHttpStatusCodeEquals(url, expectedCode);
-            }
-         });
-    }
-
-    public static void assertContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
-        try {
-            String contents = getContent(url);
-            Asserts.assertTrue(contents != null && contents.length() > 0);
-            for (String text: Lists.asList(phrase, additionalPhrases)) {
-                if (!contents.contains(text)) {
-                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
-                    Asserts.fail("URL "+url+" does not contain text: "+text);
-                }
-            }
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    public static void assertContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
-        try {
-            String contents = getContent(url);
-            Asserts.assertTrue(contents != null);
-            for (String text: Lists.asList(phrase, additionalPhrases)) {
-                if (contents.contains(text)) {
-                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+contents);
-                    Asserts.fail("URL "+url+" contain text: "+text);
-                }
-            }
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    public static void assertErrorContentContainsText(final String url, final String phrase, final String ...additionalPhrases) {
-        try {
-            String contents = getErrorContent(url);
-            Asserts.assertTrue(contents != null && contents.length() > 0);
-            for (String text: Lists.asList(phrase, additionalPhrases)) {
-                if (!contents.contains(text)) {
-                    LOG.warn("CONTENTS OF URL "+url+" MISSING TEXT: "+text+"\n"+contents);
-                    Asserts.fail("URL "+url+" does not contain text: "+text);
-                }
-            }
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-
-    public static void assertErrorContentNotContainsText(final String url, final String phrase, final String ...additionalPhrases) {
-        try {
-            String err = getErrorContent(url);
-            Asserts.assertTrue(err != null);
-            for (String text: Lists.asList(phrase, additionalPhrases)) {
-                if (err.contains(text)) {
-                    LOG.warn("CONTENTS OF URL "+url+" HAS TEXT: "+text+"\n"+err);
-                    Asserts.fail("URL "+url+" contain text: "+text);
-                }
-            }
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-    
-    public static void assertContentEventuallyContainsText(final String url, final String phrase, final String ...additionalPhrases) {
-        assertContentEventuallyContainsText(MutableMap.of(), url, phrase, additionalPhrases);
-    }
-    
-    public static void assertContentEventuallyContainsText(Map flags, final String url, final String phrase, final String ...additionalPhrases) {
-        Asserts.succeedsEventually(flags, new Runnable() {
-            public void run() {
-                assertContentContainsText(url, phrase, additionalPhrases);
-            }
-         });
-    }
-    
-    public static void assertContentMatches(String url, String regex) {
-        String contents = getContent(url);
-        Asserts.assertNotNull(contents);
-        Asserts.assertTrue(contents.matches(regex), "Contents does not match expected regex ("+regex+"): "+contents);
-    }
-
-    public static void assertContentEventuallyMatches(final String url, final String regex) {
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                assertContentMatches(url, regex);
-            }
-        });
-    }
-    
-    public static String getErrorContent(String url) {
-        try {
-            HttpURLConnection connection = (HttpURLConnection) connectToUrl(url);
-            long startTime = System.currentTimeMillis();
-            
-            String err;
-            int status;
-            try {
-                InputStream errStream = connection.getErrorStream();
-                err = Streams.readFullyString(errStream);
-                status = connection.getResponseCode();
-            } finally {
-                closeQuietly(connection);
-            }
-            
-            if (LOG.isDebugEnabled())
-                LOG.debug("read of err {} ({}ms) complete; http code {}", new Object[] { url, Time.makeTimeStringRounded(System.currentTimeMillis()-startTime), status});
-            return err;
-
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    public static String getContent(String url) {
-        try {
-            return Streams.readFullyString(SslTrustUtils.trustAll(new URL(url).openConnection()).getInputStream());
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * Schedules (with the given executor) a poller that repeatedly accesses the given url, to confirm it always gives
-     * back the expected status code.
-     * 
-     * Expected usage is to query the future, such as:
-     * 
-     * <pre>
-     * {@code
-     * Future<?> future = assertAsyncHttpStatusCodeContinuallyEquals(executor, url, 200);
-     * // do other stuff...
-     * if (future.isDone()) future.get(); // get exception if it's Asserts.failed
-     * }
-     * </pre>
-     * 
-     * For stopping it, you can either do future.cancel(true), or you can just do executor.shutdownNow().
-     * 
-     * TODO Look at difference between this and WebAppMonitor, to decide if this should be kept.
-     */
-    public static ListenableFuture<?> assertAsyncHttpStatusCodeContinuallyEquals(ListeningExecutorService executor, final String url, final int expectedStatusCode) {
-        return executor.submit(new Runnable() {
-            @Override public void run() {
-                // TODO Need to drop logging; remove sleep when that's done.
-                while (!Thread.currentThread().isInterrupted()) {
-                    assertHttpStatusCodeEquals(url, expectedStatusCode);
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e) {
-                        return; // graceful return
-                    }
-                }
-            }
-        });
-    }
-    
-    /**
-     * Consumes the input stream entirely and then cleanly closes the connection.
-     * Ignores all exceptions completely, not even logging them!
-     * 
-     * Consuming the stream fully is useful for preventing idle TCP connections.
-     * @see <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html">Persistent Connections</a>
-     */
-    public static void consumeAndCloseQuietly(HttpURLConnection connection) {
-        try { Streams.readFully(connection.getInputStream()); } catch (Exception e) {}
-        closeQuietly(connection);
-    }
-    
-    /**
-     * Closes all streams of the connection, and disconnects it. Ignores all exceptions completely,
-     * not even logging them!
-     */
-    public static void closeQuietly(HttpURLConnection connection) {
-        try { connection.disconnect(); } catch (Exception e) {}
-        try { connection.getInputStream().close(); } catch (Exception e) {}
-        try { connection.getOutputStream().close(); } catch (Exception e) {}
-        try { connection.getErrorStream().close(); } catch (Exception e) {}
-    }
-}