You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2017/08/03 15:24:14 UTC
[2/3] brooklyn-server git commit: UpdatingMap: fix synchronisation
UpdatingMap: fix synchronisation
Delegate to ServiceStateLogic.updateMapSensorEntry, to use a
`modify` operation.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/b91f03b7
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/b91f03b7
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/b91f03b7
Branch: refs/heads/master
Commit: b91f03b71283e751250beec7ec5e11cdf9f240c1
Parents: af44b6d
Author: Aled Sage <al...@gmail.com>
Authored: Thu Aug 3 15:53:23 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 3 15:53:45 2017 +0100
----------------------------------------------------------------------
.../brooklyn/enricher/stock/UpdatingMap.java | 41 ++++-------
.../enricher/stock/UpdatingMapTest.java | 71 ++++++++++++++++++--
2 files changed, 79 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b91f03b7/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
index c74423e..acd4dbd 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
@@ -70,16 +70,24 @@ public class UpdatingMap<S,TKey,TVal> extends AbstractEnricher implements Sensor
@SetFromFlag("fromSensor")
public static final ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
+
@SetFromFlag("targetSensor")
public static final ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+
@SetFromFlag("key")
public static final ConfigKey<Object> KEY_IN_TARGET_SENSOR = ConfigKeys.newConfigKey(Object.class, "enricher.updatingMap.keyInTargetSensor",
"Key to update in the target sensor map, defaulting to the name of the source sensor");
+
@SetFromFlag("computing")
- public static final ConfigKey<Function<?, ?>> COMPUTING = ConfigKeys.newConfigKey(new TypeToken<Function<?,?>>() {}, "enricher.updatingMap.computing");
+ public static final ConfigKey<Function<?, ?>> COMPUTING = ConfigKeys.newConfigKey(
+ new TypeToken<Function<?,?>>() {},
+ "enricher.updatingMap.computing");
+
@SetFromFlag("removingIfResultIsNull")
- public static final ConfigKey<Boolean> REMOVING_IF_RESULT_IS_NULL = ConfigKeys.newBooleanConfigKey("enricher.updatingMap.removingIfResultIsNull",
- "Whether the key in the target map is removed if the result if the computation is null");
+ public static final ConfigKey<Boolean> REMOVING_IF_RESULT_IS_NULL = ConfigKeys.newBooleanConfigKey(
+ "enricher.updatingMap.removingIfResultIsNull",
+ "Whether the key in the target map is removed if the result if the computation is null",
+ Boolean.TRUE);
protected Entity producer;
protected AttributeSensor<S> sourceSensor;
@@ -139,37 +147,16 @@ public class UpdatingMap<S,TKey,TVal> extends AbstractEnricher implements Sensor
protected void onUpdated() {
try {
Object v = computing.apply(producer.getAttribute(sourceSensor));
- if (v == null && !Boolean.FALSE.equals(removingIfResultIsNull)) {
+ if (v == null && Boolean.TRUE.equals(removingIfResultIsNull)) {
v = Entities.REMOVE;
}
if (v == Entities.UNCHANGED) {
// nothing
} else {
- // TODO check synchronization
TKey key = this.key;
if (key==null) key = (TKey) sourceSensor.getName();
-
- Map<TKey, TVal> map = entity.getAttribute(targetSensor);
- boolean created = (map==null);
- if (created) map = MutableMap.of();
-
- boolean changed;
- if (v == Entities.REMOVE) {
- changed = map.containsKey(key);
- if (changed)
- map.remove(key);
- } else {
- TVal oldV = map.get(key);
- if (oldV==null)
- changed = (v!=null || !map.containsKey(key));
- else
- changed = !oldV.equals(v);
- if (changed)
- map.put(key, (TVal)v);
- }
- if (changed || created)
- emit(targetSensor, map);
+ ServiceStateLogic.updateMapSensorEntry(entity, targetSensor, key, (TVal) v);
}
} catch (Throwable t) {
LOG.warn("Error calculating map update for enricher "+this, t);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b91f03b7/core/src/test/java/org/apache/brooklyn/enricher/stock/UpdatingMapTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/UpdatingMapTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/UpdatingMapTest.java
index 801d4fa..c0e36e1 100644
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/UpdatingMapTest.java
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/UpdatingMapTest.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.sensor.Sensors;
@@ -42,12 +43,21 @@ import org.apache.brooklyn.util.collections.MutableMap;
import org.testng.annotations.Test;
import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import com.google.common.reflect.TypeToken;
public class UpdatingMapTest extends BrooklynAppUnitTestSupport {
+ protected AttributeSensor<Object> mySensor = Sensors.newSensor(Object.class, "mySensor");
+
+ @SuppressWarnings("serial")
+ protected AttributeSensor<Map<String,Object>> mapSensor = Sensors.newSensor(
+ new TypeToken<Map<String,Object>>() {},
+ "mapSensor");
+
@Test
public void testUpdateServiceNotUpIndicator() throws Exception {
AttributeSensor<Object> extraIsUpSensor = Sensors.newSensor(Object.class, "extraIsUp");
@@ -78,13 +88,7 @@ public class UpdatingMapTest extends BrooklynAppUnitTestSupport {
}
@Test
- @SuppressWarnings("serial")
public void testUpdateMapUsingDifferentProducer() throws Exception {
- AttributeSensor<Object> mySensor = Sensors.newSensor(Object.class, "mySensor");
- AttributeSensor<Map<String,Object>> mapSensor = Sensors.newSensor(
- new TypeToken<Map<String,Object>>() {},
- "mapSensor");
-
Entity producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
Entity entity = app.createAndManageChild(EntitySpec.create(BasicApplication.class)
@@ -101,6 +105,61 @@ public class UpdatingMapTest extends BrooklynAppUnitTestSupport {
EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of("myKey", "valIsV1"));
}
+ @Test
+ public void testUpdateMapEmitsEventOnChange() throws Exception {
+ Entity entity = app.createAndManageChild(EntitySpec.create(BasicApplication.class)
+ .enricher(EnricherSpec.create(UpdatingMap.class)
+ .configure(UpdatingMap.SOURCE_SENSOR.getName(), mySensor.getName())
+ .configure(UpdatingMap.TARGET_SENSOR, mapSensor)
+ .configure(UpdatingMap.KEY_IN_TARGET_SENSOR, "myKey")
+ .configure(UpdatingMap.COMPUTING, Functions.forMap(MutableMap.of("v1", "valIsV1", "v2", "valIsV2"), "myDefault"))));
+
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of("myKey", "myDefault"));
+
+ RecordingSensorEventListener<Map<String, Object>> listener = new RecordingSensorEventListener<>();
+ app.subscriptions().subscribe(entity, mapSensor, listener);
+
+ entity.sensors().set(mySensor, "v1");
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of("myKey", "valIsV1"));
+
+ listener.assertHasEventEventually(Predicates.alwaysTrue());
+ assertEquals(Iterables.getOnlyElement(listener.getEventValues()), ImmutableMap.of("myKey", "valIsV1"));
+ }
+
+ @Test
+ public void testRemovingIfResultIsNull() throws Exception {
+ Entity entity = app.createAndManageChild(EntitySpec.create(BasicApplication.class)
+ .enricher(EnricherSpec.create(UpdatingMap.class)
+ .configure(UpdatingMap.SOURCE_SENSOR.getName(), mySensor.getName())
+ .configure(UpdatingMap.TARGET_SENSOR, mapSensor)
+ .configure(UpdatingMap.REMOVING_IF_RESULT_IS_NULL, true)
+ .configure(UpdatingMap.COMPUTING, Functions.forMap(MutableMap.of("v1", "valIsV1"), null))));
+
+
+ entity.sensors().set(mySensor, "v1");
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of("mySensor", "valIsV1"));
+
+ entity.sensors().set(mySensor, "different");
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of());
+ }
+
+ @Test
+ public void testNotRemovingIfResultIsNull() throws Exception {
+ Entity entity = app.createAndManageChild(EntitySpec.create(BasicApplication.class)
+ .enricher(EnricherSpec.create(UpdatingMap.class)
+ .configure(UpdatingMap.SOURCE_SENSOR.getName(), mySensor.getName())
+ .configure(UpdatingMap.TARGET_SENSOR, mapSensor)
+ .configure(UpdatingMap.REMOVING_IF_RESULT_IS_NULL, false)
+ .configure(UpdatingMap.COMPUTING, Functions.forMap(MutableMap.of("v1", "valIsV1"), null))));
+
+
+ entity.sensors().set(mySensor, "v1");
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, ImmutableMap.of("mySensor", "valIsV1"));
+
+ entity.sensors().set(mySensor, "different");
+ EntityAsserts.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.of("mySensor", null));
+ }
+
private void assertMapSensorContainsEventually(Entity entity, AttributeSensor<? extends Map<?, ?>> mapSensor, Map<?, ?> expected) {
Asserts.succeedsEventually(new Runnable() {
@Override public void run() {