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

[01/18] incubator-brooklyn git commit: Support suppressDuplicates for attributes in feeds

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 0dc391191 -> ef3af1213


Support suppressDuplicates for attributes in feeds


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

Branch: refs/heads/master
Commit: 7f046a1ce49591cfabd211c03bbcc57f93c65137
Parents: ee3c1ca
Author: Aled Sage <al...@gmail.com>
Authored: Sat Apr 18 12:50:48 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 17:51:12 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/event/feed/AttributePollHandler.java | 12 +++++++++++-
 core/src/main/java/brooklyn/event/feed/FeedConfig.java | 13 ++++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7f046a1c/core/src/main/java/brooklyn/event/feed/AttributePollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/AttributePollHandler.java b/core/src/main/java/brooklyn/event/feed/AttributePollHandler.java
index 2029237..1bf39af 100644
--- a/core/src/main/java/brooklyn/event/feed/AttributePollHandler.java
+++ b/core/src/main/java/brooklyn/event/feed/AttributePollHandler.java
@@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Objects;
+
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
@@ -52,6 +54,7 @@ public class AttributePollHandler<V> implements PollHandler<V> {
     @SuppressWarnings("rawtypes")
     private final AttributeSensor sensor;
     private final AbstractFeed feed;
+    private final boolean suppressDuplicates;
     
     // allow 30 seconds before logging at WARN, if there has been no success yet;
     // after success WARN immediately
@@ -64,12 +67,14 @@ public class AttributePollHandler<V> implements PollHandler<V> {
     private volatile Long currentProblemStartTime = null;
     private volatile boolean currentProblemLoggedAsWarning = false;
     private volatile boolean lastWasProblem = false;
+
     
     public AttributePollHandler(FeedConfig<V,?,?> config, EntityLocal entity, AbstractFeed feed) {
         this.config = checkNotNull(config, "config");
         this.entity = checkNotNull(entity, "entity");
         this.sensor = checkNotNull(config.getSensor(), "sensor");
         this.feed = checkNotNull(feed, "feed");
+        this.suppressDuplicates = config.getSupressDuplicates();
     }
 
     @Override
@@ -218,7 +223,12 @@ public class AttributePollHandler<V> implements PollHandler<V> {
         } else if (sensor == FeedConfig.NO_SENSOR) {
             // nothing
         } else {
-            entity.setAttribute(sensor, TypeCoercions.coerce(v, sensor.getType()));
+            Object coercedV = TypeCoercions.coerce(v, sensor.getType());
+            if (suppressDuplicates && Objects.equal(coercedV, entity.getAttribute(sensor))) {
+                // no change; nothing
+            } else {
+                entity.setAttribute(sensor, coercedV);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7f046a1c/core/src/main/java/brooklyn/event/feed/FeedConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/FeedConfig.java b/core/src/main/java/brooklyn/event/feed/FeedConfig.java
index 64642e1..6796730 100644
--- a/core/src/main/java/brooklyn/event/feed/FeedConfig.java
+++ b/core/src/main/java/brooklyn/event/feed/FeedConfig.java
@@ -62,7 +62,8 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
     private Function<? super V, T> onfailure;
     private Function<? super Exception, T> onexception;
     private Predicate<? super V> checkSuccess;
-
+    private boolean suppressDuplicates;
+    
     public FeedConfig(AttributeSensor<T> sensor) {
         this.sensor = checkNotNull(sensor, "sensor");
     }
@@ -73,6 +74,7 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         this.onfailure = other.onfailure;
         this.onexception = other.onexception;
         this.checkSuccess = other.checkSuccess;
+        this.suppressDuplicates = other.suppressDuplicates;
     }
 
     @SuppressWarnings("unchecked")
@@ -100,6 +102,10 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         return onexception;
     }
 
+    public boolean getSupressDuplicates() {
+        return suppressDuplicates;
+    }
+    
     /** sets the predicate used to check whether a feed run is successful */
     public F checkSuccess(Predicate<? super V> val) {
         this.checkSuccess = checkNotNull(val, "checkSuccess");
@@ -175,6 +181,11 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         return onFailureOrException(Functions.constant(val));
     }
 
+    public F suppressDuplicates(boolean val) {
+        suppressDuplicates = val;
+        return self();
+    }
+    
     public boolean hasSuccessHandler() {
         return this.onsuccess != null;
     }


[04/18] incubator-brooklyn git commit: Adds TypeCoercions.function(Class)

Posted by al...@apache.org.
Adds TypeCoercions.function(Class)


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

Branch: refs/heads/master
Commit: ce0c4223c53aa32e3b15d6654072b4caa27ff834
Parents: 81650a8
Author: Aled Sage <al...@gmail.com>
Authored: Sat Apr 18 14:38:50 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 17:51:34 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/util/flags/TypeCoercions.java | 69 ++++++++++++++------
 .../util/internal/TypeCoercionsTest.java        |  5 ++
 2 files changed, 55 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ce0c4223/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
index 3b4ec3d..f1e3992 100644
--- a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
+++ b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
@@ -274,6 +274,28 @@ public class TypeCoercions {
     }
 
     /**
+     * Returns a function that does a type coercion to the given type. For example,
+     * {@code TypeCoercions.function(Double.class)} will return a function that will
+     * coerce its input value to a {@link Double} (or throw a {@link ClassCoercionException}
+     * if that is not possible).
+     */
+    public static <T> Function<Object, T> function(final Class<T> type) {
+        return new CoerceFunction<T>(type);
+    }
+    
+    private static class CoerceFunction<T> implements Function<Object, T> {
+        private final Class<T> type;
+
+        public CoerceFunction(Class<T> type) {
+            this.type = type;
+        }
+        @Override
+        public T apply(Object input) {
+            return coerce(input, type);
+        }
+    }
+
+    /**
      * Type coercion {@link Function function} for {@link Enum enums}.
      * <p>
      * Tries to convert the string to {@link CaseFormat#UPPER_UNDERSCORE} first,
@@ -286,27 +308,36 @@ public class TypeCoercions {
      * @see Enum#valueOf(Class, String)
      */
     public static <E extends Enum<E>> Function<String, E> stringToEnum(final Class<E> type, @Nullable final E defaultValue) {
-        return new Function<String, E>() {
-            @Override
-            public E apply(String input) {
-                Preconditions.checkNotNull(input, "input");
-                List<String> options = ImmutableList.of(
-                        input,
-                        CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, input),
-                        CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, input),
-                        CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, input),
-                        CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, input));
-                for (String value : options) {
-                    try {
-                        return Enum.valueOf(type, value);
-                    } catch (IllegalArgumentException iae) {
-                        continue;
-                    }
+        return new StringToEnumFunction<E>(type, defaultValue);
+    }
+    
+    private static class StringToEnumFunction<E extends Enum<E>> implements Function<String, E> {
+        private final Class<E> type;
+        private final E defaultValue;
+        
+        public StringToEnumFunction(Class<E> type, @Nullable E defaultValue) {
+            this.type = type;
+            this.defaultValue = defaultValue;
+        }
+        @Override
+        public E apply(String input) {
+            Preconditions.checkNotNull(input, "input");
+            List<String> options = ImmutableList.of(
+                    input,
+                    CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, input),
+                    CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, input),
+                    CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, input),
+                    CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, input));
+            for (String value : options) {
+                try {
+                    return Enum.valueOf(type, value);
+                } catch (IllegalArgumentException iae) {
+                    continue;
                 }
-                Maybe<E> result = Enums.valueOfIgnoreCase(type, input);
-                return (result.isPresent()) ? result.get() : defaultValue;
             }
-        };
+            Maybe<E> result = Enums.valueOfIgnoreCase(type, input);
+            return (result.isPresent()) ? result.get() : defaultValue;
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ce0c4223/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
index 66e7d2c..ecb8c7c 100644
--- a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
+++ b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
@@ -335,6 +335,11 @@ public class TypeCoercionsTest {
         TypeCoercions.coerce(new Object(), TypeToken.of(Integer.class));
     }
 
+    @Test
+    public void testCoercionFunction() {
+        assertEquals(TypeCoercions.function(Double.class).apply("1"), Double.valueOf(1));
+    }
+
     public static class WithAs {
         String value;
         public WithAs(Object x) { value = ""+x; }


[10/18] incubator-brooklyn git commit: Adds sensor-notifications for GROUP_ADDED/REMOVED

Posted by al...@apache.org.
Adds sensor-notifications for GROUP_ADDED/REMOVED


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

Branch: refs/heads/master
Commit: 0d9372babc4ec92e9b85e351142b8ea57000850b
Parents: 70dfb20
Author: Aled Sage <al...@gmail.com>
Authored: Wed May 27 11:47:19 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:29 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/AbstractEntity.java   | 24 +++++---
 .../brooklyn/entity/basic/EntityTypeTest.java   |  5 +-
 .../java/brooklyn/entity/group/GroupTest.java   | 58 ++++++++++++++------
 .../basic/RecordingSensorEventListener.java     |  2 +-
 4 files changed, 62 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d9372ba/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index aa40158..dfc8d35 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -119,9 +119,6 @@ import com.google.common.collect.Sets;
  * <p>
  * Note that config is typically inherited by children, whereas the fields and attributes are not.
  * <p>
- * Though currently Groovy code, this is very likely to change to pure Java in a future release of 
- * Brooklyn so Groovy'isms should not be relied on.
- * <p>
  * Sub-classes should have a no-argument constructor. When brooklyn creates an entity, it will:
  * <ol>
  *   <li>Construct the entity via the no-argument constructor
@@ -172,6 +169,11 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     public static final BasicNotificationSensor<Entity> CHILD_REMOVED = new BasicNotificationSensor<Entity>(Entity.class,
             "entity.children.removed", "Child dynamically removed from entity");
 
+    public static final BasicNotificationSensor<Group> GROUP_ADDED = new BasicNotificationSensor<Group>(Group.class,
+            "entity.group.added", "Group dynamically added to entity");
+    public static final BasicNotificationSensor<Group> GROUP_REMOVED = new BasicNotificationSensor<Group>(Group.class,
+            "entity.group.removed", "Group dynamically removed from entity");
+    
     static {
         RendererHints.register(Entity.class, RendererHints.displayValue(EntityFunctions.displayName()));
     }
@@ -673,15 +675,23 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     }
 
     @Override
