PercentageEnricher updates

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

Branch: refs/heads/master
Commit: bcad2f0b3944918902fd5b24d6f8968a6782a70b
Parents: 1b7c6be
Author: graeme.miller <[email protected]>
Authored: Wed Jun 29 11:50:53 2016 +0100
Committer: graeme.miller <[email protected]>
Committed: Wed Jun 29 11:50:53 2016 +0100

----------------------------------------------------------------------
 .../enricher/stock/PercentageEnricher.java      | 86 ++++++++----------
 .../enricher/stock/PercentageEnricherTest.java  | 96 +++++++++++++++-----
 .../entity/machine/AddMachineMetrics.java       |  3 +-
 3 files changed, 114 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bcad2f0b/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java 
b/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java
index 9bc7e7e..cd827d9 100644
--- 
a/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java
+++ 
b/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.enricher.stock;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
 import com.google.common.reflect.TypeToken;
 
 import org.apache.brooklyn.api.entity.Entity;
@@ -30,22 +31,38 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.render.RendererHints;
 import org.apache.brooklyn.core.enricher.AbstractEnricher;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.math.MathFunctions;
 
+/**
+ * Enricher that is configured with two numerical sensors; a current and a 
total.
+ * The Enricher subscribes to events from these sensors, and will emit the 
ratio
+ * of current to total as a target sensor.
+ */
 public class PercentageEnricher extends AbstractEnricher implements 
SensorEventListener<Number> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PercentageEnricher.class);
 
-    public static final ConfigKey<AttributeSensor<? extends Number>> 
SOURCE_CURRENT_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<? 
extends Number>>() {
-    }, "enricher.sourceCurrentSensor");
+    @SuppressWarnings("serial")
+    public static final ConfigKey<AttributeSensor<? extends Number>> 
SOURCE_CURRENT_SENSOR = ConfigKeys.newConfigKey(
+            new TypeToken<AttributeSensor<? extends Number>>() {},
+            "enricher.sourceCurrentSensor",
+            "The sensor from which to take the current value");
 
-    public static final ConfigKey<AttributeSensor<? extends Number>> 
SOURCE_TOTAL_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<? 
extends Number>>() {
-    }, "enricher.sourceTotalSensor");
+    @SuppressWarnings("serial")
+    public static final ConfigKey<AttributeSensor<? extends Number>> 
SOURCE_TOTAL_SENSOR = ConfigKeys.newConfigKey(
+            new TypeToken<AttributeSensor<? extends Number>>() {},
+            "enricher.sourceTotalSensor",
+            "The sensor from which to take the total value");
 
-    public static final ConfigKey<AttributeSensor<Double>> TARGET_SENSOR = 
ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<Double>>() {
-    }, "enricher.targetSensor");
+    @SuppressWarnings("serial")
+    public static final ConfigKey<AttributeSensor<Double>> TARGET_SENSOR = 
ConfigKeys.newConfigKey(
+            new TypeToken<AttributeSensor<Double>>() {},
+            "enricher.targetSensor",
+            "The sensor on which to emit the ratio");
 
     public static final ConfigKey<Entity> PRODUCER = 
ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
 
