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/04/23 16:05:40 UTC

[1/3] incubator-brooklyn git commit: Ignore non-RUNNING children in SERVICE_UP quorum calculation

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 7b97cee1e -> 7a126a140


Ignore non-RUNNING children in SERVICE_UP quorum calculation


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

Branch: refs/heads/master
Commit: bc8eb2664a2170c7e1ebd797e7ba48dda492039d
Parents: 2a6d9fd
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Apr 22 14:41:32 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Apr 22 14:50:00 2015 +0300

----------------------------------------------------------------------
 .../entity/basic/ServiceStateLogic.java         | 13 ++++++---
 .../entity/basic/ServiceStateLogicTest.java     | 28 +++++++++++++-------
 2 files changed, 28 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bc8eb266/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 d8fc957..cfabf1b 100644
--- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
+++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
@@ -180,7 +180,6 @@ public class ServiceStateLogic {
         /** static only; not for instantiation */
         private ServiceNotUpLogic() {}
         
-        @SuppressWarnings({ "unchecked", "rawtypes" })
         public static final EnricherSpec<?> newEnricherForServiceUpIfNotUpIndicatorsEmpty() {
             return Enrichers.builder()
                 .transforming(SERVICE_NOT_UP_INDICATORS).<Object>publishing(Attributes.SERVICE_UP)
@@ -247,6 +246,7 @@ public class ServiceStateLogic {
             if (uniqueTag==null) uniqueTag = DEFAULT_ENRICHER_UNIQUE_TAG;
         }
         
+        @Override
         public void setEntity(EntityLocal entity) {
             super.setEntity(entity);
             if (suppressDuplicates==null) {
@@ -409,11 +409,13 @@ public class ServiceStateLogic {
             Preconditions.checkNotNull(getKeyForMapSensor());
         }
 
+        @Override
         protected void setEntityLoadingTargetConfig() {
             if (getConfig(TARGET_SENSOR)!=null)
                 throw new IllegalArgumentException("Must not set "+TARGET_SENSOR+" when using "+this);
         }
 
+        @Override
         public void setEntity(EntityLocal entity) {
             super.setEntity(entity);
             if (suppressDuplicates==null) {
@@ -472,19 +474,24 @@ public class ServiceStateLogic {
             Map<Entity, Boolean> values = getValues(SERVICE_UP);
             List<Entity> violators = MutableList.of();
             boolean ignoreNull = getConfig(IGNORE_ENTITIES_WITH_SERVICE_UP_NULL);
+            Set<Lifecycle> ignoreStates = getConfig(IGNORE_ENTITIES_WITH_THESE_SERVICE_STATES);
             int entries=0;
+            int numUp=0;
             for (Map.Entry<Entity, Boolean> state: values.entrySet()) {
                 if (ignoreNull && state.getValue()==null)
                     continue;
                 entries++;
-                if (!Boolean.TRUE.equals(state.getValue())) {
+                Lifecycle entityState = state.getKey().getAttribute(SERVICE_STATE_ACTUAL);
+                
+                if (Boolean.TRUE.equals(state.getValue())) numUp++;
+                else if (!ignoreStates.contains(entityState)) {
                     violators.add(state.getKey());
                 }
             }
 
             QuorumCheck qc = getConfig(UP_QUORUM_CHECK);
             if (qc!=null) {
-                if (qc.isQuorate(entries-violators.size(), entries))
+                if (qc.isQuorate(numUp, violators.size()+numUp))
                     // quorate
                     return null;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bc8eb266/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
index d30b05a..0c16632 100644
--- a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
@@ -24,9 +24,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Entity;
-import brooklyn.entity.Group;
 import brooklyn.entity.basic.EntitySubscriptionTest.RecordingSensorEventListener;
-import brooklyn.entity.basic.QuorumCheck.QuorumChecks;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
@@ -40,6 +38,7 @@ import brooklyn.policy.Enricher;
 import brooklyn.test.EntityTestUtils;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
+import brooklyn.util.collections.QuorumCheck.QuorumChecks;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
 
@@ -57,6 +56,7 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
 
     protected TestEntity entity;
 
+    @Override
     protected void setUpApp() {
         super.setUpApp();
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
@@ -165,13 +165,21 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, true);
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
         
-        // if we then put a not-up indicator on the TestEntity, it publishes false, so app also is false, and thus stopped
+        // if we then put a not-up indicator on the TestEntity, it publishes false, but app is still up. State
+        // won't propagate due to it's SERVICE_STATE_ACTUAL (null) being in IGNORE_ENTITIES_WITH_THESE_SERVICE_STATES
         ServiceNotUpLogic.updateNotUpIndicator(entity, INDICATOR_KEY_1, "We're also pretending to block service up");
         assertAttributeEqualsEventually(entity, Attributes.SERVICE_UP, false);
+        assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, true);
+        assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+        // the entity still has no opinion about its state
+        assertAttributeEqualsEventually(entity, Attributes.SERVICE_STATE_ACTUAL, null);
+        
+        // switching the entity state to one not in IGNORE_ENTITIES_WITH_THESE_SERVICE_STATES will propagate the up state
+        ServiceStateLogic.setExpectedState(entity, Lifecycle.RUNNING);
+        assertAttributeEqualsEventually(entity, Attributes.SERVICE_UP, false);
         assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, false);
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
-        // but the entity still has no opinion about its state
-        assertAttributeEqualsEventually(entity, Attributes.SERVICE_STATE_ACTUAL, null);
+
         
         // if the entity expects to be stopped, it will report stopped
         ServiceStateLogic.setExpectedState(entity, Lifecycle.STOPPED);
@@ -191,7 +199,7 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         // if we change the state quorum check for the app to be "all are healthy and at least one running" *then* it shows stopped
         // (normally this would be done in `initEnrichers` of course)
         Enricher appChildrenBasedEnricher = EntityAdjuncts.tryFindWithUniqueTag(app.getEnrichers(), ComputeServiceIndicatorsFromChildrenAndMembers.DEFAULT_UNIQUE_TAG).get();
-        appChildrenBasedEnricher.setConfig(ComputeServiceIndicatorsFromChildrenAndMembers.RUNNING_QUORUM_CHECK, QuorumChecks.allAndAtLeastOne());
+        appChildrenBasedEnricher.config().set(ComputeServiceIndicatorsFromChildrenAndMembers.RUNNING_QUORUM_CHECK, QuorumChecks.allAndAtLeastOne());
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
         
         // if entity is expected running, then it will show running because service is up; this is reflected at app and at entity
@@ -207,7 +215,7 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         assertAttributeEqualsContinually(app, Attributes.SERVICE_UP, true);
         
         // if we change its up-quorum to atLeastOne then state becomes stopped (because there is no expected state; has not been started)
-        appChildrenBasedEnricher.setConfig(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, QuorumChecks.atLeastOne());
+        appChildrenBasedEnricher.config().set(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, QuorumChecks.atLeastOne());
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
         assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, false);
         
@@ -218,7 +226,7 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
         
         // restoring up-quorum to "atLeastOneUnlessEmpty" causes it to become RUNNING, because happy with empty
-        appChildrenBasedEnricher.setConfig(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, QuorumChecks.atLeastOneUnlessEmpty());
+        appChildrenBasedEnricher.config().set(ComputeServiceIndicatorsFromChildrenAndMembers.UP_QUORUM_CHECK, QuorumChecks.atLeastOneUnlessEmpty());
         assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, true);
         // but running-quorum is still allAndAtLeastOne, so remains on-fire
         assertAttributeEqualsContinually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
@@ -229,13 +237,13 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         assertAttributeEqualsContinually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
         
         // tell it not to ignore null values for children states, and it will go onfire (but still be service up)
-        appChildrenBasedEnricher.setConfig(ComputeServiceIndicatorsFromChildrenAndMembers.IGNORE_ENTITIES_WITH_THESE_SERVICE_STATES, 
+        appChildrenBasedEnricher.config().set(ComputeServiceIndicatorsFromChildrenAndMembers.IGNORE_ENTITIES_WITH_THESE_SERVICE_STATES, 
             ImmutableSet.<Lifecycle>of());
         assertAttributeEqualsEventually(app, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
         assertAttributeEquals(app, Attributes.SERVICE_UP, true);
         
         // tell it not to ignore null values for service up and it will go service down
-        appChildrenBasedEnricher.setConfig(ComputeServiceIndicatorsFromChildrenAndMembers.IGNORE_ENTITIES_WITH_SERVICE_UP_NULL, false);
+        appChildrenBasedEnricher.config().set(ComputeServiceIndicatorsFromChildrenAndMembers.IGNORE_ENTITIES_WITH_SERVICE_UP_NULL, false);
         assertAttributeEqualsEventually(app, Attributes.SERVICE_UP, false);
         
         // set the entity to RUNNING and the app will be healthy again


[3/3] incubator-brooklyn git commit: This closes #609

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


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

Branch: refs/heads/master
Commit: 7a126a140f3ced112ea8ba11a1293df7c5fe3d2c
Parents: 7b97cee bc8eb26
Author: Aled Sage <al...@gmail.com>
Authored: Thu Apr 23 15:05:12 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Apr 23 15:05:12 2015 +0100

----------------------------------------------------------------------
 .../basic/AbstractMultipleSensorAggregator.java | 22 ++++++-
 .../entity/basic/ServiceStateLogic.java         | 13 ++++-
 .../entity/basic/ServiceStateLogicTest.java     | 60 ++++++++++++++++----
 3 files changed, 80 insertions(+), 15 deletions(-)
----------------------------------------------------------------------



[2/3] incubator-brooklyn git commit: Coerce aggregated values, might be coming from string sources

Posted by al...@apache.org.
Coerce aggregated values, might be coming from string sources

Caller code expects values to be in the sensor type, coerce the values before returning them. String values could be inserted - for example from BrooklynEntityMirror.


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

Branch: refs/heads/master
Commit: 2a6d9fd566f90a4fb8e6f67815d9e50f7bb78e63
Parents: ff31a41
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Apr 21 17:10:16 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Apr 22 14:50:00 2015 +0300

----------------------------------------------------------------------
 .../basic/AbstractMultipleSensorAggregator.java | 22 +++++++++++--
 .../entity/basic/ServiceStateLogicTest.java     | 34 +++++++++++++++++++-
 2 files changed, 53 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a6d9fd5/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java b/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java
index b40c234..793d8a9 100644
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractMultipleSensorAggregator.java
@@ -20,8 +20,10 @@ package brooklyn.enricher.basic;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,6 +35,7 @@ import brooklyn.event.Sensor;
 import brooklyn.event.SensorEvent;
 import brooklyn.event.SensorEventListener;
 import brooklyn.util.collections.MutableMap;
+import brooklyn.util.flags.TypeCoercions;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
@@ -138,11 +141,26 @@ public abstract class AbstractMultipleSensorAggregator<U> extends AbstractAggreg
         onUpdated();
     }
 
-    @SuppressWarnings("unchecked")
     public <T> Map<Entity,T> getValues(Sensor<T> sensor) {
+        Map<Entity, T> valuesCopy = copyValues(sensor);
+        return coerceValues(valuesCopy, sensor.getType());
+    }
+
+    private <T> Map<Entity, T> coerceValues(Map<Entity, T> values, Class<? super T> type) {
+        Map<Entity, T> typedValues = MutableMap.of();
+        for (Entry<Entity, T> entry : values.entrySet()) {
+            @SuppressWarnings("unchecked")
+            T typedValue = (T) TypeCoercions.coerce(entry.getValue(), type);
+            typedValues.put(entry.getKey(), typedValue);
+        }
+        return typedValues;
+    }
+
+    private <T> Map<Entity, T> copyValues(Sensor<T> sensor) {
         synchronized (values) {
+            @SuppressWarnings("unchecked")
             Map<Entity, T> sv = (Map<Entity, T>) values.get(sensor.getName());
-            if (sv==null) return ImmutableMap.of();
+            //use MutableMap because of potentially null values
             return MutableMap.copyOf(sv).asUnmodifiable();
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a6d9fd5/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
index 00dd322..d30b05a 100644
--- a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
@@ -24,16 +24,22 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Entity;
+import brooklyn.entity.Group;
+import brooklyn.entity.basic.EntitySubscriptionTest.RecordingSensorEventListener;
 import brooklyn.entity.basic.QuorumCheck.QuorumChecks;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
+import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
 import brooklyn.location.Location;
+import brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.Enricher;
 import brooklyn.test.EntityTestUtils;
 import brooklyn.test.entity.TestEntity;
+import brooklyn.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
 
@@ -240,7 +246,33 @@ public class ServiceStateLogicTest extends BrooklynAppUnitTestSupport {
         assertAttributeEquals(entity, Attributes.SERVICE_UP, true);
         assertAttributeEquals(entity, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
     }
-        
+
+    @Test
+    public void testQuorumWithStringStates() {
+        final DynamicCluster cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(TestEntityWithoutEnrichers.class))
+                .configure(DynamicCluster.INITIAL_SIZE, 1));
+
+        RecordingSensorEventListener r = new RecordingSensorEventListener();
+        app.subscribe(cluster, Attributes.SERVICE_STATE_ACTUAL, r);
+
+        cluster.start(ImmutableList.of(new SimulatedLocation()));
+        EntityTestUtils.assertGroupSizeEqualsEventually(cluster, 1);
+
+        //manually set state to healthy as enrichers are disabled
+        EntityInternal child = (EntityInternal) cluster.getMembers().iterator().next();
+        child.setAttribute(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+        child.setAttribute(Attributes.SERVICE_UP, Boolean.TRUE);
+
+        EntityTestUtils.assertAttributeEqualsEventually(cluster, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+
+        //set untyped service state, the quorum check should be able to handle coercion
+        AttributeSensor<Object> stateSensor = Sensors.newSensor(Object.class, Attributes.SERVICE_STATE_ACTUAL.getName());
+        child.setAttribute(stateSensor, "running");
+
+        EntityTestUtils.assertAttributeEqualsContinually(cluster, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+    }
+
     private static <T> void assertAttributeEqualsEventually(Entity x, AttributeSensor<T> sensor, T value) {
         try {
             EntityTestUtils.assertAttributeEqualsEventually(ImmutableMap.of("timeout", Duration.seconds(3)), x, sensor, value);