-    public void addGroup(Group e) {
-        groups.add(e);
+    public void addGroup(Group group) {
+        boolean changed = groups.add(group);
         getApplication();
+        
+        if (changed) {
+            emit(AbstractEntity.GROUP_ADDED, group);
+        }
     }
 
     @Override
-    public void removeGroup(Group e) {
-        groups.remove(e);
+    public void removeGroup(Group group) {
+        boolean changed = groups.remove(group);
         getApplication();
+        
+        if (changed) {
+            emit(AbstractEntity.GROUP_REMOVED, group);
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d9372ba/core/src/test/java/brooklyn/entity/basic/EntityTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityTypeTest.java b/core/src/test/java/brooklyn/entity/basic/EntityTypeTest.java
index 7035ccd..ea27129 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityTypeTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityTypeTest.java
@@ -23,6 +23,8 @@ import static brooklyn.entity.basic.AbstractEntity.CHILD_REMOVED;
 import static brooklyn.entity.basic.AbstractEntity.EFFECTOR_ADDED;
 import static brooklyn.entity.basic.AbstractEntity.EFFECTOR_CHANGED;
 import static brooklyn.entity.basic.AbstractEntity.EFFECTOR_REMOVED;
+import static brooklyn.entity.basic.AbstractEntity.GROUP_ADDED;
+import static brooklyn.entity.basic.AbstractEntity.GROUP_REMOVED;
 import static brooklyn.entity.basic.AbstractEntity.LOCATION_ADDED;
 import static brooklyn.entity.basic.AbstractEntity.LOCATION_REMOVED;
 import static brooklyn.entity.basic.AbstractEntity.POLICY_ADDED;
@@ -72,7 +74,8 @@ public class EntityTypeTest extends BrooklynAppUnitTestSupport {
             EFFECTOR_ADDED, EFFECTOR_REMOVED, EFFECTOR_CHANGED,
             POLICY_ADDED, POLICY_REMOVED,
             CHILD_ADDED, CHILD_REMOVED,
-            LOCATION_ADDED, LOCATION_REMOVED); 
+            LOCATION_ADDED, LOCATION_REMOVED,
+            GROUP_ADDED, GROUP_REMOVED); 
 
     public static class EmptyEntityForTesting extends AbstractEntity {}
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d9372ba/core/src/test/java/brooklyn/entity/group/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/GroupTest.java b/core/src/test/java/brooklyn/entity/group/GroupTest.java
index 43a31c0..013b55e 100644
--- a/core/src/test/java/brooklyn/entity/group/GroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/GroupTest.java
@@ -20,49 +20,43 @@ package brooklyn.entity.group;
 
 import static org.testng.Assert.assertEquals;
 
-import org.testng.annotations.AfterMethod;
+import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Entity;
+import brooklyn.entity.Group;
+import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.LocationSpec;
 import brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
-import brooklyn.test.entity.TestApplication;
 import brooklyn.test.entity.TestEntity;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class GroupTest {
+public class GroupTest extends BrooklynAppUnitTestSupport {
 
-    private static final int TIMEOUT_MS = 2000;
-
-    private TestApplication app;
     private BasicGroup group;
     private TestEntity entity1;
     private TestEntity entity2;
     
     SimulatedLocation loc;
 
-
-    @BeforeMethod
-    public void setUp() {
-        app = TestApplication.Factory.newManagedInstanceForTests();
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
         loc = app.getManagementContext().getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
         group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
         entity1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
     }
 
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
     @Test
     public void testAddRemoveMembers() throws Exception {
         group.addMember(entity1);
@@ -115,6 +109,34 @@ public class GroupTest {
         Entities.unmanage(entity1);
     }
     
+    @Test
+    public void testAddingAndRemovingGroupEmitsNotification() throws Exception {
+        final RecordingSensorEventListener<Group> groupAddedListener = new RecordingSensorEventListener<>();
+        final RecordingSensorEventListener<Group> groupRemovedListener = new RecordingSensorEventListener<>();
+        mgmt.getSubscriptionManager().subscribe(entity1, AbstractEntity.GROUP_ADDED, groupAddedListener);
+        mgmt.getSubscriptionManager().subscribe(entity1, AbstractEntity.GROUP_REMOVED, groupRemovedListener);
+        
+        entity1.addGroup(group);
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String msg = "events="+groupAddedListener.getEvents();
+                assertEquals(groupAddedListener.getEvents().size(), 1, msg);
+                assertEquals(groupAddedListener.getEvents().get(0).getSource(), entity1, msg);
+                assertEquals(groupAddedListener.getEvents().get(0).getSensor(), AbstractEntity.GROUP_ADDED, msg);
+            }});
+        assertEquals(groupRemovedListener.getEvents().size(), 0, "events="+groupRemovedListener.getEvents());
+        
+        entity1.removeGroup(group);
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                String msg = "events="+groupRemovedListener.getEvents();
+                assertEquals(groupRemovedListener.getEvents().size(), 1, msg);
+                assertEquals(groupRemovedListener.getEvents().get(0).getSource(), entity1, msg);
+                assertEquals(groupRemovedListener.getEvents().get(0).getSensor(), AbstractEntity.GROUP_REMOVED, msg);
+            }});
+        assertEquals(groupAddedListener.getEvents().size(), 1, "events="+groupAddedListener.getEvents());
+    }
+    
     private void assertGroupMembers(Entity... expectedMembers) {
         Asserts.assertEqualsIgnoringOrder(group.getMembers(), ImmutableList.copyOf(expectedMembers));
         assertEquals(group.getAttribute(BasicGroup.GROUP_SIZE), (Integer)expectedMembers.length);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d9372ba/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java b/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
index 067b7d4..3cfcb27 100644
--- a/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
+++ b/core/src/test/java/org/apache/brooklyn/entity/basic/RecordingSensorEventListener.java
@@ -63,7 +63,7 @@ public class RecordingSensorEventListener<T> implements SensorEventListener<T>,
     /**
      * @return An immutable iterable of the recorded events.
      */
-    public Iterable<SensorEvent<T>> getEvents() {
+    public List<SensorEvent<T>> getEvents() {
         return ImmutableList.copyOf(events);
     }
 


[03/18] incubator-brooklyn git commit: Entities suppress duplicates in feeds

Posted by al...@apache.org.
Entities suppress duplicates in feeds


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

Branch: refs/heads/master
Commit: 81650a801f489db7d01a3f505a537363aa57a49f
Parents: 7f046a1
Author: Aled Sage <al...@gmail.com>
Authored: Sat Apr 18 13:01:36 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 17:51:23 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/SoftwareProcessImpl.java   |  1 +
 .../entity/database/mysql/MySqlNodeImpl.java         |  3 ++-
 .../messaging/activemq/ActiveMQBrokerImpl.java       |  3 ++-
 .../entity/nosql/cassandra/CassandraNodeImpl.java    | 15 ++++++++++-----
 .../entity/nosql/mongodb/MongoDBServerImpl.java      |  3 ++-
 .../entity/proxy/nginx/NginxControllerImpl.java      |  3 ++-
 .../entity/webapp/jboss/JBoss6ServerImpl.java        |  3 ++-
 .../entity/webapp/jboss/JBoss7ServerImpl.java        |  7 +++++--
 .../entity/webapp/tomcat/TomcatServerImpl.java       |  3 ++-
 9 files changed, 28 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
index 79275b2..3ae2c9e 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -214,6 +214,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
                 .entity(this)
                 .period(Duration.FIVE_SECONDS)
                 .poll(new FunctionPollConfig<Boolean, Boolean>(SERVICE_PROCESS_IS_RUNNING)
+                        .suppressDuplicates(true)
                         .onException(Functions.constant(Boolean.FALSE))
                         .callable(new Callable<Boolean>() {
                             public Boolean call() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index 2e05fb0..8346fbb 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -112,7 +112,8 @@ public class MySqlNodeImpl extends SoftwareProcessImpl implements MySqlNode {
                     .poll(new SshPollConfig<Boolean>(SERVICE_PROCESS_IS_RUNNING)
                             .command(cmd)
                             .setOnSuccess(true)
-                            .setOnFailureOrException(false))
+                            .setOnFailureOrException(false)
+                            .suppressDuplicates(true))
                     .build();
         } else {
             LOG.warn("Location(s) {} not an ssh-machine location, so not polling for status; setting serviceUp immediately", getLocations());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java b/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
index 19fae9d..83d8b6e 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
@@ -101,7 +101,8 @@ public class ActiveMQBrokerImpl extends JMSBrokerImpl<ActiveMQQueue, ActiveMQTop
                         .objectName(brokerMbeanName)
                         .attributeName("BrokerName")
                         .onSuccess(Functions.forPredicate(Predicates.notNull()))
-                        .onFailureOrException(Functions.constant(false)))
+                        .onFailureOrException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index 6d16c9a..c9923ef 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -414,7 +414,8 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
                         .objectName(storageServiceMBean)
                         .attributeName("Initialized")
                         .onSuccess(Functions.forPredicate(Predicates.notNull()))
-                        .onException(Functions.constant(false)))
+                        .onException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .pollAttribute(new JmxAttributePollConfig<Set<BigInteger>>(TOKENS)
                         .objectName(storageServiceMBean)
                         .attributeName("TokenToEndpointMap")
@@ -432,7 +433,8 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
                                 }
                                 return result;
                             }})
-                        .onException(Functions.<Set<BigInteger>>constant(null)))
+                        .onException(Functions.<Set<BigInteger>>constant(null))
+                        .suppressDuplicates(true))
                 .pollAttribute(new JmxAttributePollConfig<BigInteger>(TOKEN)
                         .objectName(storageServiceMBean)
                         .attributeName("TokenToEndpointMap")
@@ -448,19 +450,22 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
                                 String token = Iterables.getFirst(tokens, null);
                                 return (token != null) ? new BigInteger(token) : null;
                             }})
-                        .onException(Functions.<BigInteger>constant(null)))
+                        .onException(Functions.<BigInteger>constant(null))
+                        .suppressDuplicates(true))
                 .pollOperation(new JmxOperationPollConfig<String>(DATACENTER_NAME)
                         .period(60, TimeUnit.SECONDS)
                         .objectName(snitchMBean)
                         .operationName("getDatacenter")
                         .operationParams(ImmutableList.of(getBroadcastAddress()))
-                        .onException(Functions.<String>constant(null)))
+                        .onException(Functions.<String>constant(null))
+                        .suppressDuplicates(true))
                 .pollOperation(new JmxOperationPollConfig<String>(RACK_NAME)
                         .period(60, TimeUnit.SECONDS)
                         .objectName(snitchMBean)
                         .operationName("getRack")
                         .operationParams(ImmutableList.of(getBroadcastAddress()))
-                        .onException(Functions.<String>constant(null)))
+                        .onException(Functions.<String>constant(null))
+                        .suppressDuplicates(true))
                 .pollAttribute(new JmxAttributePollConfig<Integer>(PEERS)
                         .objectName(storageServiceMBean)
                         .attributeName("TokenToEndpointMap")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
index 346b1ee..83c9cd1 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
@@ -114,7 +114,8 @@ public class MongoDBServerImpl extends SoftwareProcessImpl implements MongoDBSer
                                     return ReplicaSetMemberStatus.fromCode(state);
                                 }
                             })
-                            .onException(Functions.constant(ReplicaSetMemberStatus.UNKNOWN)))
+                            .onException(Functions.constant(ReplicaSetMemberStatus.UNKNOWN))
+                            .suppressDuplicates(true))
                     .build();
         } else {
             setAttribute(IS_PRIMARY_FOR_REPLICA_SET, false);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index 0253f96..f03e0d8 100644
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -121,7 +121,8 @@ public class NginxControllerImpl extends AbstractControllerImpl implements Nginx
                         // Accept any nginx response (don't assert specific version), so that sub-classing
                         // for a custom nginx build is not strict about custom version numbers in headers
                         .onResult(HttpValueFunctions.containsHeader("Server"))
-                        .setOnException(false))
+                        .setOnException(false)
+                        .suppressDuplicates(true))
                 .build());
         
         // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
index 2ce83a3..932fd44 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
@@ -76,7 +76,8 @@ public class JBoss6ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
                 .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_UP)
                         .objectName(serverMbeanName)
                         .attributeName("Started")
-                        .onException(Functions.constant(false)))
+                        .onException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index 67fe955..258b6be 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -89,10 +89,12 @@ public class JBoss7ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
                 .baseUri(managementUri)
                 .credentials(getConfig(MANAGEMENT_USER), getConfig(MANAGEMENT_PASSWORD))
                 .poll(new HttpPollConfig<Integer>(MANAGEMENT_STATUS)
-                        .onSuccess(HttpValueFunctions.responseCode()))
+                        .onSuccess(HttpValueFunctions.responseCode())
+                        .suppressDuplicates(true))
                 .poll(new HttpPollConfig<Boolean>(MANAGEMENT_URL_UP)
                         .onSuccess(HttpValueFunctions.responseCodeEquals(200))
-                        .onFailureOrException(Functions.constant(false)))
+                        .onFailureOrException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .poll(new HttpPollConfig<Integer>(REQUEST_COUNT)
                         .vars(includeRuntimeUriVars)
                         .onSuccess(HttpValueFunctions.jsonContents("requestCount", Integer.class)))
@@ -123,6 +125,7 @@ public class JBoss7ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
         addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS)
             .from(MANAGEMENT_URL_UP)
             .computing(Functionals.ifNotEquals(true).value("Management URL not reachable") )
+            .suppressDuplicates(true)
             .build());
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/81650a80/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
index 2618c31..929d120 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
@@ -76,7 +76,8 @@ public class TomcatServerImpl extends JavaWebAppSoftwareProcessImpl implements T
                             .objectName(connectorMbeanName)
                             .attributeName("stateName")
                             .onSuccess(Functions.forPredicate(Predicates.<Object>equalTo("STARTED")))
-                            .setOnFailureOrException(false))
+                            .setOnFailureOrException(false)
+                            .suppressDuplicates(true))
                     .build();
 
             jmxAppFeed = JavaAppUtils.connectMXBeanSensors(this);


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

Posted by al...@apache.org.
HttpValueFunctions: not anonymous inner classes

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


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

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

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


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

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

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ee3c1ca6/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
new file mode 100644
index 0000000..7769427
--- /dev/null
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpValueFunctionsTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.event.feed.http;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.NoSuchElementException;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.util.http.HttpToolResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class HttpValueFunctionsTest {
+
+    private int responseCode = 200;
+    private long fullLatency = 1000;
+    private String headerName = "my_header";
+    private String headerVal = "my_header_val";
+    private String bodyKey = "mykey";
+    private String bodyVal = "myvalue";
+    private String body = "{"+bodyKey+":"+bodyVal+"}";
+    private long now;
+    private HttpToolResponse response;
+    
+    @BeforeMethod
+    public void setUp() throws Exception {
+        now = System.currentTimeMillis();
+        response = new HttpToolResponse(responseCode, ImmutableMap.of(headerName, ImmutableList.of(headerVal)), 
+                body.getBytes(), now-fullLatency, fullLatency / 2, fullLatency);
+    }
+    
+    @Test
+    public void testResponseCode() throws Exception {
+        assertEquals(HttpValueFunctions.responseCode().apply(response), Integer.valueOf(responseCode));
+    }
+
+    @Test
+    public void testContainsHeader() throws Exception {
+        assertTrue(HttpValueFunctions.containsHeader(headerName).apply(response));
+        assertFalse(HttpValueFunctions.containsHeader("wrong_header").apply(response));
+    }
+    
+    @Test
+    public void testStringContents() throws Exception {
+        assertEquals(HttpValueFunctions.stringContentsFunction().apply(response), body);
+    }
+
+    @Test
+    public void testJsonContents() throws Exception {
+        JsonElement json = HttpValueFunctions.jsonContents().apply(response);
+        assertTrue(json.isJsonObject());
+        assertEquals(json.getAsJsonObject().entrySet(), ImmutableMap.of(bodyKey, new JsonPrimitive(bodyVal)).entrySet());
+    }
+
+    @Test
+    public void testJsonContentsGettingElement() throws Exception {
+        assertEquals(HttpValueFunctions.jsonContents(bodyKey, String.class).apply(response), bodyVal);
+    }
+
+    @Test(expectedExceptions=NoSuchElementException.class)
+    public void testJsonContentsGettingMissingElement() throws Exception {
+        assertNull(HttpValueFunctions.jsonContents("wrongkey", String.class).apply(response));
+    }
+
+    @Test
+    public void testLatency() throws Exception {
+        assertEquals(HttpValueFunctions.latency().apply(response), Long.valueOf(fullLatency));
+    }
+}

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


[18/18] incubator-brooklyn git commit: This closes #790

Posted by al...@apache.org.
This closes #790


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

