brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [1/8] incubator-brooklyn git commit: adds formatString function
Date Fri, 09 Oct 2015 08:37:12 GMT
Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master fa131b105 -> b73c05b57


adds formatString function


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

Branch: refs/heads/master
Commit: 8cf510cb872c0ec85998e9853cb01a815ebecd27
Parents: f0ca574
Author: Robert Moss <robertgmoss@gmail.com>
Authored: Wed Sep 23 14:16:47 2015 +0100
Committer: Robert Moss <robertgmoss@gmail.com>
Committed: Thu Oct 1 16:37:52 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/enricher/stock/Enrichers.java      |   1 +
 .../apache/brooklyn/enricher/stock/Reducer.java | 162 -------------
 .../stock/reducer/GenericStringReducer.java     |  21 ++
 .../stock/reducer/ObjectStringReducer.java      |  19 ++
 .../enricher/stock/reducer/Reducer.java         | 163 +++++++++++++
 .../stock/reducer/StringStringReducer.java      |  23 ++
 .../brooklyn/enricher/stock/ReducerTest.java    | 216 -----------------
 .../enricher/stock/reducer/ReducerTest.java     | 237 +++++++++++++++++++
 8 files changed, 464 insertions(+), 378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
index 25d186f..8c73653 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.sensor.EnricherSpec;
 import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.enricher.stock.reducer.Reducer;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/Reducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Reducer.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Reducer.java
