You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/07/17 09:06:08 UTC
[2/3] brooklyn-server git commit: Adds Aggregator for ‘first’ (and adds yaml tests)
Adds Aggregator for ‘first’ (and adds yaml tests)
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/d99e932b
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/d99e932b
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/d99e932b
Branch: refs/heads/master
Commit: d99e932b57eab13136d0488ed798038b04d8a27e
Parents: ec01ecb
Author: Aled Sage <al...@gmail.com>
Authored: Fri Jul 14 15:24:48 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Fri Jul 14 15:24:48 2017 +0100
----------------------------------------------------------------------
.../camp/brooklyn/AggregatorYamlTest.java | 199 +++++++++++++++++++
.../brooklyn/enricher/stock/Aggregator.java | 11 +-
2 files changed, 209 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d99e932b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AggregatorYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AggregatorYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AggregatorYamlTest.java
new file mode 100644
index 0000000..b5dadf8
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AggregatorYamlTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.camp.brooklyn;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Aggregator;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+@Test
+public class AggregatorYamlTest extends AbstractYamlTest {
+ private static final Logger log = LoggerFactory.getLogger(AggregatorYamlTest.class);
+
+ AttributeSensor<Object> myVal = Sensors.newSensor(Object.class, "myVal");
+ AttributeSensor<Object> myResult = Sensors.newSensor(Object.class, "myResult");
+
+ @Test
+ public void testSum() throws Exception {
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicApplication.class.getName(),
+ " brooklyn.children:",
+ " - type: " + TestEntity.class.getName(),
+ " - type: " + TestEntity.class.getName(),
+ " brooklyn.enrichers:",
+ " - type: " + Aggregator.class.getName(),
+ " brooklyn.config:",
+ " "+Aggregator.SOURCE_SENSOR.getName()+": myVal",
+ " "+Aggregator.TARGET_SENSOR.getName()+": myResult",
+ " "+Aggregator.TRANSFORMATION_UNTYPED.getName()+": sum");
+ Entity child1 = Iterables.get(app.getChildren(), 0);
+ Entity child2 = Iterables.get(app.getChildren(), 1);
+
+ child1.sensors().set(myVal, 1d);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 1d);
+
+ child2.sensors().set(myVal, 2d);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 3d);
+
+ child1.sensors().set(myVal, 3d);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 5d);
+
+ child2.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 3d);
+ }
+
+ @Test
+ public void testAverage() throws Exception {
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicApplication.class.getName(),
+ " brooklyn.children:",
+ " - type: " + TestEntity.class.getName(),
+ " - type: " + TestEntity.class.getName(),
+ " brooklyn.enrichers:",
+ " - type: " + Aggregator.class.getName(),
+ " brooklyn.config:",
+ " "+Aggregator.SOURCE_SENSOR.getName()+": myVal",
+ " "+Aggregator.TARGET_SENSOR.getName()+": myResult",
+ " "+Aggregator.TRANSFORMATION_UNTYPED.getName()+": average");
+ Entity child1 = Iterables.get(app.getChildren(), 0);
+ Entity child2 = Iterables.get(app.getChildren(), 1);
+
+ child1.sensors().set(myVal, 1d);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 1d);
+
+ child2.sensors().set(myVal, 3d);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 2d);
+
+ child1.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, 3d);
+ }
+
+ @Test
+ public void testList() throws Exception {
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicApplication.class.getName(),
+ " brooklyn.children:",
+ " - type: " + TestEntity.class.getName(),
+ " - type: " + TestEntity.class.getName(),
+ " brooklyn.enrichers:",
+ " - type: " + Aggregator.class.getName(),
+ " brooklyn.config:",
+ " "+Aggregator.SOURCE_SENSOR.getName()+": myVal",
+ " "+Aggregator.TARGET_SENSOR.getName()+": myResult",
+ " "+Aggregator.TRANSFORMATION_UNTYPED.getName()+": list");
+ Entity child1 = Iterables.get(app.getChildren(), 0);
+ Entity child2 = Iterables.get(app.getChildren(), 1);
+
+ child1.sensors().set(myVal, "val1");
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, MutableList.of("val1", null));
+
+ child2.sensors().set(myVal, "val2");
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, ImmutableList.of("val1", "val2"));
+
+ child1.sensors().set(myVal, "val1b");
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, ImmutableList.of("val1b", "val2"));
+
+ child1.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, MutableList.of(null, "val2"));
+ }
+
+ @Test
+ public void testFirst() throws Exception {
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicApplication.class.getName(),
+ " brooklyn.children:",
+ " - type: " + TestEntity.class.getName(),
+ " - type: " + TestEntity.class.getName(),
+ " brooklyn.enrichers:",
+ " - type: " + Aggregator.class.getName(),
+ " brooklyn.config:",
+ " "+Aggregator.SOURCE_SENSOR.getName()+": myVal",
+ " "+Aggregator.TARGET_SENSOR.getName()+": myResult",
+ " "+Aggregator.TRANSFORMATION_UNTYPED.getName()+": first",
+ " "+Aggregator.VALUE_FILTER.getName()+": notNull");
+ Entity child1 = Iterables.get(app.getChildren(), 0);
+ Entity child2 = Iterables.get(app.getChildren(), 1);
+
+ child1.sensors().set(myVal, "val1");
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, "val1");
+
+ child2.sensors().set(myVal, "val2");
+ EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", Duration.millis(50)), app, myResult, "val1");
+
+ child1.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, "val2");
+
+ child2.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, null);
+
+ child1.sensors().set(myVal, "val3");
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, "val3");
+ }
+
+ @Test
+ public void testQuorum() throws Exception {
+ Entity app = createAndStartApplication(
+ "services:",
+ "- type: " + BasicApplication.class.getName(),
+ " brooklyn.children:",
+ " - type: " + TestEntity.class.getName(),
+ " - type: " + TestEntity.class.getName(),
+ " brooklyn.enrichers:",
+ " - type: " + Aggregator.class.getName(),
+ " brooklyn.config:",
+ " "+Aggregator.SOURCE_SENSOR.getName()+": myVal",
+ " "+Aggregator.TARGET_SENSOR.getName()+": myResult",
+ " "+Aggregator.TRANSFORMATION_UNTYPED.getName()+": isQuorate",
+ " "+Aggregator.QUORUM_CHECK_TYPE.getName()+": all",
+ " "+Aggregator.QUORUM_TOTAL_SIZE.getName()+": 2");
+ Entity child1 = Iterables.get(app.getChildren(), 0);
+ Entity child2 = Iterables.get(app.getChildren(), 1);
+
+ child1.sensors().set(myVal, true);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, false);
+
+ child2.sensors().set(myVal, true);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, true);
+
+ child2.sensors().set(myVal, null);
+ EntityAsserts.assertAttributeEqualsEventually(app, myResult, false);
+ }
+
+ @Override
+ protected Logger getLogger() {
+ return log;
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d99e932b/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
index f94c652..1ba4e6d 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
@@ -62,7 +62,8 @@ public class Aggregator<T,U> extends AbstractAggregator<T,U> implements SensorEv
"Specifies a transformation, as a function from a collection to the value, or as a string " +
"matching a pre-defined named transformation, such as 'average' (for numbers), " +
"'sum' (for numbers), 'isQuorate' (to compute a quorum), " +
- "or 'list' (the default, putting any collection of items into a list)");
+ "'list' (the default, putting any collection of items into a list), " +
+ "or 'first' (the first value, or null if empty)");
public static final ConfigKey<Function<? super Collection<?>, ?>> TRANSFORMATION = ConfigKeys.newConfigKey(new TypeToken<Function<? super Collection<?>, ?>>() {},
"enricher.transformation");
@@ -120,6 +121,7 @@ public class Aggregator<T,U> extends AbstractAggregator<T,U> implements SensorEv
if ("isQuorate".equalsIgnoreCase(t1)) return new Enrichers.ComputingIsQuorate(targetSensor.getTypeToken(),
QuorumChecks.of(config().get(QUORUM_CHECK_TYPE)), config().get(QUORUM_TOTAL_SIZE));
if ("list".equalsIgnoreCase(t1)) return new ComputingList();
+ if ("first".equalsIgnoreCase(t1)) return new FirstOrNull();
return null;
}
@@ -131,6 +133,13 @@ public class Aggregator<T,U> extends AbstractAggregator<T,U> implements SensorEv
}
}
+ private static class FirstOrNull<TT> implements Function<Collection<TT>, TT> {
+ @Override
+ public TT apply(Collection<TT> input) {
+ return (input==null) ? null : Iterables.getFirst(input, null);
+ }
+ }
+
@Override
protected void setEntityBeforeSubscribingProducerChildrenEvents() {
BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),