Branch: refs/heads/master
Commit: ef3af12139a3ed3361fb9fb29a5cb8c4472e40d8
Parents: 0dc3911 64a1983
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 11 21:42:32 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 21:42:32 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/AbstractEntity.java   |  24 +-
 .../java/brooklyn/entity/basic/Attributes.java  |  10 +
 .../entity/basic/ServiceStateLogic.java         |   1 +
 .../event/feed/AttributePollHandler.java        |  12 +-
 .../java/brooklyn/event/feed/FeedConfig.java    |  27 ++-
 .../event/feed/function/FunctionFeed.java       |   1 +
 .../java/brooklyn/event/feed/http/HttpFeed.java |   1 +
 .../event/feed/http/HttpValueFunctions.java     |  55 ++++-
 .../brooklyn/event/feed/shell/ShellFeed.java    |   1 +
 .../windows/WindowsPerformanceCounterFeed.java  |   1 +
 .../java/brooklyn/location/basic/Machines.java  |   4 +-
 .../internal/AbstractManagementContext.java     |   6 -
 .../internal/CollectionChangeListener.java      |   1 +
 .../internal/EntityManagementUtils.java         |   2 +-
 .../java/brooklyn/util/flags/TypeCoercions.java |  69 ++++--
 .../brooklyn/util/http/HttpToolResponse.java    |   2 +-
 .../brooklyn/entity/basic/EntitySpecTest.java   |  33 ++-
 .../brooklyn/entity/basic/EntityTypeTest.java   |   5 +-
 .../java/brooklyn/entity/group/GroupTest.java   |  58 +++--
 .../event/feed/http/HttpValueFunctionsTest.java |  94 ++++++++
 .../util/internal/TypeCoercionsTest.java        |   5 +
 .../basic/RecordingSensorEventListener.java     |   2 +-
 .../demo/WebClusterDatabaseExampleGroovy.groovy |   2 +-
 .../location/jclouds/JcloudsLocation.java       |  63 +++++
 .../jclouds/JcloudsSshMachineLocation.java      |  10 +-
 .../jclouds/JcloudsAddressesLiveTest.java       | 228 +++++++++++++++++++
 .../postgresql/PostgreSqlNodeSaltImpl.java      |   6 +-
 .../entity/monitoring/zabbix/ZabbixFeed.java    |   1 +
 .../hazelcast/HazelcastClusterEc2LiveTest.java  |   2 +-
 .../HazelcastClusterSoftlayerLiveTest.java      |   2 +-
 .../Infinispan5ServerIntegrationTest.groovy     |   2 +-
 .../entity/basic/SameServerEntityImpl.java      |   8 +-
 .../brooklyn/entity/basic/SoftwareProcess.java  |  12 +
 .../entity/basic/SoftwareProcessImpl.java       |  65 ++++++
 .../entity/brooklynnode/BrooklynNodeImpl.java   |   4 +-
 .../brooklyn/entity/chef/ChefAttributeFeed.java |   1 +
 .../brooklyn/entity/chef/ChefEntityImpl.java    |   8 +-
 .../java/brooklyn/event/feed/jmx/JmxFeed.java   |   3 +
 .../entity/brooklynnode/MockBrooklynNode.java   |   4 +
 .../brooklynnode/SameBrooklynNodeImpl.java      |   4 +
 .../entity/database/mysql/MySqlNodeImpl.java    |   8 +-
 .../PostgreSqlNodeChefImplFromScratch.java      |   4 +
 .../messaging/activemq/ActiveMQBrokerImpl.java  |   3 +-
 .../entity/messaging/kafka/KafkaBrokerImpl.java |  27 ++-
 .../entity/messaging/qpid/QpidBrokerImpl.java   |   3 +-
 .../nosql/cassandra/CassandraNodeImpl.java      |  39 ++--
 .../entity/nosql/couchdb/CouchDBNodeImpl.java   |  23 +-
 .../entity/nosql/mongodb/MongoDBServerImpl.java |   3 +-
 .../entity/nosql/redis/RedisStoreImpl.java      |  24 +-
 .../dns/geoscaling/GeoscalingDnsService.java    |   6 +
 .../geoscaling/GeoscalingDnsServiceImpl.java    |  10 +-
 .../dns/geoscaling/GeoscalingWebClient.java     |   4 +-
 .../entity/proxy/nginx/NginxControllerImpl.java |  26 ++-
 .../webapp/ControlledDynamicWebAppCluster.java  |   5 +
 .../ControlledDynamicWebAppClusterImpl.java     |  18 +-
 .../entity/webapp/jboss/JBoss6ServerImpl.java   |  26 ++-
 .../entity/webapp/jboss/JBoss7ServerImpl.java   |  28 ++-
 .../entity/webapp/tomcat/TomcatServerImpl.java  |  30 ++-
 .../ControlledDynamicWebAppClusterTest.java     |  24 ++
 ...ableRetrieveUsageMetricsIntegrationTest.java |  65 ++++++
 .../test/entity/TestJavaWebAppEntity.java       |   3 +-
 .../camp/brooklyn/ApplicationsYamlTest.java     | 116 ++++++++++
 .../brooklyn/catalog/CatalogYamlAppTest.java    |  73 ++++++
 .../camp/brooklyn/EntitiesYamlTest.java         |  38 ----
 64 files changed, 1240 insertions(+), 205 deletions(-)
----------------------------------------------------------------------



[14/18] incubator-brooklyn git commit: Adds GeoscalingDnsService.SSL_TRUST_ALL

Posted by al...@apache.org.
Adds GeoscalingDnsService.SSL_TRUST_ALL


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

Branch: refs/heads/master
Commit: 4549e281e8a00e0bf3da08421c115be77fb6b019
Parents: b9e81ed
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:23:02 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:31 2015 +0100

----------------------------------------------------------------------
 .../entity/dns/geoscaling/GeoscalingDnsService.java       |  6 ++++++
 .../entity/dns/geoscaling/GeoscalingDnsServiceImpl.java   | 10 +++++++++-
 .../entity/dns/geoscaling/GeoscalingWebClient.java        |  4 ++--
 3 files changed, 17 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4549e281/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
index c07b4cc..896d757 100644
--- a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
+++ b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
@@ -22,6 +22,7 @@ import java.net.URI;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.dns.AbstractGeoDnsService;
 import brooklyn.entity.proxying.ImplementedBy;
 import brooklyn.entity.webapp.WebAppServiceConstants;
@@ -33,6 +34,11 @@ import brooklyn.util.flags.SetFromFlag;
 @ImplementedBy(GeoscalingDnsServiceImpl.class)
 public interface GeoscalingDnsService extends AbstractGeoDnsService {
     
+    @SetFromFlag("sslTrustAll")
+    public static final ConfigKey<Boolean> SSL_TRUST_ALL = ConfigKeys.newBooleanConfigKey(
+            "ssl.trustAll",
+            "Whether to trust all certificates, or to fail with 'peer not authenticated' if untrusted (default false)",
+            false);
     @SetFromFlag("randomizeSubdomainName")
     public static final ConfigKey<Boolean> RANDOMIZE_SUBDOMAIN_NAME = new BasicConfigKey<Boolean>(
             Boolean.class, "randomize.subdomain.name");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4549e281/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
index 28d41b2..c172680 100644
--- a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
@@ -35,6 +35,7 @@ import brooklyn.entity.dns.geoscaling.GeoscalingWebClient.Domain;
 import brooklyn.entity.dns.geoscaling.GeoscalingWebClient.SmartSubdomain;
 import brooklyn.location.geo.HostGeoInfo;
 import brooklyn.util.collections.MutableSet;
+import brooklyn.util.http.HttpTool;
 import brooklyn.util.text.Identifiers;
 import brooklyn.util.text.Strings;
 
@@ -44,7 +45,7 @@ public class GeoscalingDnsServiceImpl extends AbstractGeoDnsServiceImpl implemen
 
     // Must remember any desired redirection targets if they're specified before configure() has been called.
     private Set<HostGeoInfo> rememberedTargetHosts;
-    private final GeoscalingWebClient webClient = new GeoscalingWebClient();
+    private GeoscalingWebClient webClient;
     
     // These are available only after the configure() method has been invoked.
     private boolean randomizeSmartSubdomainName;
@@ -62,6 +63,13 @@ public class GeoscalingDnsServiceImpl extends AbstractGeoDnsServiceImpl implemen
         
         // defaulting to randomized subdomains makes deploying multiple applications easier
         if (getConfig(RANDOMIZE_SUBDOMAIN_NAME)==null) setConfig(RANDOMIZE_SUBDOMAIN_NAME, true); 
+        
+        Boolean trustAll = getConfig(SSL_TRUST_ALL);
+        if (Boolean.TRUE.equals(trustAll)) {
+            webClient = new GeoscalingWebClient(HttpTool.httpClientBuilder().trustAll().build());
+        } else {
+            webClient = new GeoscalingWebClient();
+        }
     }
     
     // Ensure our configure() method gets called; may be able to remove this if/when the framework detects this

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4549e281/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
index 7ce10cc..c712b6a 100644
--- a/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
+++ b/software/webapp/src/main/java/brooklyn/entity/dns/geoscaling/GeoscalingWebClient.java
@@ -38,7 +38,6 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.util.EntityUtils;
 import org.slf4j.Logger;
@@ -49,6 +48,7 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.tidy.Tidy;
 
+import brooklyn.util.http.HttpTool;
 import brooklyn.util.text.Strings;
 
 /**
@@ -176,7 +176,7 @@ public class GeoscalingWebClient {
     
     
     public GeoscalingWebClient() {
-        this(new DefaultHttpClient());
+        this(HttpTool.httpClientBuilder().build());
     }
 
     public GeoscalingWebClient(HttpClient httpClient) {


[09/18] incubator-brooklyn git commit: Adds ControlledDynamicWebAppCluster.CONTROLLED_GROUP

Posted by al...@apache.org.
Adds ControlledDynamicWebAppCluster.CONTROLLED_GROUP


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

Branch: refs/heads/master
Commit: 70dfb20d2c88f82061efca1b8e2bc9349ee170bb
Parents: f2e3291
Author: Aled Sage <al...@gmail.com>
Authored: Mon May 25 22:25:30 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:29 2015 +0100

----------------------------------------------------------------------
 .../webapp/ControlledDynamicWebAppCluster.java  |  5 ++++
 .../ControlledDynamicWebAppClusterImpl.java     | 18 ++++++++++++++-
 .../ControlledDynamicWebAppClusterTest.java     | 24 ++++++++++++++++++++
 .../test/entity/TestJavaWebAppEntity.java       |  3 ++-
 4 files changed, 48 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/70dfb20d/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
index c747efe..7da9e11 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
@@ -69,6 +69,10 @@ public interface ControlledDynamicWebAppCluster extends DynamicGroup, Entity, St
     public static BasicAttributeSensorAndConfigKey<LoadBalancer> CONTROLLER = new BasicAttributeSensorAndConfigKey<LoadBalancer>(
         LoadBalancer.class, "controlleddynamicwebappcluster.controller", "Controller for the cluster; if null a default will created (using controllerSpec)");
 
+    @SetFromFlag("controlledGroup")
+    public static BasicAttributeSensorAndConfigKey<Group> CONTROLLED_GROUP = new BasicAttributeSensorAndConfigKey<Group>(
+        Group.class, "controlleddynamicwebappcluster.controlledgroup", "The group of web servers that the controller should point at; if null, will use the CLUSTER");
+
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @SetFromFlag("controllerSpec")
     public static BasicAttributeSensorAndConfigKey<EntitySpec<? extends LoadBalancer>> CONTROLLER_SPEC = new BasicAttributeSensorAndConfigKey(
@@ -105,4 +109,5 @@ public interface ControlledDynamicWebAppCluster extends DynamicGroup, Entity, St
     
     public DynamicWebAppCluster getCluster();
     
+    public Group getControlledGroup();
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/70dfb20d/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
index 9a4c212..d02d292 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
@@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.enricher.Enrichers;
 import brooklyn.entity.Entity;
+import brooklyn.entity.Group;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.ConfigurableEntityFactory;
 import brooklyn.entity.basic.DynamicGroupImpl;
@@ -83,6 +84,7 @@ public class ControlledDynamicWebAppClusterImpl extends DynamicGroupImpl impleme
         ConfigToAttributes.apply(this, CONTROLLER);
         ConfigToAttributes.apply(this, CONTROLLER_SPEC);
         ConfigToAttributes.apply(this, WEB_CLUSTER_SPEC);
+        ConfigToAttributes.apply(this, CONTROLLED_GROUP);
         
         ConfigurableEntityFactory<? extends WebAppService> webServerFactory = getAttribute(FACTORY);
         EntitySpec<? extends WebAppService> webServerSpec = getAttribute(MEMBER_SPEC);
@@ -136,6 +138,15 @@ public class ControlledDynamicWebAppClusterImpl extends DynamicGroupImpl impleme
             setAttribute(CONTROLLER, controller);
         }
         
+        Group controlledGroup = getAttribute(CONTROLLED_GROUP);
+        if (controlledGroup == null) {
+            log.debug("using cluster as controlledGroup for {}", this);
+            controlledGroup = cluster;
+            setAttribute(CONTROLLED_GROUP, cluster);
+        } else {
+            log.debug("using custom controlledGroup {} for {}", controlledGroup, this);
+        }
+        
         doBind();
     }
 
@@ -183,6 +194,11 @@ public class ControlledDynamicWebAppClusterImpl extends DynamicGroupImpl impleme
     }
     
     @Override
+    public Group getControlledGroup() {
+        return getAttribute(CONTROLLED_GROUP);
+    }
+    
+    @Override
     public void start(Collection<? extends Location> locations) {
         ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
 
@@ -195,7 +211,7 @@ public class ControlledDynamicWebAppClusterImpl extends DynamicGroupImpl impleme
             addLocations(locations);
 
             LoadBalancer loadBalancer = getController();
-            loadBalancer.bind(MutableMap.of("serverPool", getCluster()));
+            loadBalancer.bind(MutableMap.of("serverPool", getControlledGroup()));
 
             List<Entity> childrenToStart = MutableList.<Entity>of(getCluster());
             // Set controller as child of cluster, if it does not already have a parent

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/70dfb20d/software/webapp/src/test/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java b/software/webapp/src/test/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
index e98d094..d841f1b 100644
--- a/software/webapp/src/test/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
+++ b/software/webapp/src/test/java/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
@@ -30,6 +30,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.entity.Group;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcess;
@@ -43,6 +46,7 @@ import brooklyn.test.Asserts;
 import brooklyn.test.entity.TestJavaWebAppEntity;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 
 public class ControlledDynamicWebAppClusterTest extends BrooklynAppUnitTestSupport {
@@ -83,6 +87,26 @@ public class ControlledDynamicWebAppClusterTest extends BrooklynAppUnitTestSuppo
     }
     
     @Test
+    public void testUsesCustomControlledGroup() {
+        TestJavaWebAppEntity webServer = app.createAndManageChild(EntitySpec.create(TestJavaWebAppEntity.class));
+        webServer.setAttribute(Attributes.SUBNET_HOSTNAME, "myhostname");
+        webServer.setAttribute(Attributes.HTTP_PORT, 1234);
+        
+        TrackingAbstractController controller = app.createAndManageChild(EntitySpec.create(TrackingAbstractController.class));
+        Group controlledGroup = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+        controlledGroup.addMember(webServer);
+        
+        ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
+                .configure("initialSize", 0)
+                .configure(ControlledDynamicWebAppCluster.CONTROLLER, controller)
+                .configure(ControlledDynamicWebAppCluster.CONTROLLED_GROUP, controlledGroup)
+                .configure("memberSpec", EntitySpec.create(JBoss7Server.class).configure("war", getTestWar())));
+        app.start(locs);
+
+        assertEquals(controller.getUpdates(), ImmutableList.of(ImmutableSet.of("myhostname:1234")));
+    }
+    
+    @Test
     public void testUsesCustomControllerSpec() {
         EntitySpec<TrackingAbstractController> controllerSpec = EntitySpec.create(TrackingAbstractController.class).displayName("mycustom");
         ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/70dfb20d/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
index 3fa4015..a13ac9d 100644
--- a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
+++ b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
@@ -28,6 +28,7 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcessDriverLifecycleEffectorTasks;
+import brooklyn.entity.basic.EntityLocal;
 import brooklyn.entity.java.VanillaJavaApp;
 import brooklyn.entity.proxying.ImplementedBy;
 import brooklyn.entity.webapp.WebAppService;
@@ -38,7 +39,7 @@ import brooklyn.util.config.ConfigBag;
  * Mock web application server entity for testing.
  */
 @ImplementedBy(TestJavaWebAppEntityImpl.class)
