You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by tb...@apache.org on 2017/12/21 14:23:10 UTC

[1/3] brooklyn-server git commit: BROOKLYN-569: log.warn once when aggregating non-number

Repository: brooklyn-server
Updated Branches:
  refs/heads/master ca82123c8 -> b65451764


BROOKLYN-569: log.warn once when aggregating non-number

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

Branch: refs/heads/master
Commit: e7238512451359fbe3ac2dc2aa9568cee719868b
Parents: f78cc06
Author: Aled Sage <al...@gmail.com>
Authored: Thu Dec 21 09:31:26 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Dec 21 09:31:38 2017 +0000

----------------------------------------------------------------------
 .../enricher/stock/MathAggregatorFunctions.java | 24 ++++++++++--
 .../stock/MathAggregatorFunctionsTest.java      | 40 ++++++++++++++++++++
 .../org/apache/brooklyn/test/LogWatcher.java    |  6 +++
 3 files changed, 67 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e7238512/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
index c8509d5..8efa427 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
@@ -114,6 +114,8 @@ public class MathAggregatorFunctions {
 
     @Beta
     protected abstract static class BasicComputingNumber<T extends Number> extends AbstractComputingNumber<T> {
+        private boolean loggedNonNumber;
+        
         public BasicComputingNumber(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
             super(defaultValueForUnreportedSensors, valueToReportIfNoSensors, typeToken);
         }
@@ -122,18 +124,34 @@ public class MathAggregatorFunctions {
         public T apply(@Nullable Collection<? extends Number> vals) {
             List<Number> postProcessedVals = new ArrayList<>();
             int count = 0;
+            boolean hasNonNumber = false;
             if (vals != null) {
                 for (Object val : vals) {
                     Maybe<Number> coercedVal = TypeCoercions.tryCoerce(val, Number.class);
                     if (coercedVal.isPresentAndNonNull()) {
                         postProcessedVals.add(coercedVal.get());
                         count++;
-                    } else if (defaultValueForUnreportedSensors != null) {
-                        postProcessedVals.add(defaultValueForUnreportedSensors);
-                        count++;
+                    } else {
+                        if (val != null) {
+                            // This function is used for example in an enricher, to compute an aggregated value.
+                            // Log at warn only once per enricher if we have a non-number; but if things go back to healthy
+                            // (i.e. no non-numbers) then we'll log again at warn next time.
+                            hasNonNumber = true;
+                            if (loggedNonNumber) {
+                                if (LOG.isTraceEnabled()) LOG.trace("Input to numeric aggregator is not a number (again): "+val+" ("+val.getClass()+")");
+                            } else {
+                                loggedNonNumber = true;
+                                LOG.warn("Input to numeric aggregator is not a number: "+val+" ("+val.getClass()+")");
+                            }
+                        }
+                        if (defaultValueForUnreportedSensors != null) {
+                            postProcessedVals.add(defaultValueForUnreportedSensors);
+                            count++;
+                        }
                     }
                 }
             }
+            if (!hasNonNumber) loggedNonNumber = false;
             if (count==0) return cast(valueToReportIfNoSensors, typeToken);
             
             Number result = applyImpl(postProcessedVals);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e7238512/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
index d07b0db..16ef9d5 100644
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
@@ -18,13 +18,17 @@
  */
 package org.apache.brooklyn.enricher.stock;
 
+import static org.apache.brooklyn.test.LogWatcher.EventPredicates.containsMessage;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.brooklyn.test.LogWatcher;
 import org.apache.brooklyn.util.collections.MutableList;
+import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Function;
@@ -98,6 +102,42 @@ public class MathAggregatorFunctionsTest {
         assertEquals(func.apply(input), (Integer)5);
     }
     
+    // See https://issues.apache.org/jira/browse/BROOKLYN-569
+    @Test
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void testTryCastInputValuesWhenNotNumbers() throws Exception {
+        Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class);
+        
+        final LogWatcher watcher = new LogWatcher(
+                ImmutableList.of(LoggerFactory.getLogger(MathAggregatorFunctions.class).getName()),
+                ch.qos.logback.classic.Level.WARN,
+                containsMessage("Input to numeric aggregator is not a number"));
+
+        watcher.start();
+        try {
+            // Sums only things that can be numbers, ingnoring others; logs non-numbers only once
+            List<Number> inputWithNonNumber = (List<Number>) (List) MutableList.<Object>of(1, null, "not a number", "4", true);
+            for (int i = 0; i < 2; i++) {
+                assertEquals(func.apply(inputWithNonNumber), (Integer)5);
+            }
+            assertEquals(watcher.getEvents().size(), 1, "events="+watcher.getEvents());
+
+            // Summing only numbers resets the flag, so we'll be willing to log again
+            watcher.clearEvents();
+            assertEquals(func.apply(ImmutableList.of(1, 4)), (Integer)5);
+            assertTrue(watcher.getEvents().isEmpty(), "events="+watcher.getEvents());
+            
+            // Assert that we log again when come across non-number, but only once
+            for (int i = 0; i < 2; i++) {
+                assertEquals(func.apply(inputWithNonNumber), (Integer)5);
+            }
+            assertEquals(watcher.getEvents().size(), 1, "events="+watcher.getEvents());
+            
+        } finally {
+            watcher.close();
+        }
+    }
+    
     @Test
     public void testSum() throws Exception {
         Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e7238512/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
----------------------------------------------------------------------
diff --git a/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java b/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
index d2dafee..0f630bb 100644
--- a/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
+++ b/test-support/src/main/java/org/apache/brooklyn/test/LogWatcher.java
@@ -197,4 +197,10 @@ public class LogWatcher implements Closeable {
             return ImmutableList.copyOf(Iterables.filter(events, filter));
         }
     }
+    
+    public void clearEvents() {
+        synchronized (events) {
+            events.clear();
+        }
+    }
 }


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

Posted by tb...@apache.org.
This closes #915


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

Branch: refs/heads/master
Commit: b65451764031b22287f8d5b3fcd38c7a71877366
Parents: ca82123 e723851
Author: Thomas Bouron <th...@cloudsoftcorp.com>
Authored: Thu Dec 21 14:23:02 2017 +0000
Committer: Thomas Bouron <th...@cloudsoftcorp.com>
Committed: Thu Dec 21 14:23:02 2017 +0000

----------------------------------------------------------------------
 .../enricher/stock/MathAggregatorFunctions.java | 40 ++++++++++++----
 .../stock/MathAggregatorFunctionsTest.java      | 50 ++++++++++++++++++++
 .../org/apache/brooklyn/test/LogWatcher.java    |  6 +++
 .../util/javalang/coerce/TypeCoercionsTest.java | 12 +++++
 4 files changed, 100 insertions(+), 8 deletions(-)
----------------------------------------------------------------------



[2/3] brooklyn-server git commit: BROOKLYN-569: aggregator casts vals to numbers

Posted by tb...@apache.org.
BROOKLYN-569: aggregator casts vals to numbers

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

Branch: refs/heads/master
Commit: f78cc06b2a23850e751ad3a9d8878fd0b585b72e
Parents: cedbd92
Author: Aled Sage <al...@gmail.com>
Authored: Mon Dec 11 17:15:50 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Dec 21 09:31:38 2017 +0000

----------------------------------------------------------------------
 .../enricher/stock/MathAggregatorFunctions.java     | 16 +++++++++++-----
 .../enricher/stock/MathAggregatorFunctionsTest.java | 10 ++++++++++
 .../util/javalang/coerce/TypeCoercionsTest.java     | 12 ++++++++++++
 3 files changed, 33 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f78cc06b/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
index a67befd..c8509d5 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctions.java
@@ -25,6 +25,9 @@ import java.util.List;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
@@ -33,6 +36,8 @@ import com.google.common.reflect.TypeToken;
 @Beta
 public class MathAggregatorFunctions {
 
+    private static final Logger LOG = LoggerFactory.getLogger(MathAggregatorFunctions.class);
+
     private MathAggregatorFunctions() {}
     
     @Beta
@@ -118,9 +123,10 @@ public class MathAggregatorFunctions {
             List<Number> postProcessedVals = new ArrayList<>();
             int count = 0;
             if (vals != null) {
-                for (Number val : vals) { 
-                    if (val != null) {
-                        postProcessedVals.add(val);
+                for (Object val : vals) {
+                    Maybe<Number> coercedVal = TypeCoercions.tryCoerce(val, Number.class);
+                    if (coercedVal.isPresentAndNonNull()) {
+                        postProcessedVals.add(coercedVal.get());
                         count++;
                     } else if (defaultValueForUnreportedSensors != null) {
                         postProcessedVals.add(defaultValueForUnreportedSensors);
@@ -145,7 +151,7 @@ public class MathAggregatorFunctions {
         @Override
         public Number applyImpl(Collection<Number> vals) {
             double result = 0d;
-            for (Number val : vals) { 
+            for (Number val : vals) {
                 result += val.doubleValue();
             }
             return result;
@@ -160,7 +166,7 @@ public class MathAggregatorFunctions {
         @Override
         public Number applyImpl(Collection<Number> vals) {
             double sum = 0d;
-            for (Number val : vals) { 
+            for (Number val : vals) {
                 sum += val.doubleValue();
             }
             return (sum / vals.size());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f78cc06b/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
index d3f4308..d07b0db 100644
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/MathAggregatorFunctionsTest.java
@@ -88,6 +88,16 @@ public class MathAggregatorFunctionsTest {
         }
     }
     
+    // See https://issues.apache.org/jira/browse/BROOKLYN-569
+    // Casting like this can be required when used in aggregators - the input sensors may not have been cast.
+    @Test
+    public void testCastInputValuesToNumbers() throws Exception {
+        Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class);
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        List<Number> input = (List<Number>) (List) MutableList.<Object>of("1", null, "4");
+        assertEquals(func.apply(input), (Integer)5);
+    }
+    
     @Test
     public void testSum() throws Exception {
         Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f78cc06b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercionsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercionsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercionsTest.java
index c5e989b..c3aea92 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercionsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercionsTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.util.javalang.coerce;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -485,6 +486,13 @@ public class TypeCoercionsTest {
     }
 
     @Test
+    public void testCoerceToSameTypeIsNoop() {
+        assertCoerceToSame(Integer.valueOf(1), Integer.class);
+        assertCoerceToSame(Integer.valueOf(1), Number.class);
+        assertCoerceToSame("myval", String.class);
+    }
+
+    @Test
     public void testCoerceStringToPredicate() {
         assertEquals(coerce("alwaysFalse", Predicate.class), Predicates.alwaysFalse());
         assertEquals(coerce("alwaysTrue", Predicate.class), Predicates.alwaysTrue());
@@ -509,6 +517,10 @@ public class TypeCoercionsTest {
         assertEquals(coercer.function(Double.class).apply("1"), Double.valueOf(1));
     }
 
+    private <T> void assertCoerceToSame(T val, Class<? super T> type) {
+        assertSame(coerce(val, type), val);
+    }
+    
     public static class WithAs {
         String value;
         public WithAs(Object x) { value = ""+x; }