@@ -59,68 +76,41 @@ public class PercentageEnricher extends AbstractEnricher 
implements SensorEventL
     public void setEntity(EntityLocal entity) {
         super.setEntity(entity);
 
-        this.sourceCurrentSensor = getConfig(SOURCE_CURRENT_SENSOR);
-        this.sourceTotalSensor = getConfig(SOURCE_TOTAL_SENSOR);
-        this.targetSensor = getConfig(TARGET_SENSOR);
-        this.producer = getConfig(PRODUCER) == null ? entity : 
getConfig(PRODUCER);
+        sourceCurrentSensor = 
Preconditions.checkNotNull(getConfig(SOURCE_CURRENT_SENSOR), "Can't add 
Enricher %s to entity %s as it has no %s", 
JavaClassNames.simpleClassName(this), entity, SOURCE_CURRENT_SENSOR.getName());
+        sourceTotalSensor = 
Preconditions.checkNotNull(getConfig(SOURCE_TOTAL_SENSOR), "Can't add Enricher 
%s to entity %s as it has no %s", JavaClassNames.simpleClassName(this), entity, 
SOURCE_TOTAL_SENSOR.getName());
+        targetSensor = Preconditions.checkNotNull(getConfig(TARGET_SENSOR), 
"Can't add Enricher %s to entity %s as it has no %s", 
JavaClassNames.simpleClassName(this), entity, TARGET_SENSOR.getName());
+        producer = getConfig(PRODUCER) == null ? entity : getConfig(PRODUCER);
 
-        if (sourceCurrentSensor == null) {
-            throw new IllegalArgumentException("Enricher " + 
JavaClassNames.simpleClassName(this) + " has no " + 
SOURCE_CURRENT_SENSOR.getName());
-        }
-        if (sourceTotalSensor == null) {
-            throw new IllegalArgumentException("Enricher " + 
JavaClassNames.simpleClassName(this) + " has no " + 
SOURCE_TOTAL_SENSOR.getName());
+        if (targetSensor.equals(sourceCurrentSensor) && 
entity.equals(producer)) {
+            throw new IllegalArgumentException("Can't add Enricher " + 
JavaClassNames.simpleClassName(this) + " to entity "+entity+" as cycle detected 
with " + SOURCE_CURRENT_SENSOR.getName());
         }
-        if (targetSensor == null) {
-            throw new IllegalArgumentException("Enricher " + 
JavaClassNames.simpleClassName(this) + " has no " + TARGET_SENSOR.getName());
-        }
-
-        if (targetSensor.equals(sourceCurrentSensor)) {
-            throw new IllegalArgumentException("Enricher " + 
JavaClassNames.simpleClassName(this) + " detect cycle with " + 
SOURCE_CURRENT_SENSOR.getName());
-        }
-        if (targetSensor.equals(sourceTotalSensor)) {
-            throw new IllegalArgumentException("Enricher " + 
JavaClassNames.simpleClassName(this) + " detect cycle with " + 
SOURCE_TOTAL_SENSOR.getName());
+        if (targetSensor.equals(sourceTotalSensor) && entity.equals(producer)) 
{
+            throw new IllegalArgumentException("Can't add Enricher " + 
JavaClassNames.simpleClassName(this) + " to entity "+entity+" as cycle detected 
with " + SOURCE_TOTAL_SENSOR.getName());
         }
 
         subscriptions().subscribe(MutableMap.of("notifyOfInitialValue", true), 
producer, sourceCurrentSensor, this);
         subscriptions().subscribe(MutableMap.of("notifyOfInitialValue", true), 
producer, sourceTotalSensor, this);
-
+        RendererHints.register(targetSensor, 
RendererHints.displayValue(MathFunctions.percent(2)));
     }
 
     @Override
     public void onEvent(SensorEvent<Number> event) {
-        Number current = producer.sensors().get(sourceCurrentSensor);
-        Number total = producer.sensors().get(sourceTotalSensor);
-        Double result = null;
-
-        if (current == null) {
-            LOG.debug("Current is null, returning");
-            return;
-        }
-
-        if (total == null || total.equals(0)) {
-            LOG.debug("total {" + total + "} is null or zero, returning");
-            return;
-        }
-
+        Number current = 
Preconditions.checkNotNull(producer.sensors().get(sourceCurrentSensor), "Can't 
calculate Enricher %s value for entity %s as current from producer %s is null", 
JavaClassNames.simpleClassName(this), entity, producer);
+        Number total = 
Preconditions.checkNotNull(producer.sensors().get(sourceTotalSensor),     
"Can't calculate Enricher %s value for entity %s as total from producer %s is 
null", JavaClassNames.simpleClassName(this), entity, producer);
         Double currentDouble = current.doubleValue();
         Double totalDouble = total.doubleValue();
 
-        if (currentDouble > totalDouble) {
-            LOG.debug("Current is greater than total, returning");
+        if (totalDouble.compareTo(0d) == 0) {
+            LOG.debug("Can't calculate Enricher ({}) value for entity ({}) as 
total from producer ({}) is zero", new 
Object[]{JavaClassNames.simpleClassName(this), entity, producer});
             return;
         }
 
         if (currentDouble < 0 || totalDouble < 0) {
-            LOG.debug("Current {"+currentDouble+"}  or total {"+totalDouble+"} 
is negative, returning");
+            LOG.debug("Can't calculate Enricher ({}) value for entity ({}) as 
Current ({})  or total ({}) value from producer ({}) is negative, returning", 
new Object[]{JavaClassNames.simpleClassName(this), entity, currentDouble, 
totalDouble, producer});
             return;
         }
 
-        if (current.equals(0)) {
-            LOG.debug("current is zero, setting percent to zero");
-            result = 0d;
-        } else {
-            result = currentDouble / totalDouble;
-        }
+        Double result = currentDouble / totalDouble;
 
         emit(targetSensor, result);
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bcad2f0b/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
 
b/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
index 575970f..a3b6d17 100644
--- 
a/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
@@ -18,8 +18,6 @@
  */
 package org.apache.brooklyn.enricher.stock;
 
-import static org.testng.Assert.assertEquals;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
@@ -27,15 +25,15 @@ import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
+import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.entity.EntityAsserts;
 import org.apache.brooklyn.core.location.SimulatedLocation;
 import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
 import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
 
 public class PercentageEnricherTest extends BrooklynAppUnitTestSupport {
 
@@ -69,7 +67,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 50d);
         app.sensors().set(totalSensor, 100d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
     }
 
     @Test
@@ -123,7 +121,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 50d);
         app.sensors().set(totalSensor, 25d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 2.0d);
     }
 
     @Test
@@ -132,7 +130,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 50d);
         app.sensors().set(totalSensor, 50d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 1.0d);
     }
 
     @Test
@@ -168,37 +166,80 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, Double.MAX_VALUE);
         app.sensors().set(totalSensor, Double.MAX_VALUE);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 1.0d);
     }
 
-    //SETUP TESTS
-    @Test(expectedExceptions = IllegalArgumentException.class)
+
+    @Test(expectedExceptions = NullPointerException.class)
     public void totalNoCurrentSensor() {
         app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
                 .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
                 .configure(PercentageEnricher.TARGET_SENSOR, targetSensor));
     }
 