-public interface TestJavaWebAppEntity extends VanillaJavaApp, WebAppService {
+public interface TestJavaWebAppEntity extends VanillaJavaApp, WebAppService, EntityLocal {
 
     /**
      * Injects the test entity's customised lifecycle tasks.


[17/18] incubator-brooklyn git commit: Fix imports to org.apache.brooklyn

Posted by al...@apache.org.
Fix imports to org.apache.brooklyn

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

Branch: refs/heads/master
Commit: 64a19837b8c953f8ef5f8efad68f23ffd1ed4388
Parents: 36fb5e9
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 11 17:16:30 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:33 2015 +0100

----------------------------------------------------------------------
 .../apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy    | 2 +-
 .../entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java        | 2 +-
 .../entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java  | 2 +-
 .../nosql/infinispan/Infinispan5ServerIntegrationTest.groovy       | 2 +-
 .../TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java    | 2 +-
 .../test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java  | 1 +
 .../java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java | 2 +-
 7 files changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
index d40fcc5..bcd4903 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
@@ -22,6 +22,7 @@ import static brooklyn.entity.java.JavaEntityMethods.javaSysProp
 import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady
 import static brooklyn.event.basic.DependentConfiguration.formatString
 
+import org.apache.brooklyn.launcher.BrooklynLauncher
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 
@@ -31,7 +32,6 @@ import brooklyn.entity.database.mysql.MySqlNode
 import brooklyn.entity.proxying.EntitySpec
 import brooklyn.entity.webapp.ControlledDynamicWebAppCluster
 import brooklyn.entity.webapp.DynamicWebAppCluster
-import brooklyn.launcher.BrooklynLauncher
 import brooklyn.policy.autoscaling.AutoScalerPolicy
 import brooklyn.util.CommandLineUtil
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java
index 552ad02..0afb49b 100644
--- a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java
+++ b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterEc2LiveTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.entity.nosql.hazelcast;
 
 import org.apache.brooklyn.entity.nosql.hazelcast.HazelcastCluster;
 import org.apache.brooklyn.entity.nosql.hazelcast.HazelcastNode;
+import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
@@ -28,7 +29,6 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.Location;
-import brooklyn.test.EntityTestUtils;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java
index 03d95af..7e05c74 100644
--- a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java
+++ b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastClusterSoftlayerLiveTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.entity.nosql.hazelcast;
 
 import org.apache.brooklyn.entity.nosql.hazelcast.HazelcastCluster;
 import org.apache.brooklyn.entity.nosql.hazelcast.HazelcastNode;
+import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
@@ -28,7 +29,6 @@ import brooklyn.entity.AbstractSoftlayerLiveTest;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.Location;
-import brooklyn.test.EntityTestUtils;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
index b7d8d1a..1287e2a 100644
--- a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
+++ b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.entity.nosql.infinispan
 
-import static brooklyn.test.TestUtils.*
+import static org.apache.brooklyn.test.TestUtils.*
 import static java.util.concurrent.TimeUnit.*
 import static org.testng.Assert.*
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
index 0761af6..ed300c4 100644
--- a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
+++ b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity.webapp.tomcat;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 
+import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
@@ -28,7 +29,6 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
-import brooklyn.test.EntityTestUtils;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
index 3f860d6..1bd904d 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
@@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64a19837/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
index 48ecb42..3a24b51 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
@@ -20,7 +20,7 @@ package io.brooklyn.camp.brooklyn.catalog;
 
 import org.testng.annotations.Test;
 
-import io.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 
 
 public class CatalogYamlAppTest extends AbstractYamlTest {


[08/18] incubator-brooklyn git commit: Tidy Machines.java logging

Posted by al...@apache.org.
Tidy Machines.java logging


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

Branch: refs/heads/master
Commit: 92063d902eb09a54f7e5e0cc095249e684156b05
Parents: 0c52d9c
Author: Aled Sage <al...@gmail.com>
Authored: Fri May 1 20:17:04 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:28 2015 +0100

----------------------------------------------------------------------
 core/src/main/java/brooklyn/location/basic/Machines.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/92063d90/core/src/main/java/brooklyn/location/basic/Machines.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/Machines.java b/core/src/main/java/brooklyn/location/basic/Machines.java
index 7c143a8..38e99d9 100644
--- a/core/src/main/java/brooklyn/location/basic/Machines.java
+++ b/core/src/main/java/brooklyn/location/basic/Machines.java
@@ -51,7 +51,7 @@ public class Machines {
             InetAddress addr = ((MachineLocation) where).getAddress();
             if (addr != null) hostname = addr.getHostAddress();
         }
-        log.debug("computed hostname {} for {}", hostname, where);
+        log.debug("computed subnet hostname {} for {}", hostname, where);
         // TODO if Maybe.absent(message) appears, could/should use that
         // TODO If no machine available, should we throw new IllegalStateException("Cannot find hostname for "+where);
         return Maybe.fromNullable(hostname);
@@ -73,7 +73,7 @@ public class Machines {
             InetAddress addr = ((MachineLocation) where).getAddress();
             if (addr != null) result = addr.getHostAddress();
         }
-        log.debug("computed hostname {} for {}", result, where);
+        log.debug("computed subnet host ip {} for {}", result, where);
         return Maybe.fromNullable(result);
     }
 


[12/18] incubator-brooklyn git commit: Fix EntityManagementUtils.hasNoNameOrCustomKeysOrRoot

Posted by al...@apache.org.
Fix EntityManagementUtils.hasNoNameOrCustomKeysOrRoot


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

Branch: refs/heads/master
Commit: 23543fa3c61f396ecac7609987592e8043505d2f
Parents: 0d9372b
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:17:43 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:30 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/management/internal/EntityManagementUtils.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/23543fa3/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
index 046d56c..07ab79a 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
@@ -287,7 +287,7 @@ public class EntityManagementUtils {
     /** worker method to help determine whether child/children can be promoted */
     @Beta //where should this live long-term?
     public static boolean hasNoNameOrCustomKeysOrRoot(AssemblyTemplate template, EntitySpec<?> spec) {
-        if (!Strings.isEmpty(template.getName())) {
+        if (Strings.isNonEmpty(template.getName())) {
             if (spec.getChildren().size()==1) {
                 String childName = Iterables.getOnlyElement(spec.getChildren()).getDisplayName();
                 if (Strings.isEmpty(childName) || childName.equals(template.getName())) {


[05/18] incubator-brooklyn git commit: Adds SoftwareProcess.RETRIEVE_USAGE_METRICS

Posted by al...@apache.org.
Adds SoftwareProcess.RETRIEVE_USAGE_METRICS

- RETRIEVE_USAGE_METRICS defaults to true
- Setting RETRIEVE_USAGE_METRICS to false will disable the automatic
  retrieval of performance/usage metrics in some entity types.
- Adds FeedConfig.enabled as an easy way to programmatically
  prevent a feed from being enabled (which can be easier to program
  against than guarding its creation with an if statement).
- Adds TomcatServerDisableRetrieveUsageMetricsIntegrationTest


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

Branch: refs/heads/master
Commit: b416623040397d9129953bf4b95db07dea0a1546
Parents: ce0c422
Author: Aled Sage <al...@gmail.com>
Authored: Sat Apr 18 14:40:33 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 17:51:35 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/event/feed/FeedConfig.java    | 14 +++++
 .../event/feed/function/FunctionFeed.java       |  1 +
 .../java/brooklyn/event/feed/http/HttpFeed.java |  1 +
 .../brooklyn/event/feed/shell/ShellFeed.java    |  1 +
 .../windows/WindowsPerformanceCounterFeed.java  |  1 +
 .../internal/AbstractManagementContext.java     |  6 --
 .../internal/CollectionChangeListener.java      |  1 +
 .../entity/monitoring/zabbix/ZabbixFeed.java    |  1 +
 .../brooklyn/entity/basic/SoftwareProcess.java  |  5 ++
 .../brooklyn/entity/chef/ChefAttributeFeed.java |  1 +
 .../java/brooklyn/event/feed/jmx/JmxFeed.java   |  3 +
 .../entity/database/mysql/MySqlNodeImpl.java    |  5 +-
 .../entity/messaging/kafka/KafkaBrokerImpl.java | 27 +++++---
 .../entity/messaging/qpid/QpidBrokerImpl.java   |  3 +-
 .../nosql/cassandra/CassandraNodeImpl.java      | 24 +++++---
 .../entity/nosql/couchdb/CouchDBNodeImpl.java   | 23 ++++---
 .../entity/nosql/redis/RedisStoreImpl.java      | 24 +++++---
 .../entity/webapp/jboss/JBoss6ServerImpl.java   | 27 +++++---
 .../entity/webapp/jboss/JBoss7ServerImpl.java   | 19 ++++--
 .../entity/webapp/tomcat/TomcatServerImpl.java  | 31 ++++++----
 ...ableRetrieveUsageMetricsIntegrationTest.java | 65 ++++++++++++++++++++
 21 files changed, 213 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/event/feed/FeedConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/FeedConfig.java b/core/src/main/java/brooklyn/event/feed/FeedConfig.java
index 6796730..f51050f 100644
--- a/core/src/main/java/brooklyn/event/feed/FeedConfig.java
+++ b/core/src/main/java/brooklyn/event/feed/FeedConfig.java
@@ -63,6 +63,7 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
     private Function<? super Exception, T> onexception;
     private Predicate<? super V> checkSuccess;
     private boolean suppressDuplicates;
+    private boolean enabled = true;
     
     public FeedConfig(AttributeSensor<T> sensor) {
         this.sensor = checkNotNull(sensor, "sensor");
@@ -75,6 +76,7 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         this.onexception = other.onexception;
         this.checkSuccess = other.checkSuccess;
         this.suppressDuplicates = other.suppressDuplicates;
+        this.enabled = other.enabled;
     }
 
     @SuppressWarnings("unchecked")
@@ -106,6 +108,10 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         return suppressDuplicates;
     }
     
+    public boolean isEnabled() {
+        return enabled;
+    }
+    
     /** sets the predicate used to check whether a feed run is successful */
     public F checkSuccess(Predicate<? super V> val) {
         this.checkSuccess = checkNotNull(val, "checkSuccess");
@@ -186,6 +192,14 @@ public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
         return self();
     }
     
+    /**
+     * Whether this feed is enabled (defaulting to true).
+     */
+    public F enabled(boolean val) {
+        enabled = val;
+        return self();
+    }
+    
     public boolean hasSuccessHandler() {
         return this.onsuccess != null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/event/feed/function/FunctionFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/function/FunctionFeed.java b/core/src/main/java/brooklyn/event/feed/function/FunctionFeed.java
index 6acf408..9f96f24 100644
--- a/core/src/main/java/brooklyn/event/feed/function/FunctionFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/function/FunctionFeed.java
@@ -175,6 +175,7 @@ public class FunctionFeed extends AbstractFeed {
         
         SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>> polls = HashMultimap.<FunctionPollIdentifier,FunctionPollConfig<?,?>>create();
         for (FunctionPollConfig<?,?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "rawtypes", "unchecked" })
             FunctionPollConfig<?,?> configCopy = new FunctionPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java b/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
index ab9dcd1..5131a4b 100644
--- a/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/http/HttpFeed.java
@@ -279,6 +279,7 @@ public class HttpFeed extends AbstractFeed {
         
         SetMultimap<HttpPollIdentifier, HttpPollConfig<?>> polls = HashMultimap.<HttpPollIdentifier,HttpPollConfig<?>>create();
         for (HttpPollConfig<?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "unchecked", "rawtypes" })
             HttpPollConfig<?> configCopy = new HttpPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/event/feed/shell/ShellFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/shell/ShellFeed.java b/core/src/main/java/brooklyn/event/feed/shell/ShellFeed.java
index f92ec07..f325a2d 100644
--- a/core/src/main/java/brooklyn/event/feed/shell/ShellFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/shell/ShellFeed.java
@@ -196,6 +196,7 @@ public class ShellFeed extends AbstractFeed {
 
         SetMultimap<ShellPollIdentifier, ShellPollConfig<?>> polls = HashMultimap.<ShellPollIdentifier,ShellPollConfig<?>>create();
         for (ShellPollConfig<?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "unchecked", "rawtypes" })
             ShellPollConfig<?> configCopy = new ShellPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
index 5278ff9..99eec78 100644
--- a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
@@ -169,6 +169,7 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
     protected WindowsPerformanceCounterFeed(Builder builder) {
         List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
         for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "unchecked", "rawtypes" })
             WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index e296ddf..3cd64da 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -340,12 +340,6 @@ public abstract class AbstractManagementContext implements ManagementContextInte
     protected abstract <T> Task<T> runAtEntity(final Entity entity, final Effector<T> eff, @SuppressWarnings("rawtypes") final Map parameters);
 
     @Override
-    public abstract void addEntitySetListener(CollectionChangeListener<Entity> listener);
-
-    @Override
-    public abstract void removeEntitySetListener(CollectionChangeListener<Entity> listener);
-    
-    @Override
     public StringConfigMap getConfig() {
         return configMap;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/core/src/main/java/brooklyn/management/internal/CollectionChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/CollectionChangeListener.java b/core/src/main/java/brooklyn/management/internal/CollectionChangeListener.java
index c4cb8be..654debc 100644
--- a/core/src/main/java/brooklyn/management/internal/CollectionChangeListener.java
+++ b/core/src/main/java/brooklyn/management/internal/CollectionChangeListener.java
@@ -17,6 +17,7 @@
  * under the License.
  */
 package brooklyn.management.internal;
+
 public interface CollectionChangeListener<Item> {
     void onItemAdded(Item item);
     void onItemRemoved(Item item);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
index 08fba87..4347543 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
@@ -305,6 +305,7 @@ public class ZabbixFeed extends AbstractFeed {
 
         Set<ZabbixPollConfig<?>> polls = Sets.newLinkedHashSet();
         for (ZabbixPollConfig<?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "unchecked", "rawtypes" })
             ZabbixPollConfig<?> configCopy = new ZabbixPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index 5144a2b..05852d0 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -239,6 +239,11 @@ public interface SoftwareProcess extends Entity, Startable {
             "softwareProcess.lifecycleTasks", "An object that handles lifecycle of an entity's associated machine.",
             new SoftwareProcessDriverLifecycleEffectorTasks());
 
+    ConfigKey<Boolean> RETRIEVE_USAGE_METRICS = ConfigKeys.newBooleanConfigKey(
+            "metrics.usage.retrieve",
+            "Whether to retrieve the usage (e.g. performance) metrics",
+            true);
+
     /** Controls the behavior when starting (stop, restart) {@link Startable} children as part of the start (stop, restart) effector on this entity
      * <p>
      * (NB: restarts are currently not propagated to children in the default {@link SoftwareProcess}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/base/src/main/java/brooklyn/entity/chef/ChefAttributeFeed.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefAttributeFeed.java b/software/base/src/main/java/brooklyn/entity/chef/ChefAttributeFeed.java
index d55845e..4cf7a95 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefAttributeFeed.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefAttributeFeed.java
@@ -199,6 +199,7 @@ public class ChefAttributeFeed extends AbstractFeed {
 
         Set<ChefAttributePollConfig<?>> polls = Sets.newLinkedHashSet();
         for (ChefAttributePollConfig<?> config : builder.polls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "unchecked", "rawtypes" })
             ChefAttributePollConfig<?> configCopy = new ChefAttributePollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/base/src/main/java/brooklyn/event/feed/jmx/JmxFeed.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/event/feed/jmx/JmxFeed.java b/software/base/src/main/java/brooklyn/event/feed/jmx/JmxFeed.java
index de0a553..00bb017 100644
--- a/software/base/src/main/java/brooklyn/event/feed/jmx/JmxFeed.java
+++ b/software/base/src/main/java/brooklyn/event/feed/jmx/JmxFeed.java
@@ -198,6 +198,7 @@ public class JmxFeed extends AbstractFeed {
         
         SetMultimap<String, JmxAttributePollConfig<?>> attributePolls = HashMultimap.<String,JmxAttributePollConfig<?>>create();
         for (JmxAttributePollConfig<?> config : builder.attributePolls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "rawtypes", "unchecked" })
             JmxAttributePollConfig<?> configCopy = new JmxAttributePollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
@@ -207,6 +208,7 @@ public class JmxFeed extends AbstractFeed {
         
         SetMultimap<List<?>, JmxOperationPollConfig<?>> operationPolls = HashMultimap.<List<?>,JmxOperationPollConfig<?>>create();
         for (JmxOperationPollConfig<?> config : builder.operationPolls) {
+            if (!config.isEnabled()) continue;
             @SuppressWarnings({ "rawtypes", "unchecked" })
             JmxOperationPollConfig<?> configCopy = new JmxOperationPollConfig(config);
             if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
@@ -216,6 +218,7 @@ public class JmxFeed extends AbstractFeed {
         
         SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = HashMultimap.create();
         for (JmxNotificationSubscriptionConfig<?> config : builder.notificationSubscriptions) {
+            if (!config.isEnabled()) continue;
             notificationSubscriptions.put(config.getNotificationFilter(), config);
         }
         setConfig(NOTIFICATION_SUBSCRIPTIONS, notificationSubscriptions);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index 8346fbb..892f552 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -93,6 +93,8 @@ public class MySqlNodeImpl extends SoftwareProcessImpl implements MySqlNode {
          * So can extract lots of sensors from that.
          */
         Maybe<SshMachineLocation> machine = Locations.findUniqueSshMachineLocation(getLocations());
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+
         if (machine.isPresent()) {
             String cmd = getDriver().getStatusCmd();
             feed = SshFeed.builder()
@@ -108,7 +110,8 @@ public class MySqlNodeImpl extends SoftwareProcessImpl implements MySqlNode {
                                     if (q==null) return null;
                                     return Double.parseDouble(q);
                                 }})
-                            .setOnFailureOrException(null) )
+                            .setOnFailureOrException(null)
+                            .enabled(retrieveUsageMetrics))
                     .poll(new SshPollConfig<Boolean>(SERVICE_PROCESS_IS_RUNNING)
                             .command(cmd)
                             .setOnSuccess(true)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
index d6aadd1..1354d6f 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
@@ -91,7 +91,8 @@ public class KafkaBrokerImpl extends SoftwareProcessImpl implements MessageBroke
     @Override
     protected void connectSensors() {
         connectServiceUpIsRunning();
-
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+        
         if (((KafkaBrokerDriver)getDriver()).isJmxEnabled()) {
             jmxFeed = JmxFeed.builder()
                 .entity(this)
@@ -99,35 +100,43 @@ public class KafkaBrokerImpl extends SoftwareProcessImpl implements MessageBroke
                 .pollAttribute(new JmxAttributePollConfig<Long>(FETCH_REQUEST_COUNT)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("NumFetchRequests")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(TOTAL_FETCH_TIME)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("TotalFetchRequestMs")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Double>(MAX_FETCH_TIME)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("MaxFetchRequestMs")
-                        .onException(Functions.constant(-1.0d)))
+                        .onException(Functions.constant(-1.0d))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(PRODUCE_REQUEST_COUNT)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("NumProduceRequests")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(TOTAL_PRODUCE_TIME)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("TotalProduceRequestMs")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Double>(MAX_PRODUCE_TIME)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("MaxProduceRequestMs")
-                        .onException(Functions.constant(-1.0d)))
+                        .onException(Functions.constant(-1.0d))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(BYTES_RECEIVED)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("TotalBytesRead")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(BYTES_SENT)
                         .objectName(SOCKET_SERVER_STATS_MBEAN)
                         .attributeName("TotalBytesWritten")
-                        .onException(Functions.constant(-1l)))
+                        .onException(Functions.constant(-1l))
+                        .enabled(retrieveUsageMetrics))
                 .build();
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java b/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
index 9ccbec1..d67ce95 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
@@ -129,7 +129,8 @@ public class QpidBrokerImpl extends JMSBrokerImpl<QpidQueue, QpidTopic> implemen
                                     }
                                     return true;
                                 }})
-                        .onException(Functions.constant(false)))
+                        .onException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index c9923ef..dedf875 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -406,6 +406,8 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
         super.connectSensors();
 
         jmxHelper = new JmxHelper(this);
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+        
         jmxFeed = JmxFeed.builder()
                 .entity(this)
                 .period(3000, TimeUnit.MILLISECONDS)
