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 2016/07/04 20:27:56 UTC

[1/3] brooklyn-server git commit: Added a percentage enricher

Repository: brooklyn-server
Updated Branches:
  refs/heads/master c7731a4fa -> a58ba05c7


Added a percentage enricher


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

Branch: refs/heads/master
Commit: 1b7c6be62592421ea2144a6bd15a0c635bf544a2
Parents: a941963
Author: graeme.miller <gr...@cloudsoftcorp.com>
Authored: Thu Jun 23 14:34:21 2016 +0100
Committer: graeme.miller <gr...@cloudsoftcorp.com>
Committed: Fri Jun 24 14:16:45 2016 +0100

----------------------------------------------------------------------
 .../enricher/stock/PercentageEnricher.java      | 127 +++++++++
 .../enricher/stock/PercentageEnricherTest.java  | 275 +++++++++++++++++++
 .../entity/machine/AddMachineMetrics.java       |   8 +
 .../entity/machine/MachineAttributes.java       |   6 +
 4 files changed, 416 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1b7c6be6/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
new file mode 100644
index 0000000..9bc7e7e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/PercentageEnricher.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.enricher.stock;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.reflect.TypeToken;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+
+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");
+
+    public static final ConfigKey<AttributeSensor<? extends Number>> SOURCE_TOTAL_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<? extends Number>>() {
+    }, "enricher.sourceTotalSensor");
+
+    public static final ConfigKey<AttributeSensor<Double>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<Double>>() {
+    }, "enricher.targetSensor");
+
+    public static final ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
+
+    protected AttributeSensor<? extends Number> sourceCurrentSensor;
+    protected AttributeSensor<? extends Number> sourceTotalSensor;
+    protected AttributeSensor<Double> targetSensor;
+    protected Entity producer;
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    @Override
+    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);
+
+        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 == 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());
+        }
+
+        subscriptions().subscribe(MutableMap.of("notifyOfInitialValue", true), producer, sourceCurrentSensor, this);
+        subscriptions().subscribe(MutableMap.of("notifyOfInitialValue", true), producer, sourceTotalSensor, this);
+
+    }
+
+    @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;
+        }
+
+        Double currentDouble = current.doubleValue();
+        Double totalDouble = total.doubleValue();
+
+        if (currentDouble > totalDouble) {
+            LOG.debug("Current is greater than total, returning");
+            return;
+        }
+
+        if (currentDouble < 0 || totalDouble < 0) {
+            LOG.debug("Current {"+currentDouble+"}  or total {"+totalDouble+"} is negative, returning");
+            return;
+        }
+
+        if (current.equals(0)) {
+            LOG.debug("current is zero, setting percent to zero");
+            result = 0d;
+        } else {
+            result = currentDouble / totalDouble;
+        }
+
+        emit(targetSensor, result);
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1b7c6be6/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
new file mode 100644
index 0000000..575970f
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/PercentageEnricherTest.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.enricher.stock;
+
+import static org.testng.Assert.assertEquals;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+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;
+
+public class PercentageEnricherTest extends BrooklynAppUnitTestSupport {
+
+    public static final Logger log = LoggerFactory.getLogger(PercentageEnricherTest.class);
+
+    AttributeSensor<Double> currentSensor;
+    AttributeSensor<Double> totalSensor;
+    AttributeSensor<Double> targetSensor;
+
+    @BeforeMethod(alwaysRun = true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        currentSensor = new BasicAttributeSensor<Double>(Double.class, "current");
+        totalSensor = new BasicAttributeSensor<Double>(Double.class, "total");
+        targetSensor = new BasicAttributeSensor<Double>(Double.class, "target");
+
+        app.start(ImmutableList.of(new SimulatedLocation()));
+    }
+
+    private void addEnricher() {
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, targetSensor));
+    }
+
+    @Test
+    public void vanillaTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+    }
+
+    @Test
+    public void currentNullTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, null);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void totalNullTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, null);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void bothInputNullTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, null);
+        app.sensors().set(totalSensor, null);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void currentZeroTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 0d);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 0d);
+    }
+
+    @Test
+    public void totalZeroTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 0d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void totalLessThanCurrentTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 25d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void oneHundredPercentTest() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 100d);
+    }
+
+    @Test
+    public void negativeCurrent() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, -50d);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void negativeTotal() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, -100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void bothSourceNegative() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, -50d);
+        app.sensors().set(totalSensor, -100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, null);
+    }
+
+    @Test
+    public void totalDoubleMaxValue() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, Double.MAX_VALUE);
+        app.sensors().set(totalSensor, Double.MAX_VALUE);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 100d);
+    }
+
+    //SETUP TESTS
+    @Test(expectedExceptions = IllegalArgumentException.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)
+    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)
+    public void totalNoTargetSensor() {
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor));
+    }
+
+    @Test
+    public void testDifferentProducer() {
+        EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class)
+                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution());
+
+        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, targetSensor)
+                .configure(PercentageEnricher.PRODUCER, producer)
+        );
+
+        producer.sensors().set(currentSensor, 25d);
+        producer.sensors().set(totalSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        EntityAsserts.assertAttributeEqualsEventually(producer, targetSensor, null);
+    }
+
+    @Test
+    public void testLong() {
+        AttributeSensor<Long> currentSensor = new BasicAttributeSensor<Long>(Long.class, "current");
+        AttributeSensor<Long> totalSensor = new BasicAttributeSensor<Long>(Long.class, "total");
+
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, targetSensor)
+        );
+
+        app.sensors().set(currentSensor, 25l);
+        app.sensors().set(totalSensor, 50l);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+    }
+
+    @Test
+    public void testInteger() {
+        AttributeSensor<Integer> currentSensor = new BasicAttributeSensor<Integer>(Integer.class, "current");
+        AttributeSensor<Integer> totalSensor = new BasicAttributeSensor<Integer>(Integer.class, "total");
+
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, targetSensor)
+        );
+
+        app.sensors().set(currentSensor, 25);
+        app.sensors().set(totalSensor, 50);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+    }
+
+    @Test
+    public void testFloat() {
+        AttributeSensor<Float> currentSensor = new BasicAttributeSensor<Float>(Float.class, "current");
+        AttributeSensor<Float> totalSensor = new BasicAttributeSensor<Float>(Float.class, "total");
+
+        app.enrichers().add(EnricherSpec.create(PercentageEnricher.class)
+                .configure(PercentageEnricher.SOURCE_CURRENT_SENSOR, currentSensor)
+                .configure(PercentageEnricher.SOURCE_TOTAL_SENSOR, totalSensor)
+                .configure(PercentageEnricher.TARGET_SENSOR, targetSensor)
+        );
+
+        app.sensors().set(currentSensor, 25f);
+        app.sensors().set(totalSensor, 50f);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+    }
+
+    @Test
+    public void validThenInvalid() {
+        addEnricher();
+
+        app.sensors().set(currentSensor, 50d);
+        app.sensors().set(totalSensor, 100d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+        app.sensors().set(totalSensor, 0d);
+        EntityAsserts.assertAttributeEqualsEventually(app, targetSensor, 50d);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1b7c6be6/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 e118b93..a61d4ee 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
@@ -35,6 +35,8 @@ import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.sensor.EnricherSpec;
 import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.enricher.stock.PercentageEnricher;
+import org.apache.brooklyn.enricher.stock.Transformer;
 import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher;
 import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
@@ -75,6 +77,12 @@ public class AddMachineMetrics implements EntityInitializer {
         entity.enrichers().add(EnricherSpec.create(YamlRollingTimeWindowMeanEnricher.class)
                 .configure(YamlRollingTimeWindowMeanEnricher.SOURCE_SENSOR, MachineAttributes.USED_MEMORY_DELTA_PER_SECOND_LAST)
                 .configure(YamlRollingTimeWindowMeanEnricher.TARGET_SENSOR, MachineAttributes.USED_MEMORY_DELTA_PER_SECOND_IN_WINDOW));
+
+        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));
+
     }
 
     public static SshFeed createMachineMetricsFeed(EntityLocal entity) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1b7c6be6/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
