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/06/12 14:47:24 UTC

[5/7] brooklyn-server git commit: Delete CustomAggregatingEnricher

Delete CustomAggregatingEnricher

Was deprecated in 0.7.0; did not have a constructor usable when
deserialising from persisted state, so that backwards compatibility
is not a worry!

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

Branch: refs/heads/master
Commit: 26eeb7e0f2696006a4c111b20eba5959d5537e38
Parents: 263304b
Author: Aled Sage <al...@gmail.com>
Authored: Sun Jun 11 12:44:25 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Sun Jun 11 14:57:39 2017 +0100

----------------------------------------------------------------------
 .../stock/AbstractAggregatingEnricher.java      | 175 --------
 .../stock/CustomAggregatingEnricher.java        | 352 ----------------
 ...CustomAggregatingEnricherDeprecatedTest.java | 405 -------------------
 3 files changed, 932 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/26eeb7e0/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
deleted file mode 100644
index 9dd3d30..0000000
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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 java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.Group;
-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.core.enricher.AbstractEnricher;
-import org.apache.brooklyn.core.entity.trait.Changeable;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-
-/**
- * AggregatingEnrichers implicitly subscribes to the same sensor<S> on all entities inside an
- * {@link Group} and should emit an aggregate<T> on the target sensor
- * 
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- * @see Aggregator if need to sub-class
- */
-@Deprecated
-public abstract class AbstractAggregatingEnricher<S,T> extends AbstractEnricher implements SensorEventListener<S> {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractAggregatingEnricher.class);
-    
-    AttributeSensor<? extends S> source;
-    protected AttributeSensor<T> target;
-    protected S defaultValue;
-
-    Set<Entity> producers;
-    List<Entity> hardCodedProducers;
-    boolean allMembers;
-    Predicate<Entity> filter;
-    
-    /**
-     * Users of values should either on it synchronize when iterating over its entries or use
-     * copyOfValues to obtain an immutable copy of the map.
-     */
-    // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
-    protected final Map<Entity, S> values = Collections.synchronizedMap(new LinkedHashMap<Entity, S>());
-
-    public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target) {
-        this(flags, source, target, null);
-    }
-    
-    @SuppressWarnings("unchecked")
-    public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, S defaultValue) {
-        super(flags);
-        this.source = source;
-        this.target = target;
-        this.defaultValue = defaultValue;
-        hardCodedProducers = (List<Entity>) (flags.containsKey("producers") ? flags.get("producers") : Collections.emptyList());
-        allMembers = (Boolean) (flags.containsKey("allMembers") ? flags.get("allMembers") : false);
-        filter = flags.containsKey("filter") ? GroovyJavaMethods.<Entity>castToPredicate(flags.get("filter")) : Predicates.<Entity>alwaysTrue();
-    }
-
-    public void addProducer(Entity producer) {
-        if (LOG.isDebugEnabled()) LOG.debug("{} linked ({}, {}) to {}", new Object[] {this, producer, source, target});
-        subscriptions().subscribe(producer, source, this);
-        synchronized (values) {
-            S vo = values.get(producer);
-            if (vo==null) {
-                S initialVal = producer.getAttribute(source);
-                values.put(producer, initialVal != null ? initialVal : defaultValue);
-                //we might skip in onEvent in the short window while !values.containsKey(producer)
-                //but that's okay because the put which would have been done there is done here now
-            } else {
-                //vo will be null unless some weird race with addProducer+removeProducer is occuring
-                //(and that's something we can tolerate i think)
-                if (LOG.isDebugEnabled()) LOG.debug("{} already had value ({}) for producer ({}); but that producer has just been added", new Object[] {this, vo, producer});
-            }
-        }
-        onUpdated();
-    }
-    
-    // TODO If producer removed but then get (queued) event from it after this method returns,  
-    public S removeProducer(Entity producer) {
-        if (LOG.isDebugEnabled()) LOG.debug("{} unlinked ({}, {}) from {}", new Object[] {this, producer, source, target});
-        subscriptions().unsubscribe(producer);
-        S removed = values.remove(producer);
-        onUpdated();
-        return removed;
-    }
-    
-    @Override
-    public void onEvent(SensorEvent<S> event) {
-        Entity e = event.getSource();
-        synchronized (values) {
-            if (values.containsKey(e)) {
-                values.put(e, event.getValue());
-            } else {
-                if (LOG.isDebugEnabled()) LOG.debug("{} received event for unknown producer ({}); presumably that producer has recently been removed", this, e);
-            }
-        }
-        onUpdated();
-    }
-
-    /**
-     * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
-     * Defaults to no-op
-     */
-    // TODO should this be abstract?
-    protected void onUpdated() {
-        // no-op
-    }
-    
-    @Override
-    public void setEntity(EntityLocal entity) {
-        super.setEntity(entity);
-        
-        for (Entity producer : hardCodedProducers) {
-            if (filter.apply(producer)) {
-                addProducer(producer);
-            }
-        }
-        
-        if (allMembers) {
-            subscriptions().subscribe(entity, Changeable.MEMBER_ADDED, new SensorEventListener<Entity>() {
-                @Override public void onEvent(SensorEvent<Entity> it) {
-                    if (filter.apply(it.getValue())) addProducer(it.getValue());
-                }
-            });
-            subscriptions().subscribe(entity, Changeable.MEMBER_REMOVED, new SensorEventListener<Entity>() {
-                @Override public void onEvent(SensorEvent<Entity> it) {
-                    removeProducer(it.getValue());
-                }
-            });
-            
-            if (entity instanceof Group) {
-                for (Entity member : ((Group)entity).getMembers()) {
-                    if (filter.apply(member)) {
-                        addProducer(member);
-                    }
-                }
-            }
-        }
-    }
-    
-    protected Map<Entity, S> copyOfValues() {
-        synchronized (values) {
-            return ImmutableMap.copyOf(values);
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/26eeb7e0/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
deleted file mode 100644
index 2d797da..0000000
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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 groovy.lang.Closure;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Throwables;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Subscribes to events from producers with a sensor of type T, aggregates them with the 
- * provided closure and emits the result on the target sensor V.
- * @param <T>
- * 
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
-@Deprecated
-public class CustomAggregatingEnricher<S,T> extends AbstractAggregatingEnricher<S,T> implements SensorEventListener<S> {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(CustomAggregatingEnricher.class);
-    
-    protected final Function<Collection<S>, T> aggregator;
-    
-    /**
-     * The valid keys for the flags are:
-     * - producers: a collection of entities to be aggregated
-     * - allMembers: indicates that should track members of the entity that the aggregator is associated with,
-     *               to aggregate across all those members.
-     * - filter:     a Predicate indicating which entities to include (support for {@link groovy.lang.Closure} is deprecated)
-     * 
-     * @param flags
-     * @param source
-     * @param target
-     * @param aggregator   Aggregates a collection of values, to return a single value for the target sensor
-     * @param defaultIniitalValueForUnreportedSensors Default value to populate the collection given to aggregator, 
-     * where sensors are null or not present initially, defaults to null (note however that subsequent null reports will put an explicit null)
-     */
-    public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
-            Function<Collection<S>, T> aggregator, S defaultIniitalValueForUnreportedSensors) {
-        super(flags, source, target, defaultIniitalValueForUnreportedSensors);
-        this.aggregator = aggregator;
-    }
-    
-    public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
-            Function<Collection<S>, T> aggregator) {
-        this(flags, source, target, aggregator, null);
-    }
-    
-    public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
-            Function<Collection<S>, T> aggregator, S defaultValue) {
-        this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValue);
-    }
-    
-    public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
-            Function<Collection<S>, T> aggregator) {
-        this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
-    }
-
-    /**
-     * @param flags
-     * @param source
-     * @param target
-     * @param aggregator   Should take a collection of values and return a single, aggregate value
-     * @param defaultValueForUnreportedSensors
-     * 
-     * @see #CustomAggregatingEnricher(Map, AttributeSensor, AttributeSensor, Function, Object)
-     * 
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-     @Deprecated
-    @SuppressWarnings("unchecked")
-    public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
-            Closure<?> aggregator, S defaultValueForUnreportedSensors) {
-        this(flags, source, target, GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator), defaultValueForUnreportedSensors);
-    }
-
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-     @Deprecated
-    public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, Closure<?> aggregator) {
-        this(flags, source, target, aggregator, null);
-    }
-
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-    @Deprecated
-    public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultValueForUnreportedSensors) {
-        this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValueForUnreportedSensors);
-    }
-
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-    @Deprecated
-    public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
-        this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
-    }
-
-    @Override
-    public void onUpdated() {
-        try {
-            entity.sensors().set(target, getAggregate());
-        } catch (Throwable t) {
-            LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
-            throw Throwables.propagate(t);
-        }
-    }
-    
-    public T getAggregate() {
-        synchronized (values) {
-            return aggregator.apply(values.values());
-        }
-    }
-
-    /**
-     * Instead, consider calling:
-     * <pre>
-     * {@code
-     * Enrichers.Builder builder = Enrichers.builder()
-     *         .aggregating(source)
-     *         .publishing(target)
-     *         .computing(GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator))
-     *         .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors);
-     * 
-     * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
-     * if (filter != null) builder.entityFilter(filter);
-     * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
-     * 
-     * addEnricher(builder.build());
-     * }
-     * </pre>
-     *
-     * @deprecated since 0.7.0; use {@link Enrichers#builder()}
-     */
-    @Deprecated
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
-        return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
-    }
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-    @Deprecated
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
-        return newEnricher(flags, source, target, aggregator, null);
-    }
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-    @Deprecated
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
-        return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
-    }
-    /**
-     * @deprecated since 0.11.0; explicit groovy utilities/support will be deleted.
-     */
-    @Deprecated
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
-        return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
-    }
-    
-    /**
-     * Instead, consider calling:
-     * <pre>
-     * {@code
-     * Enrichers.Builder builder = Enrichers.builder()
-     *         .aggregating(source)
-     *         .publishing(target)
-     *         .computing(aggregator)
-     *         .defaultValueForUnreportedSensors(defaultVal);
-     * 
-     * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
-     * if (filter != null) builder.entityFilter(filter);
-     * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
-     * 
-     * addEnricher(builder.build());
-     * }
-     * </pre>
-     *
-     * @deprecated since 0.7.0; use {@link Enrichers#builder()}
-     */
-    @Deprecated
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
-        return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
-    }
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
-        return newEnricher(flags, source, target, aggregator, null);
-    }
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
-        return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
-    }
-    public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
-            AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
-        return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
-    }
-    
-    /** 
-     * creates an enricher which sums over all children/members, 
-     * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors; 
-     * this behaviour can be customised, both default value for sensors, and what to report if no sensors
-     * 
-     * Instead, consider calling:
-     * <pre>
-     * {@code
-     * Enrichers.Builder builder = Enrichers.builder()
-     *         .aggregating(source)
-     *         .publishing(target)
-     *         .computingSum()
-     *         .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
-     *         .valueToReportIfNoSensors(valueToReportIfNoSensors);
-     * 
-     * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
-     * if (filter != null) builder.entityFilter(filter);
-     * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
-     * 
-     * addEnricher(builder.build());
-     * }
-     * </pre>
-     *
-     * @deprecated since 0.7.0; use {@link Enrichers#builder()}
-     */
-    @Deprecated
-    public static <N extends Number, T extends Number> CustomAggregatingEnricher<N,T> newSummingEnricher(
-            Map<String,?> flags, AttributeSensor<N> source, final AttributeSensor<T> target, 
-            final N defaultValueForUnreportedSensors, final T valueToReportIfNoSensors) {
-        
-        Function<Collection<N>, T> aggregator = new Function<Collection<N>, T>() {
-                @Override public T apply(Collection<N> vals) {
-                    return sum(vals, defaultValueForUnreportedSensors, valueToReportIfNoSensors, target.getTypeToken());
-                }
-        };
-        return new CustomAggregatingEnricher<N,T>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
-    }
-    
-    /** @see {@link #newSummingEnricher(Map, AttributeSensor, AttributeSensor, Number, Number)} */
-    public static <N extends Number> CustomAggregatingEnricher<N,N> newSummingEnricher(
-            AttributeSensor<N> source, AttributeSensor<N> target) {
-        return newSummingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
-    }
-
-    /** creates an enricher which averages over all children/members, 
-     * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors; 
-     * this behaviour can be customised, both default value for sensors, and what to report if no sensors
-     * 
-     * Instead, consider calling:
-     * <pre>
-     * {@code
-     * Enrichers.Builder builder = Enrichers.builder()
-     *         .aggregating(source)
-     *         .publishing(target)
-     *         .computingAverage()
-     *         .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
-     *         .valueToReportIfNoSensors(valueToReportIfNoSensors);
-     * 
-     * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
-     * if (filter != null) builder.entityFilter(filter);
-     * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
-     * 
-     * addEnricher(builder.build());
-     * }
-     * </pre>
-     *
-     * @deprecated since 0.7.0; use {@link Enrichers#builder()}
-     */
-    @Deprecated
-    public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
-            Map<String,?> flags, AttributeSensor<? extends N> source, final AttributeSensor<Double> target,
-            final N defaultValueForUnreportedSensors, final Double valueToReportIfNoSensors) {
-        Function<Collection<N>, Double> aggregator = new Function<Collection<N>, Double>() {
-            @Override public Double apply(Collection<N> vals) {
-                int count = count(vals, defaultValueForUnreportedSensors!=null);
-                return (count==0) ? valueToReportIfNoSensors : 
-                    (Double) ((sum(vals, defaultValueForUnreportedSensors, 0, TypeToken.of(Double.class)) / count));
-            }
-        };
-        return new CustomAggregatingEnricher<N,Double>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
-    }
-
-    /** @see #newAveragingEnricher(Map, AttributeSensor, AttributeSensor, Number, Double) */
-    public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
-            AttributeSensor<N> source, AttributeSensor<Double> target) {
-        return newAveragingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <N extends Number> N cast(Number n, TypeToken<? extends N> numberType) {
-        return (N) TypeCoercions.castPrimitive(n, numberType.getRawType());
-    }
-
-    private static <N extends Number> N sum(Iterable<? extends Number> vals, Number valueIfNull, Number valueIfNone, TypeToken<N> type) {
-        double result = 0d;
-        int count = 0;
-        if (vals!=null) {
-            for (Number val : vals) { 
-                if (val!=null) {
-                    result += val.doubleValue();
-                    count++;
-                } else if (valueIfNull!=null) {
-                    result += valueIfNull.doubleValue();
-                    count++;
-                }
-            }
-        }
-        if (count==0) return cast(valueIfNone, type);
-        return cast(result, type);
-    }
-    
-    private static int count(Iterable<? extends Object> vals, boolean includeNullValues) {
-        int result = 0;
-        if (vals!=null) 
-            for (Object val : vals) 
-                if (val!=null || includeNullValues) result++;
-        return result;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/26eeb7e0/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.java
deleted file mode 100644
index c7792af..0000000
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * 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 java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.test.Asserts;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-@SuppressWarnings("deprecation")
-public class CustomAggregatingEnricherDeprecatedTest {
-
-    public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherDeprecatedTest.class);
-            
-    private static final long TIMEOUT_MS = 10*1000;
-    private static final long SHORT_WAIT_MS = 250;
-    
-    TestApplication app;
-    TestEntity producer;
-    Map<String, ?> producersFlags;
-    
-    AttributeSensor<Integer> intSensor = Sensors.newIntegerSensor("int sensor");
-    AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("double sensor");
-    AttributeSensor<Integer> target = Sensors.newIntegerSensor("target sensor");
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        producersFlags = ImmutableMap.of("producers", ImmutableList.of(producer));
-        
-        app.start(ImmutableList.of(new SimulatedLocation()));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (app!=null) Entities.destroyAll(app.getManagementContext());
-    }
-    
-    @Test
-    public void testEnrichersWithNoProducers() {
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(ImmutableMap.<String,Object>of(), intSensor, target, 11, 40);
-        producer.enrichers().add(cae);
-        assertEquals(cae.getAggregate(), 40);
-    }
-
-    @Test
-    public void testSummingEnricherWhenNoSensorValuesYet() {
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                producersFlags, intSensor, target, 11, 40);
-        producer.enrichers().add(cae);
-        assertEquals(cae.getAggregate(), 11);
-    }
-
-    @Test
-    public void testSingleProducerSum() {
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                producersFlags, intSensor, target, null, null);
-        producer.enrichers().add(cae);
-        Assert.assertEquals(cae.getAggregate(), null);
-        cae.onEvent(intSensor.newEvent(producer, 1));
-        assertEquals(cae.getAggregate(), 1);
-    }
-    
-    @Test
-    public void testSummingEnricherWhenNoAndNullSensorValue() {
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                producersFlags, intSensor, target, null, null);
-        producer.enrichers().add(cae);
-        Assert.assertEquals(cae.getAggregate(), null);
-        cae.onEvent(intSensor.newEvent(producer, null));
-        Assert.assertEquals(cae.getAggregate(), null);
-    }
-    
-    @Test
-    public void testSummingEnricherWhenNoAndNullSensorValueExplicitValue() {
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                producersFlags, intSensor, target, 3 /** if null */, 5 /** if none */);
-        producer.enrichers().add(cae);
-        assertEquals(cae.getAggregate(), 3);
-        cae.onEvent(intSensor.newEvent(producer, null));
-        assertEquals(cae.getAggregate(), 3);
-        cae.onEvent(intSensor.newEvent(producer, 1));
-        assertEquals(cae.getAggregate(), 1);
-        cae.onEvent(intSensor.newEvent(producer, 7));
-        assertEquals(cae.getAggregate(), 7);
-    }
-    
-    @Test
-    public void testMultipleProducersSum() {
-        List<TestEntity> producers = ImmutableList.of(
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)), 
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)),
-                app.createAndManageChild(EntitySpec.create(TestEntity.class))
-                );
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                ImmutableMap.of("producers", producers), intSensor, target, null, null);
-        
-        producer.enrichers().add(cae);
-        Assert.assertEquals(cae.getAggregate(), null);
-        cae.onEvent(intSensor.newEvent(producers.get(2), 1));
-        assertEquals(cae.getAggregate(), 1);
-        cae.onEvent(intSensor.newEvent(producers.get(0), 3));
-        assertEquals(cae.getAggregate(), 4);
-        cae.onEvent(intSensor.newEvent(producers.get(1), 3));
-        assertEquals(cae.getAggregate(), 7);
-
-    }
-    
-    @Test
-    public void testAveragingEnricherWhenNoAndNullSensorValues() {
-        List<TestEntity> producers = ImmutableList.of(
-                app.createAndManageChild(EntitySpec.create(TestEntity.class))
-                );
-        CustomAggregatingEnricher<Integer, Double> cae = CustomAggregatingEnricher.<Integer>newAveragingEnricher(
-                ImmutableMap.of("producers", producers), intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null);
-        producer.enrichers().add(cae);
-        Assert.assertEquals(cae.getAggregate(), null);
-        cae.onEvent(intSensor.newEvent(producers.get(0), null));
-        Assert.assertEquals(cae.getAggregate(), null);
-    }
-
-    @Test
-    public void testAveragingEnricherWhenNoAndNullSensorValuesExplicit() {
-        List<TestEntity> producers = ImmutableList.of(
-                app.createAndManageChild(EntitySpec.create(TestEntity.class))
-                );
-        CustomAggregatingEnricher<Integer, Double> cae = CustomAggregatingEnricher.<Integer>newAveragingEnricher(
-                ImmutableMap.of("producers", producers), intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5d /** if none */);
-        producer.enrichers().add(cae);
-        
-        assertEquals(cae.getAggregate(), 3d);
-        cae.onEvent(intSensor.newEvent(producers.get(0), null));
-        assertEquals(cae.getAggregate(), 3d);
-        cae.onEvent(intSensor.newEvent(producers.get(0), 4));
-        assertEquals(cae.getAggregate(), 4d);
-    }
-
-    @Test
-    public void testAveragingEnricherWhenNoSensors() {
-        List<TestEntity> producers = ImmutableList.of(
-                );
-        CustomAggregatingEnricher<Integer, Double> cae = CustomAggregatingEnricher.<Integer>newAveragingEnricher(
-                ImmutableMap.of("producers", producers), intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5d /** if none */);
-        producer.enrichers().add(cae);
-        
-        assertEquals(cae.getAggregate(), 5d);
-    }
-
-    @Test
-    public void testMultipleProducersAverage() {
-        List<TestEntity> producers = ImmutableList.of(
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)), 
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)),
-                app.createAndManageChild(EntitySpec.create(TestEntity.class))
-                );
-        CustomAggregatingEnricher<Double, Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
-                ImmutableMap.of("producers", producers),
-                doubleSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null);
-        
-        producer.enrichers().add(cae);
-        
-        Assert.assertEquals(cae.getAggregate(), null);
-        cae.onEvent(doubleSensor.newEvent(producers.get(0), 3d));
-        assertEquals(cae.getAggregate(), 3d);
-        
-        cae.onEvent(doubleSensor.newEvent(producers.get(1), 3d));
-        assertEquals(cae.getAggregate(), 3d);
-        
-        cae.onEvent(doubleSensor.newEvent(producers.get(2), 6d));
-        assertEquals(cae.getAggregate(), 4d);
-
-        // change p2's value to 7.5, average increase of 0.5.
-        cae.onEvent(doubleSensor.newEvent(producers.get(2), 7.5d));
-        assertEquals(cae.getAggregate(), 4.5d);
-    }
-    
-    @Test
-    public void testMultipleProducersAverageDefaultingZero() {
-        List<TestEntity> producers = ImmutableList.of(
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)), 
-                app.createAndManageChild(EntitySpec.create(TestEntity.class)),
-                app.createAndManageChild(EntitySpec.create(TestEntity.class))
-                );
-        CustomAggregatingEnricher<Double, Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
-                ImmutableMap.of("producers", producers),
-                doubleSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 0d, 0d);
-        
-        producer.enrichers().add(cae);
-        
-        assertEquals(cae.getAggregate(), 0d);
-        cae.onEvent(doubleSensor.newEvent(producers.get(0), 3d));
-        assertEquals(cae.getAggregate(), 1d);
-        
-        cae.onEvent(doubleSensor.newEvent(producers.get(1), 3d));
-        assertEquals(cae.getAggregate(), 2d);
-        
-        cae.onEvent(doubleSensor.newEvent(producers.get(2), 6d));
-        assertEquals(cae.getAggregate(), 4d);
-
-        // change p2's value to 7.5, average increase of 0.5.
-        cae.onEvent(doubleSensor.newEvent(producers.get(2), 7.5d));
-        assertEquals(cae.getAggregate(), 4.5d);
-    }
-    
-    @Test
-    public void testAddingAndRemovingProducers() {
-        TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); 
-        TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                ImmutableMap.of("producers", ImmutableList.of(p1)),
-                intSensor, target, null, null);
-
-        producer.enrichers().add(cae);
-        Assert.assertEquals(cae.getAggregate(), null);
-        
-        // Event by initial producer
-        cae.onEvent(intSensor.newEvent(p1, 1));
-        assertEquals(cae.getAggregate(), 1);
-        
-        // Add producer and fire event
-        cae.addProducer(p2);
-        cae.onEvent(intSensor.newEvent(p2, 4));
-        assertEquals(cae.getAggregate(), 5);
-        
-        cae.removeProducer(p2);
-        assertEquals(cae.getAggregate(), 1);
-    }
-    
-    @Test
-    public void testAggregatesNewMembersOfGroup() {
-        try {
-            BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
-            TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-            TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-            log.debug("created $group and the entities it will contain $p1 $p2");
-
-            CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                    ImmutableMap.of("allMembers", true),
-                    intSensor, target, 0, 0);
-            group.enrichers().add(cae);
-
-            assertEquals(cae.getAggregate(), 0);
-
-            group.addMember(p1);
-            p1.sensors().set(intSensor, 1);
-            aggregateIsEventually(cae, 1);
-
-            group.addMember(p2);
-            p2.sensors().set(intSensor, 2);
-            aggregateIsEventually(cae, 3);
-
-            group.removeMember(p2);
-            aggregateIsEventually(cae, 1);
-        } catch (Exception e) {
-            log.error("testAggregatesNewMembersOfGroup failed (now cleaning up): "+e);
-            throw e;
-        }
-    }
-    
-    @Test(groups = "Integration")
-    public void testAggregatesGroupMembersFiftyTimes() {
-        for (int i=0; i<50; i++) {
-            log.debug("testAggregatesNewMembersOfGroup $i");
-            testAggregatesNewMembersOfGroup();
-        }
-    }
-    
-    @Test
-    public void testAggregatesExistingMembersOfGroup() {
-        BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
-        TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); 
-        TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group)); 
-        group.addMember(p1);
-        group.addMember(p2);
-        p1.sensors().set(intSensor, 1);
-        Entities.manage(group);
-        
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                ImmutableMap.of("allMembers", true),
-                intSensor, target, null, null);
-        group.enrichers().add(cae);
-        
-        assertEquals(cae.getAggregate(), 1);
-
-        p2.sensors().set(intSensor, 2);
-        aggregateIsEventually(cae, 3);
-        
-        group.removeMember(p2);
-        aggregateIsEventually(cae, 1);
-    }
-    
-    @Test
-    public void testAppliesFilterWhenAggregatingMembersOfGroup() {
-        BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
-        TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        group.addMember(p1);
-        group.addMember(p2);
-        p1.sensors().set(intSensor, 1);
-        p2.sensors().set(intSensor, 2);
-        p3.sensors().set(intSensor, 4);
-        
-        final CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newSummingEnricher(
-                ImmutableMap.of("allMembers", true, "filter", Predicates.equalTo(p1)),
-                intSensor, target, null, null);
-        group.enrichers().add(cae);
-        
-        assertEquals(cae.getAggregate(), 1);
-        
-        group.addMember(p3);
-        Asserts.succeedsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), new Runnable() {
-            @Override
-            public void run() {
-                assertEquals(cae.getAggregate(), 1);
-            }
-        });
-    }
-    
-    @Test
-    public void testCustomAggregatingFunction() {
-        TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class)); 
-        Function<Collection<Integer>,Integer> aggregator = new Function<Collection<Integer>, Integer>() {
-            @Override
-            public Integer apply(Collection<Integer> c) {
-                int result = 0;
-                for (Integer it : c) {
-                    result += it*it;
-                }
-                return result;
-            }
-        };
-
-        CustomAggregatingEnricher<Integer, Integer> cae = CustomAggregatingEnricher.<Integer, Integer>newEnricher(
-                ImmutableMap.of("producers", ImmutableList.of(p1)),
-                intSensor, target, aggregator, 0);
-
-        producer.enrichers().add(cae);
-        assertEquals(cae.getAggregate(), 0);
-
-        // Event by producer
-        cae.onEvent(intSensor.newEvent(p1, 2));
-        assertEquals(cae.getAggregate(), 4);
-    }
-
-
-    private void assertEquals(Integer i1, int i2) {
-        Assert.assertEquals(i1, (Integer)i2);
-     }
-    private void assertEquals(Double i1, double i2) {
-        Assert.assertEquals(i1, i2);
-    }
-
-    private void aggregateIsEventually(final CustomAggregatingEnricher<Integer, Integer> cae, final int avg) {
-        ImmutableMap<String, Long> timeout = ImmutableMap.of("timeout", TIMEOUT_MS);
-
-        Asserts.succeedsEventually(timeout, new Runnable() {
-            @Override
-            public void run() {
-                assertEquals(cae.getAggregate(), avg);
-            }
-        });
-    }
-
-}