@@ -493,27 +495,33 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
                 .pollAttribute(new JmxAttributePollConfig<Integer>(READ_ACTIVE)
                         .objectName(readStageMBean)
                         .attributeName("ActiveCount")
-                        .onException(Functions.constant((Integer)null)))
+                        .onException(Functions.constant((Integer)null))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(READ_PENDING)
                         .objectName(readStageMBean)
                         .attributeName("PendingTasks")
-                        .onException(Functions.constant((Long)null)))
+                        .onException(Functions.constant((Long)null))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(READ_COMPLETED)
                         .objectName(readStageMBean)
                         .attributeName("CompletedTasks")
-                        .onException(Functions.constant((Long)null)))
+                        .onException(Functions.constant((Long)null))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Integer>(WRITE_ACTIVE)
                         .objectName(mutationStageMBean)
                         .attributeName("ActiveCount")
-                        .onException(Functions.constant((Integer)null)))
+                        .onException(Functions.constant((Integer)null))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(WRITE_PENDING)
                         .objectName(mutationStageMBean)
                         .attributeName("PendingTasks")
-                        .onException(Functions.constant((Long)null)))
+                        .onException(Functions.constant((Long)null))
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Long>(WRITE_COMPLETED)
                         .objectName(mutationStageMBean)
                         .attributeName("CompletedTasks")
-                        .onException(Functions.constant((Long)null)))
+                        .onException(Functions.constant((Long)null))
+                        .enabled(retrieveUsageMetrics))
                 .build();
         
         functionFeed = FunctionFeed.builder()
@@ -543,8 +551,8 @@ public class CassandraNodeImpl extends SoftwareProcessImpl implements CassandraN
                                 setAttribute(SERVICE_UP,
                                         getAttribute(THRIFT_PORT_LATENCY)!=null && getAttribute(THRIFT_PORT_LATENCY)>=0 && 
                                         Boolean.TRUE.equals(getAttribute(SERVICE_UP_JMX)));
-                            }
-                        }))
+                            }})
+                        .enabled(retrieveUsageMetrics))
                 .build();
         
         jmxMxBeanFeed = JavaAppUtils.connectMXBeanSensors(this);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
index 298b6b6..2f5bd36 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
@@ -31,6 +31,8 @@ import brooklyn.entity.webapp.WebAppServiceMethods;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.Functionals;
 
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
@@ -62,27 +64,28 @@ public class CouchDBNodeImpl extends SoftwareProcessImpl implements CouchDBNode
 
         connectServiceUpIsRunning();
 
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+        
         httpFeed = HttpFeed.builder()
                 .entity(this)
                 .period(500, TimeUnit.MILLISECONDS)
                 .baseUri(String.format("http://%s:%d/_stats", getAttribute(HOSTNAME), getHttpPort()))
                 .poll(new HttpPollConfig<Integer>(REQUEST_COUNT)
                         .onSuccess(HttpValueFunctions.jsonContents(new String[] { "httpd", "requests", "count" }, Integer.class))
-                        .onFailureOrException(Functions.constant(-1)))
+                        .onFailureOrException(Functions.constant(-1))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(ERROR_COUNT)
                         .onSuccess(HttpValueFunctions.jsonContents(new String[] { "httpd_status_codes", "404", "count" }, Integer.class))
-                        .onFailureOrException(Functions.constant(-1)))
+                        .onFailureOrException(Functions.constant(-1))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(TOTAL_PROCESSING_TIME)
                         .onSuccess(HttpValueFunctions.jsonContents(new String[] { "couchdb", "request_time", "count" }, Integer.class))
-                        .onFailureOrException(Functions.constant(-1)))
+                        .onFailureOrException(Functions.constant(-1))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(MAX_PROCESSING_TIME)
-                        .onSuccess(HttpValueFunctions.chain(HttpValueFunctions.jsonContents(new String[] { "couchdb", "request_time", "max" }, Double.class), new Function<Double, Integer>() {
-                            @Override
-                            public Integer apply(@Nullable Double input) {
-                                return Integer.valueOf(input.intValue());
-                            }
-                        }))
-                        .onFailureOrException(Functions.constant(-1)))
+                        .onSuccess(Functionals.chain(HttpValueFunctions.jsonContents(new String[] { "couchdb", "request_time", "max" }, Double.class), TypeCoercions.function(Integer.class)))
+                        .onFailureOrException(Functions.constant(-1))
+                        .enabled(retrieveUsageMetrics))
                 .build();
 
         WebAppServiceMethods.connectWebAppServerPolicies(this);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
index f556bcf..c2d559f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
@@ -64,7 +64,8 @@ public class RedisStoreImpl extends SoftwareProcessImpl implements RedisStore {
         if (!location.isPresent()) throw new IllegalStateException("Could not find SshMachineLocation in list of locations");
         SshMachineLocation machine = (SshMachineLocation) location.get();
         String statsCommand = getDriver().getRunDir() + "/bin/redis-cli -p " + getRedisPort() + " info stats";
-
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+        
         sshFeed = SshFeed.builder()
                 .entity(this)
                 .machine(machine)
@@ -72,31 +73,38 @@ public class RedisStoreImpl extends SoftwareProcessImpl implements RedisStore {
                 .poll(new SshPollConfig<Integer>(UPTIME)
                         .command(getDriver().getRunDir() + "/bin/redis-cli -p " + getRedisPort() + " info server")
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("uptime_in_seconds")))
+                        .onSuccess(infoFunction("uptime_in_seconds"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(TOTAL_CONNECTIONS_RECEIVED)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("total_connections_received")))
+                        .onSuccess(infoFunction("total_connections_received"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(TOTAL_COMMANDS_PROCESSED)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("total_commands_processed")))
+                        .onSuccess(infoFunction("total_commands_processed"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(EXPIRED_KEYS)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("expired_keys")))
+                        .onSuccess(infoFunction("expired_keys"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(EVICTED_KEYS)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("evicted_keys")))
+                        .onSuccess(infoFunction("evicted_keys"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(KEYSPACE_HITS)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("keyspace_hits")))
+                        .onSuccess(infoFunction("keyspace_hits"))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new SshPollConfig<Integer>(KEYSPACE_MISSES)
                         .command(statsCommand)
                         .onFailureOrException(Functions.constant(-1))
-                        .onSuccess(infoFunction("keyspace_misses")))
+                        .onSuccess(infoFunction("keyspace_misses"))
+                        .enabled(retrieveUsageMetrics))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
index 932fd44..7bfb6e6 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
@@ -25,7 +25,9 @@ import java.util.concurrent.TimeUnit;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import brooklyn.enricher.Enrichers;
 import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
 import brooklyn.event.feed.jmx.JmxAttributePollConfig;
 import brooklyn.event.feed.jmx.JmxFeed;
@@ -60,24 +62,31 @@ public class JBoss6ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
 
         String requestProcessorMbeanName = "jboss.web:type=GlobalRequestProcessor,name=http-*";
         String serverMbeanName = "jboss.system:type=Server";
-        
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
+
         jmxFeed = JmxFeed.builder()
                 .entity(this)
                 .period(500, TimeUnit.MILLISECONDS)
+                .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_UP)
+                        // TODO instead of setting SERVICE_UP directly, want to use equivalent of 
+                        // addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS).key("serverMBean")...
+                        // but not supported in feed?
+                        .objectName(serverMbeanName)
+                        .attributeName("Started")
+                        .onException(Functions.constant(false))
+                        .suppressDuplicates(true))
                 .pollAttribute(new JmxAttributePollConfig<Integer>(ERROR_COUNT)
                         .objectName(requestProcessorMbeanName)
-                        .attributeName("errorCount"))
+                        .attributeName("errorCount")
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Integer>(REQUEST_COUNT)
                         .objectName(requestProcessorMbeanName)