index ff3ef86..fc852b6 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
@@ -56,6 +56,9 @@ public class MachineAttributes {
     public static final AttributeSensor<Double> USED_MEMORY_DELTA_PER_SECOND_LAST = Sensors.newDoubleSensor("memory.used.delta", "Change in memory usage per second");
     public static final AttributeSensor<Double> USED_MEMORY_DELTA_PER_SECOND_IN_WINDOW = Sensors.newDoubleSensor("memory.used.windowed", "Average change in memory usage over 30s");
 
+    public static final AttributeSensor<Double> USED_MEMORY_PERCENT = Sensors.newDoubleSensor("memory.used.percent", "The percentage of memory used");
+    public static final AttributeSensor<Double> AVERAGE_USED_MEMORY_PERCENT = Sensors.newDoubleSensor("memory.used.percent.average", "Average percentage of memory used across the cluster");
+
     private static AtomicBoolean initialized = new AtomicBoolean(false);
 
     /**
@@ -75,6 +78,9 @@ public class MachineAttributes {
         RendererHints.register(CPU_USAGE, RendererHints.displayValue(MathFunctions.percent(2)));
         RendererHints.register(AVERAGE_CPU_USAGE, RendererHints.displayValue(MathFunctions.percent(2)));
 
+        RendererHints.register(USED_MEMORY_PERCENT, RendererHints.displayValue(MathFunctions.percent(2)));
+        RendererHints.register(AVERAGE_USED_MEMORY_PERCENT, RendererHints.displayValue(MathFunctions.percent(2)));
+
         RendererHints.register(FREE_MEMORY, RendererHints.displayValue(Functionals.chain(MathFunctions.times(1000L), ByteSizeStrings.metric())));
         RendererHints.register(TOTAL_MEMORY, RendererHints.displayValue(Functionals.chain(MathFunctions.times(1000L), ByteSizeStrings.metric())));
         RendererHints.register(USED_MEMORY, RendererHints.displayValue(Functionals.chain(MathFunctions.times(1000L), ByteSizeStrings.metric())));


[2/3] brooklyn-server git commit: PercentageEnricher updates

Posted by al...@apache.org.
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 <gr...@cloudsoftcorp.com>
Authored: Wed Jun 29 11:50:53 2016 +0100
Committer: graeme.miller <gr...@cloudsoftcorp.com>
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));
 
     }
 


[3/3] brooklyn-server git commit: This closes #220

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


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

Branch: refs/heads/master
Commit: a58ba05c7b7e621b22a6fa83410b4cea8f1a7f7e
Parents: c7731a4 bcad2f0
Author: Aled Sage <al...@gmail.com>
Authored: Mon Jul 4 21:27:03 2016 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Jul 4 21:27:03 2016 +0100

----------------------------------------------------------------------
 .../enricher/stock/PercentageEnricher.java      | 117 +++++++
 .../enricher/stock/PercentageEnricherTest.java  | 327 +++++++++++++++++++
 .../entity/machine/AddMachineMetrics.java       |   9 +
 .../entity/machine/MachineAttributes.java       |   6 +
 4 files changed, 459 insertions(+)
----------------------------------------------------------------------