deleted file mode 100644
index 938cf22..0000000
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/Reducer.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.apache.brooklyn.enricher.stock;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-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.Sensor;
-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.core.flags.SetFromFlag;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.api.client.util.Lists;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.reflect.TypeToken;
-
-@SuppressWarnings("serial")
-public abstract class Reducer<S, T> extends AbstractEnricher implements SensorEventListener<Object>
{
-
-    private static final Logger LOG = LoggerFactory.getLogger(Reducer.class);
-
-    @SetFromFlag("producer")
-    public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class,
"enricher.producer");
-    public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new
TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
-    public static ConfigKey<List<? extends AttributeSensor<?>>> SOURCE_SENSORS
= ConfigKeys.newConfigKey(new TypeToken<List<? extends AttributeSensor<?>>>()
{}, "enricher.sourceSensors");
-    public static ConfigKey<Function<List<?>,?>> REDUCER_FUNCTION = ConfigKeys.newConfigKey(new
TypeToken<Function<List<?>, ?>>() {}, "enricher.reducerFunction");
-    @SetFromFlag("transformation")
-    public static final ConfigKey<String> REDUCER_FUNCTION_UNTYPED = ConfigKeys.newStringConfigKey("enricher.reducerFunction.untyped",
-        "A string matching a pre-defined named reducer function, such as join");
-    public static final ConfigKey<Map<String, Object>> PARAMETERS = ConfigKeys.newConfigKey(new
TypeToken<Map<String, Object>>() {}, "enricher.reducerFunctionParameters", 
-        "A map of parameters to pass into the reducer function");
-   
-    protected Entity producer;
-    protected List<AttributeSensor<S>> subscribedSensors;
-    protected Sensor<T> targetSensor;
-    protected Function<List<S>, T> reducerFunction;
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    public void setEntity(EntityLocal entity) {
-        super.setEntity(entity);
-        Preconditions.checkNotNull(getConfig(SOURCE_SENSORS), "source sensors");
-
-        this.producer = getConfig(PRODUCER) == null ? entity : getConfig(PRODUCER);
-        List<AttributeSensor<S>> sensorListTemp = Lists.newArrayList();
-
-        for (Object sensorO : getConfig(SOURCE_SENSORS)) {
-            AttributeSensor<S> sensor = Tasks.resolving(sensorO).as(AttributeSensor.class).timeout(ValueResolver.REAL_QUICK_WAIT).context(producer).get();
-            if(!sensorListTemp.contains(sensor)) {
-                sensorListTemp.add(sensor);
-            }
-        }
-        
-        String reducerName = config().get(REDUCER_FUNCTION_UNTYPED);
-        Function<List<S>, T> reducerFunction = (Function) config().get(REDUCER_FUNCTION);
-        if(reducerFunction == null){
-            Map<String, ?> parameters = config().get(PARAMETERS);
-            reducerFunction = createReducerFunction(reducerName, parameters);
-        }
-
-        this.reducerFunction = reducerFunction;
-        Preconditions.checkState(sensorListTemp.size() > 0, "Nothing to reduce");
-
-        for (Sensor<S> sensor : sensorListTemp) {
-            subscribe(producer, sensor, this);
-        }
-
-        subscribedSensors = ImmutableList.copyOf(sensorListTemp);
-    }
-
-    protected abstract Function<List<S>, T> createReducerFunction(String reducerName,
Map<String, ?> parameters);
-    
-    @SuppressWarnings("unchecked")
-    @Override
-    public void onEvent(SensorEvent<Object> event) {
-        Sensor<T> destinationSensor = (Sensor<T>) getConfig(TARGET_SENSOR);
-
-        List<S> values = Lists.newArrayList();
-
-        for (AttributeSensor<S> sourceSensor : subscribedSensors) {
-            S resolvedSensorValue = entity.sensors().get(sourceSensor);
-            if (resolvedSensorValue == null) {
-                // only apply function if all values are resolved
-                return;
-            }
-
-            values.add(resolvedSensorValue);
-        }
-
-        Object result = reducerFunction.apply(values);
-
-        if (LOG.isTraceEnabled()) LOG.trace("enricher {} got {}, propagating via {} as {}",
-                new Object[] {this, event, entity, reducerFunction, destinationSensor});
-
-        emit((Sensor<T>)destinationSensor, result);
-    }
-    
-    public static class StringStringReducer extends Reducer<String, String> {
-        
-        public StringStringReducer() {}
-
-        @Override
-        protected Function<List<String>, String> createReducerFunction(
-                String reducerName, Map<String, ?> parameters) {
-            if(reducerName.equals("joiner")){
-                return new JoinerFunction(parameters.get("separator"));
-            }
-            throw new IllegalStateException("unknown function: " + reducerName);
-        }
-    }
-
-    public static class JoinerReducerFunction<A> implements Function<List<A>,
String> {
-        
-        private Object separator;
-
-        public JoinerReducerFunction(Object separator) {
-            this.separator = (separator == null) ? ", " : separator;
-        }
-
-        @Override
-        public String apply(List<A> input) {
-            
-            StringBuilder sb = new StringBuilder();
-            Iterator<A> it = input.iterator();
-            while(it.hasNext()) {
-                sb.append(it.next().toString());
-                if(it.hasNext()){
-                    sb.append(separator);
-                }
-            }
-            return sb.toString();
-        }
-        
-    }
-
-    public static class JoinerFunction extends JoinerReducerFunction<String>{
-        
-        public JoinerFunction(Object separator) {
-            super(separator);
-        }
-    }
-
-    public static class ToStringReducerFunction<A> implements Function<List<A>,
String> {
-
-        @Override
-        public String apply(List<A> input) {
-            return input.toString();
-        }
-        
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/GenericStringReducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/GenericStringReducer.java
b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/GenericStringReducer.java
new file mode 100644
index 0000000..037a869
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/GenericStringReducer.java
@@ -0,0 +1,21 @@
+package org.apache.brooklyn.enricher.stock.reducer;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+
+public abstract class GenericStringReducer<T> extends Reducer<T, String>{
+
+    @Override
+    protected Function<List<T>, String> createReducerFunction(
+            String reducerName, Map<String, ?> parameters) {
+        if (reducerName.equals("formatString")){
+            String format = Preconditions.checkNotNull((String)parameters.get("format"),
"format");
+            return new FormatStringReducerFunction<T>(format);
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/ObjectStringReducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/ObjectStringReducer.java
b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/ObjectStringReducer.java
new file mode 100644
index 0000000..775d075
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/ObjectStringReducer.java
@@ -0,0 +1,19 @@
+package org.apache.brooklyn.enricher.stock.reducer;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Function;
+
+public class ObjectStringReducer extends GenericStringReducer<Object> {
+
+    @Override
+    protected Function<List<Object>, String> createReducerFunction(
+            String reducerName, Map<String, ?> parameters) {
+        
+        Function<List<Object>, String> function = super.createReducerFunction(reducerName,
parameters);
+        if(function != null) return function;
+
+        throw new IllegalStateException("unknown function: " + reducerName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
new file mode 100644
index 0000000..439b003
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/Reducer.java
@@ -0,0 +1,163 @@
+package org.apache.brooklyn.enricher.stock.reducer;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+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.Sensor;
+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.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ValueResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.api.client.util.Lists;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("serial")
+public abstract class Reducer<S, T> extends AbstractEnricher implements SensorEventListener<Object>
{
+
+    private static final Logger LOG = LoggerFactory.getLogger(Reducer.class);
+
+    @SetFromFlag("producer")
+    public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class,
"enricher.producer");
+    public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new
TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+    public static ConfigKey<List<? extends AttributeSensor<?>>> SOURCE_SENSORS
= ConfigKeys.newConfigKey(new TypeToken<List<? extends AttributeSensor<?>>>()
{}, "enricher.sourceSensors");
+    public static ConfigKey<Function<List<?>,?>> REDUCER_FUNCTION = ConfigKeys.newConfigKey(new
TypeToken<Function<List<?>, ?>>() {}, "enricher.reducerFunction");
+    @SetFromFlag("transformation")
+    public static final ConfigKey<String> REDUCER_FUNCTION_UNTYPED = ConfigKeys.newStringConfigKey("enricher.reducerFunction.untyped",
+        "A string matching a pre-defined named reducer function, such as join");
+    public static final ConfigKey<Map<String, Object>> PARAMETERS = ConfigKeys.newConfigKey(new
TypeToken<Map<String, Object>>() {}, "enricher.reducerFunction.parameters", 
+        "A map of parameters to pass into the reducer function");
+   
+    protected Entity producer;
+    protected List<AttributeSensor<S>> subscribedSensors;
+    protected Sensor<T> targetSensor;
+    protected Function<List<S>, T> reducerFunction;
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public void setEntity(EntityLocal entity) {
+        super.setEntity(entity);
+        Preconditions.checkNotNull(getConfig(SOURCE_SENSORS), "source sensors");
+
+        this.producer = getConfig(PRODUCER) == null ? entity : getConfig(PRODUCER);
+        List<AttributeSensor<S>> sensorListTemp = Lists.newArrayList();
+
+        for (Object sensorO : getConfig(SOURCE_SENSORS)) {
+            AttributeSensor<S> sensor = Tasks.resolving(sensorO).as(AttributeSensor.class).timeout(ValueResolver.REAL_QUICK_WAIT).context(producer).get();
+            if(!sensorListTemp.contains(sensor)) {
+                sensorListTemp.add(sensor);
+            }
+        }
+        
+        String reducerName = config().get(REDUCER_FUNCTION_UNTYPED);
+        Function<List<S>, T> reducerFunction = (Function) config().get(REDUCER_FUNCTION);
+        if(reducerFunction == null){
+            Map<String, ?> parameters = config().get(PARAMETERS);
+            reducerFunction = createReducerFunction(reducerName, parameters);
+        }
+
+        this.reducerFunction = reducerFunction;
+        Preconditions.checkState(sensorListTemp.size() > 0, "Nothing to reduce");
+
+        for (Sensor<S> sensor : sensorListTemp) {
+            subscribe(producer, sensor, this);
+        }
+
+        subscribedSensors = ImmutableList.copyOf(sensorListTemp);
+    }
+
+    protected abstract Function<List<S>, T> createReducerFunction(String reducerName,
Map<String, ?> parameters);
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public void onEvent(SensorEvent<Object> event) {
+        Sensor<T> destinationSensor = (Sensor<T>) getConfig(TARGET_SENSOR);
+
+        List<S> values = Lists.newArrayList();
+
+        for (AttributeSensor<S> sourceSensor : subscribedSensors) {
+            S resolvedSensorValue = entity.sensors().get(sourceSensor);
+            if (resolvedSensorValue == null) {
+                // only apply function if all values are resolved
+                return;
+            }
+
+            values.add(resolvedSensorValue);
+        }
+
+        Object result = reducerFunction.apply(values);
+
+        if (LOG.isTraceEnabled()) LOG.trace("enricher {} got {}, propagating via {} as {}",
+                new Object[] {this, event, entity, reducerFunction, destinationSensor});
+
+        emit((Sensor<T>)destinationSensor, result);
+    }
+   
+    public static class JoinerReducerFunction<A> implements Function<List<A>,
String> {
+        
+        private Object separator;
+
+        public JoinerReducerFunction(Object separator) {
+            this.separator = (separator == null) ? ", " : separator;
+        }
+
+        @Override
+        public String apply(List<A> input) {
+            
+            StringBuilder sb = new StringBuilder();
+            Iterator<A> it = input.iterator();
+            while(it.hasNext()) {
+                sb.append(it.next().toString());
+                if(it.hasNext()){
+                    sb.append(separator);
+                }
+            }
+            return sb.toString();
+        }
+        
+    }
+
+    public static class JoinerFunction extends JoinerReducerFunction<String>{
+        
+        public JoinerFunction(Object separator) {
+            super(separator);
+        }
+    }
+
+    public static class ToStringReducerFunction<A> implements Function<List<A>,
String> {
+
+        @Override
+        public String apply(List<A> input) {
+            return input.toString();
+        }
+        
+    }
+    
+    public static class FormatStringReducerFunction<T> implements Function<List<T>,
String> {
+        
+        private String format;
+
+        public FormatStringReducerFunction(String format) {
+            this.format = Preconditions.checkNotNull(format, "format");
+        }
+
+        @Override
+        public String apply(List<T> input) {
+            return String.format(format, input.toArray());
+        }
+        
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/StringStringReducer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/StringStringReducer.java
b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/StringStringReducer.java
new file mode 100644
index 0000000..eaa0dc7
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/reducer/StringStringReducer.java
@@ -0,0 +1,23 @@
+package org.apache.brooklyn.enricher.stock.reducer;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Function;
+
+public class StringStringReducer extends GenericStringReducer<String> {
+    
+    public StringStringReducer() {}
+
+    @Override
+    protected Function<List<String>, String> createReducerFunction(
+            String reducerName, Map<String, ?> parameters) {
+        Function<List<String>, String> function = super.createReducerFunction(reducerName,
parameters);
+        if(function != null) return function;
+        
+        if(reducerName.equals("joiner")){
+            return new JoinerFunction(parameters.get("separator"));
+        }
+        throw new IllegalStateException("unknown function: " + reducerName);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/test/java/org/apache/brooklyn/enricher/stock/ReducerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/ReducerTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/ReducerTest.java
deleted file mode 100644
index a39d76c..0000000
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/ReducerTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package org.apache.brooklyn.enricher.stock;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-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.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.enricher.stock.Reducer.StringStringReducer;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class ReducerTest extends BrooklynAppUnitTestSupport {
-
-    public static final AttributeSensor<String> STR1 = Sensors.newStringSensor("test.str1");
-    public static final AttributeSensor<String> STR2 = Sensors.newStringSensor("test.str2");
-    public static final AttributeSensor<String> STR3 = Sensors.newStringSensor("test.str3");
-    public static final AttributeSensor<Integer> INT1 = Sensors.newIntegerSensor("test.int1");
-
-    private TestEntity entity;
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-    }
-
-    @Test
-    public void testBasicReducer(){
-        entity.addEnricher(EnricherSpec.create(StringStringReducer.class).configure(
-                MutableMap.of(
-                Reducer.SOURCE_SENSORS, ImmutableList.of(STR1, STR2),
-                Reducer.PRODUCER, entity,
-                Reducer.TARGET_SENSOR, STR3,
-                Reducer.REDUCER_FUNCTION, new Concatenator())
-            )
-        );
-
-        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foobar");
-    }
-
-    @Test
-    public void testReducingBuilderWithConcatenator() {
-        entity.addEnricher(Enrichers.builder()
-                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
-                .from(entity)
-                .computing(new Concatenator())
-                .publishing(STR3)
-                .build()
-        );
-
-        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foobar");
-    }
-    
-    @Test
-    public void testReducingBuilderWithLengthCalculator() {
-        entity.addEnricher(Enrichers.builder()
-                .reducing(StringIntegerReducer.class, ImmutableList.of(STR1, STR2))
-                .from(entity)
-                .computing(new LengthCalculator())
-                .publishing(INT1)
-                .build()
-        );
-
-        EntityTestUtils.assertAttributeEquals(entity, INT1, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, INT1, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, INT1, 6);
-    }
-    
-    @Test
-    public void testReducingBuilderWithJoinerFunction() {
-        entity.addEnricher(Enrichers.builder()
-                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
-                .from(entity)
-                .computing("joiner", ImmutableMap.<String, Object>of("separator", "-"))
-                .publishing(STR3)
-                .build()
-        );
-
-        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo-bar");
-    }
-    
-    @Test
-    public void testReducingBuilderWithJoinerFunctionWithDefaultParameter() {
-        entity.addEnricher(Enrichers.builder()
-            .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
-            .from(entity)
-            .computing("joiner")
-            .publishing(STR3)
-            .build()
-        );
-        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo, bar");
-    }
-    
-    @Test
-    public void testReducingBuilderWithJoinerFunctionAndUnusedParameter() {
-        
-        entity.addEnricher(Enrichers.builder()
-            .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
-            .from(entity)
-            .computing("joiner", ImmutableMap.<String, Object>of("non.existent.parameter",
"-"))
-            .publishing(STR3)
-            .build()
-        );
-        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
-        
-        entity.sensors().set(STR1, "foo");
-        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
-
-        entity.sensors().set(STR2, "bar");
-        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo, bar");
-    }
-    
-    @Test
-    public void testReducingBuilderWithNamedNonExistentFunction() {
-        try { 
-            entity.addEnricher(Enrichers.builder()
-                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
-                .from(entity)
-                .computing("unknown function name", ImmutableMap.<String, Object>of("separator",
"-"))
-                .publishing(STR3)
-                .build()
-            );
-            Asserts.fail("Expected exception when adding reducing enricher with unknown named
function");
-        } catch (Exception e) {
-            Throwable t = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class);
-            Assert.assertNotNull(t);
-        }
-    }
-    
-    private static class Concatenator implements Function<List<String>, String>
{
-        @Nullable
-        @Override
-        public String apply(List<String> values) {
-            StringBuilder result = new StringBuilder();
-            for (String value : values) {
-                if (value == null) {
-                    return null;
-                } else {
-                    result.append(value);
-                }
-            }
-            return result.toString();
-        }
-    }
-    
-    public static class StringIntegerReducer extends Reducer<String, Integer> {
-        
-        public StringIntegerReducer() {}
-
-        @Override
-        protected Function<List<String>, Integer> createReducerFunction(
-                String reducerName, Map<String, ?> parameters) {
-            throw new IllegalStateException("unknown function: " + reducerName);
-        }
-        
-    }
-    
-    private static class LengthCalculator implements Function<List<String>, Integer>{
-
-        @Override
-        public Integer apply(List<String> values) {
-            int acc = 0;
-            for (String value : values) {
-                if (value != null) {
-                    acc += value.length();
-                }
-            }
-            return acc;
-        }
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8cf510cb/core/src/test/java/org/apache/brooklyn/enricher/stock/reducer/ReducerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/reducer/ReducerTest.java
b/core/src/test/java/org/apache/brooklyn/enricher/stock/reducer/ReducerTest.java
new file mode 100644
index 0000000..a1429f4
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/reducer/ReducerTest.java
@@ -0,0 +1,237 @@
+package org.apache.brooklyn.enricher.stock.reducer;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+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.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.enricher.stock.reducer.Reducer;
+import org.apache.brooklyn.enricher.stock.reducer.StringStringReducer;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class ReducerTest extends BrooklynAppUnitTestSupport {
+
+    public static final AttributeSensor<String> STR1 = Sensors.newStringSensor("test.str1");
+    public static final AttributeSensor<String> STR2 = Sensors.newStringSensor("test.str2");
+    public static final AttributeSensor<String> STR3 = Sensors.newStringSensor("test.str3");
+    public static final AttributeSensor<Integer> INT1 = Sensors.newIntegerSensor("test.int1");
+
+    private TestEntity entity;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+    }
+
+    @Test
+    public void testBasicReducer(){
+        entity.addEnricher(EnricherSpec.create(StringStringReducer.class).configure(
+                MutableMap.of(
+                Reducer.SOURCE_SENSORS, ImmutableList.of(STR1, STR2),
+                Reducer.PRODUCER, entity,
+                Reducer.TARGET_SENSOR, STR3,
+                Reducer.REDUCER_FUNCTION, new Concatenator())
+            )
+        );
+
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foobar");
+    }
+
+    @Test
+    public void testReducingBuilderWithConcatenator() {
+        entity.addEnricher(Enrichers.builder()
+                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+                .from(entity)
+                .computing(new Concatenator())
+                .publishing(STR3)
+                .build()
+        );
+
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foobar");
+    }
+    
+    @Test
+    public void testReducingBuilderWithLengthCalculator() {
+        entity.addEnricher(Enrichers.builder()
+                .reducing(StringIntegerReducer.class, ImmutableList.of(STR1, STR2))
+                .from(entity)
+                .computing(new LengthCalculator())
+                .publishing(INT1)
+                .build()
+        );
+
+        EntityTestUtils.assertAttributeEquals(entity, INT1, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, INT1, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, INT1, 6);
+    }
+    
+    @Test
+    public void testReducingBuilderWithJoinerFunction() {
+        entity.addEnricher(Enrichers.builder()
+                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+                .from(entity)
+                .computing("joiner", ImmutableMap.<String, Object>of("separator", "-"))
+                .publishing(STR3)
+                .build()
+        );
+
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo-bar");
+    }
+    
+    @Test
+    public void testReducingBuilderWithJoinerFunctionWithDefaultParameter() {
+        entity.addEnricher(Enrichers.builder()
+            .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+            .from(entity)
+            .computing("joiner")
+            .publishing(STR3)
+            .build()
+        );
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo, bar");
+    }
+    
+    @Test
+    public void testReducingBuilderWithJoinerFunctionAndUnusedParameter() {
+        
+        entity.addEnricher(Enrichers.builder()
+            .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+            .from(entity)
+            .computing("joiner", ImmutableMap.<String, Object>of("non.existent.parameter",
"-"))
+            .publishing(STR3)
+            .build()
+        );
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "foo, bar");
+    }
+    
+    @Test
+    public void testReducingBuilderWithFormatStringFunction() {
+        
+        entity.addEnricher(Enrichers.builder()
+            .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+            .from(entity)
+            .computing("formatString", ImmutableMap.<String, Object>of("format", "hello,
%s and %s"))
+            .publishing(STR3)
+            .build()
+        );
+        EntityTestUtils.assertAttributeEquals(entity, STR3, null);
+        
+        entity.sensors().set(STR1, "foo");
+        EntityTestUtils.assertAttributeEqualsContinually(entity, STR3, null);
+
+        entity.sensors().set(STR2, "bar");
+        EntityTestUtils.assertAttributeEqualsEventually(entity, STR3, "hello, foo and bar");
+    }
+    
+    @Test
+    public void testReducingBuilderWithNamedNonExistentFunction() {
+        try { 
+            entity.addEnricher(Enrichers.builder()
+                .reducing(StringStringReducer.class, ImmutableList.of(STR1, STR2))
+                .from(entity)
+                .computing("unknown function name", ImmutableMap.<String, Object>of("separator",
"-"))
+                .publishing(STR3)
+                .build()
+            );
+            Asserts.fail("Expected exception when adding reducing enricher with unknown named
function");
+        } catch (Exception e) {
+            Throwable t = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class);
+            Assert.assertNotNull(t);
+        }
+    }
+    
+    private static class Concatenator implements Function<List<String>, String>
{
+        @Nullable
+        @Override
+        public String apply(List<String> values) {
+            StringBuilder result = new StringBuilder();
+            for (String value : values) {
+                if (value == null) {
+                    return null;
+                } else {
+                    result.append(value);
+                }
+            }
+            return result.toString();
+        }
+    }
+    
+    public static class StringIntegerReducer extends Reducer<String, Integer> {
+        
+        public StringIntegerReducer() {}
+
+        @Override
+        protected Function<List<String>, Integer> createReducerFunction(
+                String reducerName, Map<String, ?> parameters) {
+            throw new IllegalStateException("unknown function: " + reducerName);
+        }
+        
+    }
+    
+    private static class LengthCalculator implements Function<List<String>, Integer>{
+
+        @Override
+        public Integer apply(List<String> values) {
+            int acc = 0;
+            for (String value : values) {
+                if (value != null) {
+                    acc += value.length();
+                }
+            }
+            return acc;
+        }
+        
+    }
+}



Mime
View raw message