-                        .attributeName("requestCount"))
+                        .attributeName("requestCount")
+                        .enabled(retrieveUsageMetrics))
                 .pollAttribute(new JmxAttributePollConfig<Integer>(TOTAL_PROCESSING_TIME)
                         .objectName(requestProcessorMbeanName)
-                        .attributeName("processingTime"))
-                .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_UP)
-                        .objectName(serverMbeanName)
-                        .attributeName("Started")
-                        .onException(Functions.constant(false))
-                        .suppressDuplicates(true))
+                        .attributeName("processingTime")
+                        .enabled(retrieveUsageMetrics))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index 258b6be..cf6ba59 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -82,6 +82,7 @@ public class JBoss7ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
         setAttribute(MANAGEMENT_URL, managementUri);
         log.debug("JBoss sensors for "+this+" reading from "+managementUri);
         Map<String, String> includeRuntimeUriVars = ImmutableMap.of("include-runtime","true");
+        boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
         
         httpFeed = HttpFeed.builder()
                 .entity(this)
@@ -97,23 +98,29 @@ public class JBoss7ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
                         .suppressDuplicates(true))
                 .poll(new HttpPollConfig<Integer>(REQUEST_COUNT)
                         .vars(includeRuntimeUriVars)
-                        .onSuccess(HttpValueFunctions.jsonContents("requestCount", Integer.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("requestCount", Integer.class))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(ERROR_COUNT)
                         .vars(includeRuntimeUriVars)
-                        .onSuccess(HttpValueFunctions.jsonContents("errorCount", Integer.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("errorCount", Integer.class))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(TOTAL_PROCESSING_TIME)
                         .vars(includeRuntimeUriVars)
-                        .onSuccess(HttpValueFunctions.jsonContents("processingTime", Integer.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("processingTime", Integer.class))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Integer>(MAX_PROCESSING_TIME)
                         .vars(includeRuntimeUriVars)
-                        .onSuccess(HttpValueFunctions.jsonContents("maxTime", Integer.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("maxTime", Integer.class))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Long>(BYTES_RECEIVED)
                         .vars(includeRuntimeUriVars)
                         // jboss seems to report 0 even if it has received lots of requests; dunno why.
-                        .onSuccess(HttpValueFunctions.jsonContents("bytesReceived", Long.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("bytesReceived", Long.class))
+                        .enabled(retrieveUsageMetrics))
                 .poll(new HttpPollConfig<Long>(BYTES_SENT)
                         .vars(includeRuntimeUriVars)
-                        .onSuccess(HttpValueFunctions.jsonContents("bytesSent", Long.class)))
+                        .onSuccess(HttpValueFunctions.jsonContents("bytesSent", Long.class))
+                        .enabled(retrieveUsageMetrics))
                 .build();
         
         connectServiceUp();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
index 929d120..e5b5ac0 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
@@ -56,28 +56,35 @@ public class TomcatServerImpl extends JavaWebAppSoftwareProcessImpl implements T
 
             Integer port = isHttpsEnabled() ? getAttribute(HTTPS_PORT) : getAttribute(HTTP_PORT);
             String connectorMbeanName = format("Catalina:type=Connector,port=%s", port);
+            boolean retrieveUsageMetrics = getConfig(RETRIEVE_USAGE_METRICS);
 
             jmxWebFeed = JmxFeed.builder()
                     .entity(this)
                     .period(3000, TimeUnit.MILLISECONDS)
-                    .pollAttribute(new JmxAttributePollConfig<Integer>(ERROR_COUNT)
-                            .objectName(requestProcessorMbeanName)
-                            .attributeName("errorCount"))
-                    .pollAttribute(new JmxAttributePollConfig<Integer>(REQUEST_COUNT)
-                            .objectName(requestProcessorMbeanName)
-                            .attributeName("requestCount"))
-                    .pollAttribute(new JmxAttributePollConfig<Integer>(TOTAL_PROCESSING_TIME)
-                            .objectName(requestProcessorMbeanName)
-                            .attributeName("processingTime"))
-                    .pollAttribute(new JmxAttributePollConfig<String>(CONNECTOR_STATUS)
-                            .objectName(connectorMbeanName)
-                            .attributeName("stateName"))
                     .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_PROCESS_IS_RUNNING)
+                            // TODO Want to use something different from SERVICE_PROCESS_IS_RUNNING,
+                            // to indicate this is jmx MBean's reported state (or failure to connect)
                             .objectName(connectorMbeanName)
                             .attributeName("stateName")
                             .onSuccess(Functions.forPredicate(Predicates.<Object>equalTo("STARTED")))
                             .setOnFailureOrException(false)
                             .suppressDuplicates(true))
+                    .pollAttribute(new JmxAttributePollConfig<String>(CONNECTOR_STATUS)
+                            .objectName(connectorMbeanName)
+                            .attributeName("stateName")
+                            .suppressDuplicates(true))
+                    .pollAttribute(new JmxAttributePollConfig<Integer>(ERROR_COUNT)
+                            .objectName(requestProcessorMbeanName)
+                            .attributeName("errorCount")
+                            .enabled(retrieveUsageMetrics))
+                    .pollAttribute(new JmxAttributePollConfig<Integer>(REQUEST_COUNT)
+                            .objectName(requestProcessorMbeanName)
+                            .attributeName("requestCount")
+                            .enabled(retrieveUsageMetrics))
+                    .pollAttribute(new JmxAttributePollConfig<Integer>(TOTAL_PROCESSING_TIME)
+                            .objectName(requestProcessorMbeanName)
+                            .attributeName("processingTime")
+                            .enabled(retrieveUsageMetrics))
                     .build();
 
             jmxAppFeed = JavaAppUtils.connectMXBeanSensors(this);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b4166230/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
new file mode 100644
index 0000000..0761af6
--- /dev/null
+++ b/software/webapp/src/test/java/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.entity.webapp.tomcat;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.test.Asserts;
+import brooklyn.test.EntityTestUtils;
+
+import com.google.common.collect.ImmutableList;
+
+public class TomcatServerDisableRetrieveUsageMetricsIntegrationTest extends BrooklynAppLiveTestSupport {
+    
+    // Note we test the default and the disabled with two entities, in the same method.
+    // This piggie-backs off the necessary length of time required for the default entity
+    // to have its metrics set; we then assert that the other entity does not have its set.
+    @Test(groups="Integration")
+    public void testDisableRetrievalOfUsageMetrics() throws Exception {
+        LocalhostMachineProvisioningLocation loc = app.newLocalhostProvisioningLocation();
+        final TomcatServer tc1 = app.createAndManageChild(EntitySpec.create(TomcatServer.class)
+                .configure(SoftwareProcess.RETRIEVE_USAGE_METRICS, false));
+        final TomcatServer tc2 = app.createAndManageChild(EntitySpec.create(TomcatServer.class));
+        
+        tc1.start(ImmutableList.of(loc));
+        tc2.start(ImmutableList.of(loc));
+
+        // tc2 uses defaults, so will include usage metrics
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                assertNotNull(tc2.getAttribute(TomcatServer.CONNECTOR_STATUS));
+                assertNotNull(tc2.getAttribute(TomcatServer.ERROR_COUNT));
+                assertNotNull(tc2.getAttribute(TomcatServer.REQUEST_COUNT));
+                assertNotNull(tc2.getAttribute(TomcatServer.TOTAL_PROCESSING_TIME));
+            }});
+
+        // tc1 should have status info, but not usage metrics
+        EntityTestUtils.assertAttributeEventuallyNonNull(tc1, TomcatServer.CONNECTOR_STATUS);
+        EntityTestUtils.assertAttributeEqualsContinually(tc1, TomcatServer.ERROR_COUNT, null);
+        assertNull(tc1.getAttribute(TomcatServer.REQUEST_COUNT));
+        assertNull(tc1.getAttribute(TomcatServer.TOTAL_PROCESSING_TIME));
+    }
+}


[13/18] incubator-brooklyn git commit: Fix SameServerEntity: up when all members up

Posted by al...@apache.org.
Fix SameServerEntity: up when all members up


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

Branch: refs/heads/master
Commit: b9e81ed4845453d685c04c0372f8419b1bb7dcdf
Parents: 286289e
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:21:05 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:31 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/entity/basic/SameServerEntityImpl.java     | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b9e81ed4/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
index fcd687e..a773c98 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
@@ -22,9 +22,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Collection;
 
+import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.location.Location;
 import brooklyn.management.Task;
+import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.Tasks;
@@ -36,7 +38,11 @@ public class SameServerEntityImpl extends AbstractEntity implements SameServerEn
     @Override
     protected void initEnrichers() {
         super.initEnrichers();
-        addEnricher(ServiceStateLogic.newEnricherFromChildren());
+        
+        // Because can have multiple children (similar to groups/clusters/apps), need to
+        // monitor their health and indicate this has failed if any of them have failed.
+        addEnricher(ServiceStateLogic.newEnricherFromChildren()
+                .configure(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, QuorumCheck.QuorumChecks.all()));
     }
     
     /**


[11/18] incubator-brooklyn git commit: Tests for defaultDisplayName

Posted by al...@apache.org.
Tests for defaultDisplayName


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

Branch: refs/heads/master
Commit: 286289e8797bff0e2e736b0cdad5ab02ac481e9a
Parents: 23543fa
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:18:43 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:30 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/EntitySpecTest.java   | 33 ++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/286289e8/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java b/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
index f80ab04..da0c983 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import brooklyn.config.ConfigKey;
 import brooklyn.enricher.basic.AbstractEnricher;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Entity;
@@ -37,6 +38,7 @@ import brooklyn.policy.PolicySpec;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.test.entity.TestEntity;
+import brooklyn.test.entity.TestEntityImpl;
 import brooklyn.test.entity.TestEntityNoEnrichersImpl;
 import brooklyn.util.flags.SetFromFlag;
 
@@ -153,19 +155,46 @@ public class EntitySpecTest extends BrooklynAppUnitTestSupport {
     }
     
     @Test
-    public void testSetsDefaultDisplayName() throws Exception {
+    public void testDisplayNameUsesDefault() throws Exception {
         TestEntity entity = app.addChild(EntitySpec.create(TestEntity.class));
         
         assertTrue(entity.getDisplayName().startsWith("TestEntity:"+entity.getId().substring(0,4)), "displayName="+entity.getDisplayName());
     }
     
     @Test
-    public void testUsesCustomDisplayName() throws Exception {
+    public void testDisplayNameUsesCustom() throws Exception {
         TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("entityname"));
         
         assertEquals(entity.getDisplayName(), "entityname");
     }
 
+    @Test
+    public void testDisplayNameUsesOverriddenDefault() throws Exception {
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+                .impl(TestEntityWithDefaultNameImpl.class)
+                .configure(TestEntityWithDefaultNameImpl.DEFAULT_NAME, "myOverriddenDefaultName"));
+        assertEquals(entity.getDisplayName(), "myOverriddenDefaultName");
+    }        
+
+    @Test
+    public void testDisplayNameUsesCustomWhenOverriddenDefault() throws Exception {
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+                .impl(TestEntityWithDefaultNameImpl.class)
+                .configure(TestEntityWithDefaultNameImpl.DEFAULT_NAME, "myOverriddenDefaultName")
+                .displayName("myEntityName"));
+        assertEquals(entity.getDisplayName(), "myEntityName");
+    }        
+
+    public static class TestEntityWithDefaultNameImpl extends TestEntityImpl {
+        public static final ConfigKey<String> DEFAULT_NAME = ConfigKeys.newStringConfigKey("defaultName");
+        
+        @Override
+        public void init() {
+            super.init();
+            if (getConfig(DEFAULT_NAME) != null) setDefaultDisplayName(getConfig(DEFAULT_NAME));
+        }
+    }
+    
     public static class MyPolicy extends AbstractPolicy {
         public static final BasicConfigKey<String> CONF1 = new BasicConfigKey<String>(String.class, "testpolicy.conf1", "my descr, conf1", "defaultval1");
         public static final BasicConfigKey<Integer> CONF2 = new BasicConfigKey<Integer>(Integer.class, "testpolicy.conf2", "my descr, conf2", 2);


[15/18] incubator-brooklyn git commit: Creates ApplicationsYamlTest

Posted by al...@apache.org.
Creates ApplicationsYamlTest

Moves tests about app-wrapping from EntitiesYamlTest to
ApplicationsYamlTest.


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

Branch: refs/heads/master
Commit: a5fbce79024b5645feaa7e21fce06a55f35c6b89
Parents: 4549e28
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:23:58 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:32 2015 +0100

----------------------------------------------------------------------
 .../camp/brooklyn/ApplicationsYamlTest.java     | 115 +++++++++++++++++++
 .../camp/brooklyn/EntitiesYamlTest.java         |  38 ------
 2 files changed, 115 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a5fbce79/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
new file mode 100644
index 0000000..3f860d6
--- /dev/null
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/ApplicationsYamlTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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 io.brooklyn.camp.brooklyn;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.BasicEntity;
+import brooklyn.management.internal.EntityManagementUtils;
+
+import com.google.common.collect.Iterables;
+
+@Test
+public class ApplicationsYamlTest extends AbstractYamlTest {
+    private static final Logger log = LoggerFactory.getLogger(ApplicationsYamlTest.class);
+
+    @Test
+    public void testWrapsEntity() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicEntity.class.getName());
+        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicEntity);
+    }
+
+    @Test
+    public void testDoesNotWrapApp() throws Exception {
+        Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertTrue(app.getChildren().isEmpty());
+    }
+
+    @Test
+    public void testWrapsAppIfForced() throws Exception {
+        Entity app = createAndStartApplication(
+                "wrappedApp: true",
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicApplication);
+        assertTrue(Iterables.getOnlyElement(app.getChildren()).getChildren().isEmpty());
+    }
+
+    @Test
+    public void testDoesNotWrapAppIfUnforced() throws Exception {
+        Entity app = createAndStartApplication(
+                "wrappedApp: false",
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertTrue(app.getChildren().isEmpty());
+    }
+    
+    @Test
+    public void testWrapsEntityIfDifferentTopLevelName() throws Exception {
+        Entity app = createAndStartApplication(
+                "name: topLevel",
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  name: bottomLevel");
+        assertTrue(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertEquals(app.getDisplayName(), "topLevel");
+        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof BasicApplication);
+        assertTrue(Iterables.getOnlyElement(app.getChildren()).getChildren().isEmpty());
+        assertEquals(Iterables.getOnlyElement(app.getChildren()).getDisplayName(), "bottomLevel");
+    }
+    
+    @Test
+    public void testDoesNotWrapsEntityIfNoNameOnService() throws Exception {
+        Entity app = createAndStartApplication(
+                "name: topLevel",
+                "services:",
+                "- type: " + BasicApplication.class.getName());
+        assertNull(app.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
+        assertTrue(app instanceof BasicApplication);
+        assertTrue(app.getChildren().isEmpty());
+        assertEquals(app.getDisplayName(), "topLevel");
+    }
+    
+    @Override
+    protected Logger getLogger() {
+        return log;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a5fbce79/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index e873ffa..e35b217 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -20,7 +20,6 @@ package org.apache.brooklyn.camp.brooklyn;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 import java.io.StringReader;
@@ -44,7 +43,6 @@ import brooklyn.entity.Application;
 import brooklyn.entity.Effector;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.BasicEntity;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
@@ -60,7 +58,6 @@ import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.location.Location;
 import brooklyn.management.Task;
-import brooklyn.management.internal.EntityManagementUtils;
 import brooklyn.management.internal.EntityManagerInternal;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.test.entity.TestEntityImpl;
@@ -877,43 +874,8 @@ public class EntitiesYamlTest extends AbstractYamlTest {
         }
     }
 
-    @Test
-    public void testWrapperAppMarkerExists() throws Exception {
-        Entity entity = createAndStartApplication(
-                "services:",
-                "- type: " + BasicEntity.class.getName());
-        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerDoesntExist() throws Exception {
-        Entity entity = createAndStartApplication(
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerForced() throws Exception {
-        Entity entity = createAndStartApplication(
-                "wrappedApp: true",
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertTrue(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
-    @Test
-    public void testWrapperAppMarkerUnforced() throws Exception {
-        Entity entity = createAndStartApplication(
-                "wrappedApp: false",
-                "services:",
-                "- type: " + BasicApplication.class.getName());
-        assertNull(entity.getConfig(EntityManagementUtils.WRAPPER_APP_MARKER));
-    }
-
     @Override
     protected Logger getLogger() {
         return log;
     }
-
 }


[07/18] incubator-brooklyn git commit: Fix subnetHostname (in JcloudsLocation’s private hostname)

Posted by al...@apache.org.
Fix subnetHostname (in JcloudsLocation’s private hostname)


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

Branch: refs/heads/master
Commit: f2e32912a6ae216e712962d84ee4885edc67f96c
Parents: 92063d9
Author: Aled Sage <al...@gmail.com>
Authored: Fri May 1 20:18:06 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:28 2015 +0100

----------------------------------------------------------------------
 .../location/jclouds/JcloudsLocation.java       |  63 +++++
 .../jclouds/JcloudsSshMachineLocation.java      |  10 +-
 .../jclouds/JcloudsAddressesLiveTest.java       | 228 +++++++++++++++++++
 3 files changed, 295 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2e32912/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index 4916de5..0f4035b 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -2664,6 +2664,69 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
         }
     }
 
+    /**
+     * Attempts to obtain the private hostname or IP of the node, as advertised by the cloud provider.
+     * 
+     * For some clouds (e.g. aws-ec2), it will attempt to find the fully qualified hostname (as that works in public+private).
+     */
+    protected String getPrivateHostname(NodeMetadata node, Optional<HostAndPort> sshHostAndPort, ConfigBag setup) {
+        String provider = (setup != null) ? setup.get(CLOUD_PROVIDER) : null;
+        if (provider == null) provider= getProvider();
+
+        // TODO Discouraged to do cloud-specific things; think of this code for aws as an
+        // exceptional situation rather than a pattern to follow. We need a better way to
+        // do cloud-specific things.
+        if ("aws-ec2".equals(provider)) {
+            Maybe<String> result = getPrivateHostnameAws(node, sshHostAndPort, setup);
+            if (result.isPresent()) return result.get();
+        }
+
+        return getPrivateHostnameGeneric(node, setup);
+    }
+
+    private Maybe<String> getPrivateHostnameAws(NodeMetadata node, Optional<HostAndPort> sshHostAndPort, ConfigBag setup) {
+        // TODO Remove duplication from getPublicHostname.
+        // TODO Don't like 
+        HostAndPort inferredHostAndPort = null;
+        if (!sshHostAndPort.isPresent()) {
+            try {
+                String vmIp = JcloudsUtil.getFirstReachableAddress(this.getComputeService().getContext(), node);
+                int port = node.getLoginPort();
+                inferredHostAndPort = HostAndPort.fromParts(vmIp, port);
+            } catch (Exception e) {
+                LOG.warn("Error reaching aws-ec2 instance "+node.getId()+"@"+node.getLocation()+" on port "+node.getLoginPort()+"; falling back to jclouds metadata for address", e);
+            }
+        }
+        if (sshHostAndPort.isPresent() || inferredHostAndPort != null) {
+            HostAndPort hostAndPortToUse = sshHostAndPort.isPresent() ? sshHostAndPort.get() : inferredHostAndPort;
+            try {
+                return Maybe.of(getPublicHostnameAws(hostAndPortToUse, setup));
+            } catch (Exception e) {
+                LOG.warn("Error querying aws-ec2 instance instance "+node.getId()+"@"+node.getLocation()+" over ssh for its hostname; falling back to jclouds metadata for address", e);
+            }
+        }
+        return Maybe.absent();
+    }
+
+    private String getPrivateHostnameGeneric(NodeMetadata node, @Nullable ConfigBag setup) {
+        //prefer the private address to the hostname because hostname is sometimes wrong/abbreviated
+        //(see that javadoc; also e.g. on rackspace/cloudstack, the hostname is not registered with any DNS).
+        //Don't return local-only address (e.g. never 127.0.0.1)
+        if (groovyTruth(node.getPrivateAddresses())) {
+            for (String p : node.getPrivateAddresses()) {
+                if (Networking.isLocalOnly(p)) continue;
+                return p;
+            }
+        }
+        if (groovyTruth(node.getPublicAddresses())) {
+            return node.getPublicAddresses().iterator().next();
+        } else if (groovyTruth(node.getHostname())) {
+            return node.getHostname();
+        } else {
+            return null;
+        }
+    }
+
     // ------------ static converters (could go to a new file) ------------------
 
     public static File asFile(Object o) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2e32912/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