-    @Test(expectedExceptions = IllegalArgumentException.class)
+    @Test(expectedExceptions = NullPointerException.class)
     public void totalNoTotalSensor() {
         app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
                 .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
                 .configure(PercentageEnricher.TARGET_SENSOR, targetSensor));
     }
 
-    @Test(expectedExceptions = IllegalArgumentException.class)
+    @Test(expectedExceptions = NullPointerException.class)
     public void totalNoTargetSensor() {
         app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
                 .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
                 .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, 
totalSensor));
     }
 
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testTotalCycleNoProducer() {
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, totalSensor));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testCurrentCycleNoProducer() {
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, currentSensor));
+    }
+
     @Test
-    public void testDifferentProducer() {
-        EntitySpec<TestApplication> appSpec = 
EntitySpec.create(TestApplication.class)
-                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
shouldSkipOnBoxBaseDirResolution());
+    public void testNoCycleDifferentProducerTotal() {
+        Entity producer = app.addChild(EntitySpec.create(TestEntity.class));
 
-        TestApplication producer = 
mgmt.getEntityManager().createEntity(appSpec);
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, totalSensor)
+                .configure(PercentageEnricher.PRODUCER, producer));
+
+        producer.sensors().set(currentSensor, 25d);
+        producer.sensors().set(totalSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, totalSensor, 0.5d);
+    }
+
+    @Test
+    public void testNoCycleDifferentProducerCurrent() {
+        Entity producer = app.addChild(EntitySpec.create(TestEntity.class));
+
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, currentSensor)
+                .configure(PercentageEnricher.PRODUCER, producer));
+
+        producer.sensors().set(currentSensor, 25d);
+        producer.sensors().set(totalSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, currentSensor, 
0.5d);
+    }
+
+    @Test
+    public void testDifferentProducer() {
+        Entity producer = app.addChild(EntitySpec.create(TestEntity.class));
 
         app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
                 .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
currentSensor)
@@ -209,7 +250,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         producer.sensors().set(currentSensor, 25d);
         producer.sensors().set(totalSensor, 50d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
         EntityAsserts.assertAttributeEqualsEventually(producer, targetSensor, 
null);
     }
 
@@ -226,7 +267,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 25l);
         app.sensors().set(totalSensor, 50l);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
     }
 
     @Test
@@ -242,7 +283,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 25);
         app.sensors().set(totalSensor, 50);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
     }
 
     @Test
@@ -258,7 +299,7 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 25f);
         app.sensors().set(totalSensor, 50f);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
     }
 
     @Test
@@ -267,9 +308,20 @@ public class PercentageEnricherTest extends 
BrooklynAppUnitTestSupport {
 
         app.sensors().set(currentSensor, 50d);
         app.sensors().set(totalSensor, 100d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
         app.sensors().set(totalSensor, 0d);
-        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
+    }
+
+    @Test
+    public void validThenNull() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
+        app.sensors().set(totalSensor, null);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0.5d);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bcad2f0b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
index a61d4ee..a310e8a 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
@@ -81,7 +81,8 @@ public class AddMachineMetrics implements EntityInitializer {
         entity.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
                 .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, 
MachineAttributes.USED_MEMORY)
                 .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, 
MachineAttributes.TOTAL_MEMORY)
-                .configure(PercentageEnricher.TARGET_SENSOR, 
MachineAttributes.USED_MEMORY_PERCENT));
+                .configure(PercentageEnricher.TARGET_SENSOR, 
MachineAttributes.USED_MEMORY_PERCENT)
+                .configure(PercentageEnricher.SUPPRESS_DUPLICATES, true));
 
     }
 

Reply via email to