index 6e98e3a..205771a 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
@@ -153,6 +153,7 @@ public class JcloudsSshMachineLocation extends SshMachineLocation implements Jcl
         return node.getHostname();
     }
     
+    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
     @Override
     public Set<String> getPublicAddresses() {
         return node.getPublicAddresses();
@@ -163,11 +164,10 @@ public class JcloudsSshMachineLocation extends SshMachineLocation implements Jcl
         return node.getPrivateAddresses();
     }
 
-    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
     @Override
     public String getSubnetHostname() {
-        String publicHostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
-        return publicHostname;
+        String privateHostname = jcloudsParent.getPrivateHostname(node, Optional.<HostAndPort>absent(), config().getBag());
+        return privateHostname;
     }
 
     @Override
@@ -190,9 +190,7 @@ public class JcloudsSshMachineLocation extends SshMachineLocation implements Jcl
 
     protected Optional<String> getPrivateAddress() {
         if (groovyTruth(node.getPrivateAddresses())) {
-            Iterator<String> pi = node.getPrivateAddresses().iterator();
-            while (pi.hasNext()) {
-                String p = pi.next();
+            for (String p : node.getPrivateAddresses()) {
                 // disallow local only addresses
                 if (Networking.isLocalOnly(p)) continue;
                 // other things may be public or private, but either way, return it

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2e32912/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
new file mode 100644
index 0000000..2d5d511
--- /dev/null
+++ b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import brooklyn.location.LocationSpec;
+import brooklyn.location.basic.Locations;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.stream.Streams;
+
+/**
+ * Tests that the correct address is advertised for the VM - for its public/private, 
+ * its subnet hostname, etc.
+ */
+public class JcloudsAddressesLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsAddressesLiveTest.class);
+
+    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
+    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : ":" + AWS_EC2_REGION_NAME);
+    
+    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.0, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, version=5.8.8.5, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_CENTOS_IMAGE_ID = "us-east-1/ami-7d7bfc14";
+
+    // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_UBUNTU_IMAGE_ID = "us-east-1/ami-d0f89fb9";
+    
+    // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    // Uses "root" as loginUser
+    public static final String AWS_EC2_UBUNTU_10_IMAGE_ID = "us-east-1/ami-5e008437";
+
+    public static final String RACKSPACE_LOCATION_SPEC = "jclouds:" + RACKSPACE_PROVIDER;
+    
+    // Image: {id=LON/c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, providerId=c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, name=CentOS 6.0, location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=centos, name=CentOS 6.0, version=6.0, description=CentOS 6.0, is64Bit=true}, description=CentOS 6.0, status=AVAILABLE, loginUser=root, userMetadata={os_distro=centos, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.centos, com.rackspace__1__release_build_date=2013-07-25_18-56-29, auto_disk_config=True, com.rackspace__1__release_version=5, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=210, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.0, org.openstack__1__architecture=x64, com.rackspace__1__build_ma
 naged=0}}
+    public static final String RACKSPACE_CENTOS_IMAGE_NAME_REGEX = "CentOS 6.0";
+    
+    protected JcloudsSshMachineLocation machine;
+    
+    @Test(groups = {"Live"})
+    protected void testAwsEc2Addresses() throws Exception {
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+
+        String locationAddress = machine.getAddress().getHostName();
+        InetAddress address = machine.getAddress();
+        Set<String> publicAddresses = machine.getPublicAddresses();
+        Set<String> privateAddresses = machine.getPrivateAddresses();
+        String subnetIp = machine.getSubnetIp();
+        String hostname = machine.getHostname();
+        String subnetHostname = machine.getSubnetHostname();
+        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
+        LOG.info("node: "+msg);
+
+        // On AWS, machine advertises its FQ hostname that is accessible from inside and outside the region
+        assertReachable(machine, locationAddress, msg);
+        assertReachableFromMachine(machine, locationAddress, msg);
+
+        assertReachable(machine, address, msg);
+        
+        assertTrue(publicAddresses.size() > 0, msg);
+        for (String publicAddress: publicAddresses) {
+            assertReachable(machine, publicAddress, msg);
+        }
+        
+        // On AWS, private address is not reachable from outside.
+        // If you ran this test from the same AWS region, it would fail!
+        assertTrue(privateAddresses.size() > 0, msg);
+        for (String privateAddress: privateAddresses) {
+            assertReachableFromMachine(machine, privateAddress, msg);
+            assertNotReachable(machine, privateAddress, msg);
+        }
+        
+        assertNotNull(subnetIp, msg);
+        assertReachableFromMachine(machine, subnetIp, msg);
+
+        // hostname is reachable from inside; not necessarily reachable from outside
+        assertNotNull(hostname, msg);
+        assertReachableFromMachine(machine, hostname, msg);
+        
+        assertNotNull(subnetHostname, msg);
+        assertReachableFromMachine(machine, subnetHostname, msg);
+    }
+
+    @Test(groups = {"Live"})
+    protected void testRackspaceAddresses() throws Exception {
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+        
+        machine = createRackspaceMachine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+
+        String locationAddress = machine.getAddress().getHostAddress();
+        InetAddress address = machine.getAddress();
+        Set<String> publicAddresses = machine.getPublicAddresses();
+        Set<String> privateAddresses = machine.getPrivateAddresses();
+        String subnetIp = machine.getSubnetIp();
+        String hostname = machine.getHostname();
+        String subnetHostname = machine.getSubnetHostname();
+        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
+        LOG.info("node: "+msg);
+
+        // On Rackspace, IP is accessible from inside and outside.
+        assertReachable(machine, locationAddress, msg);
+        assertReachableFromMachine(machine, locationAddress, msg);
+
+        assertReachable(machine, address, msg);
+        
+        assertTrue(publicAddresses.size() > 0, msg);
+        for (String publicAddress: publicAddresses) {
+            assertReachable(machine, publicAddress, msg);
+        }
+        
+        // On Rackspace, don't care if no private addresses
+        for (String privateAddress: privateAddresses) {
+            assertReachableFromMachine(machine, privateAddress, msg);
+            assertNotReachable(machine, privateAddress, msg);
+        }
+        
+        assertNotNull(subnetIp, msg);
+        assertReachableFromMachine(machine, subnetIp, msg);
+
+        // hostname is reachable from inside; not necessarily reachable from outside
+        assertNotNull(hostname, msg);
+        assertReachableFromMachine(machine, hostname, msg);
+        
+        assertNotNull(subnetHostname, msg);
+        assertReachableFromMachine(machine, subnetHostname, msg);
+    }
+
+    private void assertReachable(SshMachineLocation machine, InetAddress addr, String msg) {
+        assertReachable(machine, addr.getHostAddress(), msg);
+    }
+
+    private void assertReachable(SshMachineLocation machine, String addr, String msg) {
+        assertReachability(true, machine, addr, msg);
+    }
+    
+    private void assertNotReachable(SshMachineLocation machine, String addr, String msg) {
+        assertReachability(false, machine, addr, msg);
+    }
+
+    private void assertReachability(boolean expectedReachable, SshMachineLocation machine, String addr, String msg) {
+        SshMachineLocation tmpMachine = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machine.config().getBag().getAllConfig())
+                .configure("address", addr));
+        try {
+            boolean sshable = tmpMachine.isSshable();
+            assertEquals(sshable, expectedReachable, addr+" not sshable; "+msg);
+        } finally {
+            Locations.unmanage(tmpMachine);
+        }
+    }
+
+    // TODO Assumes that "ping" will work; i.e. that ICMP is not firewall'ed
+    private void assertReachableFromMachine(SshMachineLocation machine, String addr, String msg) {
+        OutputStream outStream = new ByteArrayOutputStream();
+        OutputStream errStream = new ByteArrayOutputStream();
+        int result = machine.execScript(MutableMap.of("out", outStream, "err", errStream), "reach "+addr, ImmutableList.of("ping -c 1 "+addr));
+        String outString = outStream.toString();
+        String errString = errStream.toString();
+        assertEquals(result, 0, "result="+0+"; err="+errString+"; out="+outString+"; msg="+msg);
+    }
+
+    @Override
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        jcloudsLocation.release(machine);
+    }
+    
+    private JcloudsSshMachineLocation createEc2Machine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("imageId", AWS_EC2_CENTOS_IMAGE_ID)
+                .putIfAbsent("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    private JcloudsSshMachineLocation createRackspaceMachine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    protected void assertSshable(Map<?,?> machineConfig) {
+        SshMachineLocation machineWithThatConfig = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machineConfig));
+        try {
+            assertSshable(machineWithThatConfig);
+        } finally {
+            Streams.closeQuietly(machineWithThatConfig);
+        }
+    }
+}


[06/18] incubator-brooklyn git commit: Adds SoftwareProcess.SERVICE_NOT_UP_DIAGNOSTICS

Posted by al...@apache.org.
Adds SoftwareProcess.SERVICE_NOT_UP_DIAGNOSTICS

In SoftwareProcess, only do expensive checks (e.g. process-running)
if serviceUp is false.


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

Branch: refs/heads/master
Commit: 0c52d9c27fd3c664d7e7f3f24b81cf1d2044708e
Parents: b416623
Author: Aled Sage <al...@gmail.com>
Authored: Thu Apr 23 21:21:18 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:27 2015 +0100

----------------------------------------------------------------------
 .../java/brooklyn/entity/basic/Attributes.java  | 10 +++
 .../entity/basic/ServiceStateLogic.java         |  1 +
 .../postgresql/PostgreSqlNodeSaltImpl.java      |  6 +-
 .../brooklyn/entity/basic/SoftwareProcess.java  |  7 +++
 .../entity/basic/SoftwareProcessImpl.java       | 64 ++++++++++++++++++++
 .../entity/brooklynnode/BrooklynNodeImpl.java   |  4 +-
 .../brooklyn/entity/chef/ChefEntityImpl.java    |  8 ++-
 .../entity/brooklynnode/MockBrooklynNode.java   |  4 ++
 .../brooklynnode/SameBrooklynNodeImpl.java      |  4 ++
 .../PostgreSqlNodeChefImplFromScratch.java      |  4 ++
 .../entity/webapp/jboss/JBoss7ServerImpl.java   |  2 -
 11 files changed, 106 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/core/src/main/java/brooklyn/entity/basic/Attributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Attributes.java b/core/src/main/java/brooklyn/entity/basic/Attributes.java
index f625652..3ff977c 100644
--- a/core/src/main/java/brooklyn/entity/basic/Attributes.java
+++ b/core/src/main/java/brooklyn/entity/basic/Attributes.java
@@ -102,6 +102,7 @@ public interface Attributes {
      */
     AttributeSensor<Boolean> SERVICE_UP = Sensors.newBooleanSensor("service.isUp", 
             "Whether the service is active and availability (confirmed and monitored)");
+    
     @SuppressWarnings("serial")
     AttributeSensor<Map<String,Object>> SERVICE_NOT_UP_INDICATORS = Sensors.newSensor(
         new TypeToken<Map<String,Object>>() {},
@@ -114,6 +115,15 @@ public interface Attributes {
         "service.problems", 
         "A map of namespaced indicators of problems with a service");
 
+    /**
+     * @since 0.8.0
+     */
+    @SuppressWarnings("serial")
+    AttributeSensor<Map<String,Object>> SERVICE_NOT_UP_DIAGNOSTICS = Sensors.newSensor(
+        new TypeToken<Map<String,Object>>() {},
+        "service.notUp.diagnostics", 
+        "A map of namespaced diagnostics, from when the service is not up");
+    
     AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Sensors.newSensor(Lifecycle.class,
             "service.state", "Actual lifecycle state of the service");
     AttributeSensor<Lifecycle.Transition> SERVICE_STATE_EXPECTED = Sensors.newSensor(Lifecycle.Transition.class,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
index 3b1efbe..135c1a3 100644
--- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
+++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
@@ -75,6 +75,7 @@ public class ServiceStateLogic {
     
     public static final AttributeSensor<Boolean> SERVICE_UP = Attributes.SERVICE_UP;
     public static final AttributeSensor<Map<String,Object>> SERVICE_NOT_UP_INDICATORS = Attributes.SERVICE_NOT_UP_INDICATORS;
+    public static final AttributeSensor<Map<String,Object>> SERVICE_NOT_UP_DIAGNOSTICS = Attributes.SERVICE_NOT_UP_DIAGNOSTICS;
     
     public static final AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Attributes.SERVICE_STATE_ACTUAL;
     public static final AttributeSensor<Lifecycle.Transition> SERVICE_STATE_EXPECTED = Attributes.SERVICE_STATE_EXPECTED;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 66c7acb..e394187 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -18,10 +18,10 @@
  */
 package org.apache.brooklyn.entity.database.postgresql;
 
-import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNodeSaltImpl;
 import org.apache.brooklyn.entity.salt.SaltConfig;
 import org.apache.brooklyn.entity.salt.SaltConfigs;
 import org.apache.brooklyn.entity.salt.SaltLifecycleEffectorTasks;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -176,4 +176,8 @@ public class PostgreSqlNodeSaltImpl extends EffectorStartableImpl implements Pos
                 ConfigBag.newInstance().configure(ExecuteScriptEffectorBody.SCRIPT, commands).getAllConfig()).getUnchecked();
     }
 
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        // TODO no-op currently; should check ssh'able etc
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index 05852d0..064f462 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.Lifecycle.Transition;
+import brooklyn.entity.annotation.Effector;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.AttributeSensorAndConfigKey;
@@ -348,4 +349,10 @@ public interface SoftwareProcess extends Entity, Startable {
     
     // NB: the START, STOP, and RESTART effectors themselves are (re)defined by MachineLifecycleEffectorTasks
 
+    /**
+     * @since 0.8.0
+     */
+    @Effector(description="Populates the attribute service.notUp.diagnostics, with any available health indicators")
+    @Beta
+    void populateServiceNotUpDiagnostics();
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
index 3ae2c9e..feb506a 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -49,6 +49,7 @@ import brooklyn.location.MachineLocation;
 import brooklyn.location.MachineProvisioningLocation;
 import brooklyn.location.PortRange;
 import brooklyn.location.basic.LocationConfigKeys;
+import brooklyn.location.basic.SshMachineLocation;
 import brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.management.Task;
 import brooklyn.policy.EnricherSpec;
@@ -64,6 +65,7 @@ import brooklyn.util.time.Time;
 
 import com.google.common.base.Functions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import com.google.common.reflect.TypeToken;
@@ -133,8 +135,70 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
         ServiceNotUpLogic.updateNotUpIndicator(this, SERVICE_PROCESS_IS_RUNNING, "No information yet on whether this service is running");
         // add an indicator above so that if is_running comes through, the map is cleared and an update is guaranteed
         addEnricher(EnricherSpec.create(UpdatingNotUpFromServiceProcessIsRunning.class).uniqueTag("service-process-is-running-updating-not-up"));
+        addEnricher(EnricherSpec.create(ServiceNotUpDiagnosticsCollector.class).uniqueTag("service-not-up-diagnostics-collector"));
     }
     
+    /**
+     * @since 0.8.0
+     */
+    protected static class ServiceNotUpDiagnosticsCollector extends AbstractEnricher implements SensorEventListener<Object> {
+        public ServiceNotUpDiagnosticsCollector() {
+        }
+        
+        @Override
+        public void setEntity(EntityLocal entity) {
+            super.setEntity(entity);
+            if (!(entity instanceof SoftwareProcess)) {
+                throw new IllegalArgumentException("Expected SoftwareProcess, but got entity "+entity);
+            }
+            subscribe(entity, Attributes.SERVICE_UP, this);
+            onUpdated();
+        }
+
+        @Override
+        public void onEvent(SensorEvent<Object> event) {
+            onUpdated();
+        }
+
+        protected void onUpdated() {
+            Boolean up = entity.getAttribute(SERVICE_UP);
+            if (up == null || up) {
+                entity.setAttribute(ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, ImmutableMap.<String, Object>of());
+            } else {
+                ((SoftwareProcess)entity).populateServiceNotUpDiagnostics();
+            }
+        }
+    }
+    
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        if (getDriver() == null) {
+            ServiceStateLogic.updateMapSensorEntry(this, ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, "driver", "No driver");
+            return;
+        }
+
+        Location loc = getDriver().getLocation();
+        if (loc instanceof SshMachineLocation) {
+            if (!((SshMachineLocation)loc).isSshable()) {
+                ServiceStateLogic.updateMapSensorEntry(
+                        this, 
+                        ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, 
+                        "sshable", 
+                        "The machine for this entity does not appear to be sshable");
+            }
+            return;
+        }
+
+        boolean processIsRunning = getDriver().isRunning();
+        if (!processIsRunning) {
+            ServiceStateLogic.updateMapSensorEntry(
+                    this, 
+                    ServiceStateLogic.SERVICE_NOT_UP_DIAGNOSTICS, 
+                    SERVICE_PROCESS_IS_RUNNING.getName(), 
+                    "The software process for this entity does not appear to be running");
+        }
+    }
+
     /** subscribes to SERVICE_PROCESS_IS_RUNNING and SERVICE_UP; the latter has no effect if the former is set,
      * but to support entities which set SERVICE_UP directly we want to make sure that the absence of 
      * SERVICE_PROCESS_IS_RUNNING does not trigger any not-up indicators */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 7be6dc5..a477c6f 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -476,8 +476,6 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
         }
         setAttribute(WEB_CONSOLE_URI, webConsoleUri);
 
-        connectServiceUpIsRunning();
-
         if (webConsoleUri != null) {
             httpFeed = HttpFeed.builder()
                     .entity(this)
@@ -505,6 +503,8 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
                 .from(WEB_CONSOLE_ACCESSIBLE)
                 .computing(Functionals.ifNotEquals(true).value("URL where Brooklyn listens is not answering correctly") )
                 .build());
+        } else {
+            connectServiceUpIsRunning();
         }
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/main/java/brooklyn/entity/chef/ChefEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefEntityImpl.java b/software/base/src/main/java/brooklyn/entity/chef/ChefEntityImpl.java
index a96668f..6ee9b1f 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefEntityImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefEntityImpl.java
@@ -30,7 +30,9 @@ public class ChefEntityImpl extends EffectorStartableImpl implements ChefEntity
         super.init();
         new ChefLifecycleEffectorTasks().attachLifecycleEffectors(this);
     }
-    
-    
-    
+
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        // TODO no-op currently; should check ssh'able etc
+    }    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
index e20f493..b7c70d8 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
@@ -63,4 +63,8 @@ public class MockBrooklynNode extends AbstractEntity implements BrooklynNode {
     public void restart() {
     }
 
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        // no-op
+    }    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
index 198c257..4366873 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
@@ -88,4 +88,8 @@ public class SameBrooklynNodeImpl extends AbstractEntity implements BrooklynNode
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        // no-op
+    }    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
index 4e743c9..491c8e7 100644
--- a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
+++ b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
@@ -162,4 +162,8 @@ public class PostgreSqlNodeChefImplFromScratch extends EffectorStartableImpl imp
                 ConfigBag.newInstance().configure(ExecuteScriptEffectorBody.SCRIPT, commands).getAllConfig()).getUnchecked();
     }
 
+    @Override
+    public void populateServiceNotUpDiagnostics() {
+        // TODO no-op currently; should check ssh'able etc
+    }    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0c52d9c2/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index cf6ba59..5279d09 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -127,8 +127,6 @@ public class JBoss7ServerImpl extends JavaWebAppSoftwareProcessImpl implements J
     }
     
     protected void connectServiceUp() {
-        connectServiceUpIsRunning();
-        
         addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS)
             .from(MANAGEMENT_URL_UP)
             .computing(Functionals.ifNotEquals(true).value("Management URL not reachable") )


[16/18] incubator-brooklyn git commit: Adds CatalogYamlAppTest.testAddCatalogItemWithCircularReference

Posted by al...@apache.org.
Adds CatalogYamlAppTest.testAddCatalogItemWithCircularReference

A work-in-progress test, demonstrating a StackOverflowError.


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

Branch: refs/heads/master
Commit: 36fb5e9dcbe5f72a3be577006d5375aecea08cad
Parents: a5fbce7
Author: Aled Sage <al...@gmail.com>
Authored: Tue Aug 4 23:29:43 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Aug 11 20:04:32 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/catalog/CatalogYamlAppTest.java    | 73 ++++++++++++++++++++
 1 file changed, 73 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/36fb5e9d/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
new file mode 100644
index 0000000..48ecb42
--- /dev/null
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlAppTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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 io.brooklyn.camp.brooklyn.catalog;
+
+import org.testng.annotations.Test;
+
+import io.brooklyn.camp.brooklyn.AbstractYamlTest;
+
+
+public class CatalogYamlAppTest extends AbstractYamlTest {
+    
+    /**
+     * "Contrived" example was encountered by a customer in a real use-case!
+     * I couldn't yet simplify it further while still reproducing the failure.
+     * Throws StackOverlfowError, without giving a nice error message about 
+     * "BasicEntity" cyclic reference.
+     * 
+     * The circular reference comes from the member spec referencing 
+     * "brooklyn.entity.basic.BasicEntity", but that has been defined in the
+     * catalog as this new blueprint (which overrides the previous value of it
+     * being a reference to the Java class).
+     * 
+     * We need to use an id that matches something else already on the classpath.
+     * Otherwise we'd get an error telling us "could not resolve item ..." when
+     * attempting to add the initial catalog item.
+     */
+    @Test(groups="WIP") // TODO Fix this!
+    public void testAddCatalogItemWithCircularReference() throws Exception {
+        // Add a catalog item with a circular reference to its own id.
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: brooklyn.entity.basic.BasicEntity",
+                "  version: "+TEST_VERSION,
+                "services:",
+                "- type: brooklyn.entity.basic.BasicApplication",
+                "  brooklyn.config:",
+                "    memberSpec:",
+                "      $brooklyn:entitySpec:",
+                "      - type: brooklyn.entity.basic.BasicApplication",
+                "        brooklyn.children:",
+                "        - type: brooklyn.entity.basic.BasicEntity");
+
+        try {
+            // Use the blueprint from the catalog that has the circular reference.
+            // This should really give a nice error (rather than a StackOverflowError!).
+            addCatalogItems(
+                    "brooklyn.catalog:",
+                    "  id: another.app.in.the.catalog",
+                    "  version: "+TEST_VERSION,
+                    "services:",
+                    "- type: brooklyn.entity.basic.BasicEntity");
+            deleteCatalogEntity("another.app.in.the.catalog");
+        } finally {
+            deleteCatalogEntity("brooklyn.entity.basic.BasicEntity");
+        }
+    }
+}