brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [1/2] brooklyn-server git commit: Add AbstractTransformer.ALLOW_CYCLIC_PUBLISHING
Date Thu, 09 Jun 2016 09:04:52 GMT
Repository: brooklyn-server
Updated Branches:
  refs/heads/master 88df98d5a -> 0150e2b7c


Add AbstractTransformer.ALLOW_CYCLIC_PUBLISHING

If set to true, then allows the transformer to read and publish on the
same sensor. This is needed for some use-cases in
brooklyncentral/advanced-networking.


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

Branch: refs/heads/master
Commit: 544c73e9700969471bef872722b555e1435db058
Parents: 8dc292b
Author: Aled Sage <aled.sage@gmail.com>
Authored: Thu Jun 9 01:06:10 2016 +0100
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Thu Jun 9 10:03:37 2016 +0100

----------------------------------------------------------------------
 .../enricher/stock/AbstractTransformer.java     | 30 +++++++++++-----
 .../stock/TransformingEnricherTest.java         | 38 ++++++++++++++++----
 2 files changed, 54 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/544c73e9/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
index a9c6d07..ca68266 100644
--- a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
@@ -59,6 +59,14 @@ public abstract class AbstractTransformer<T,U> extends AbstractEnricher
implemen
             "Sensors that will trigger re-evaluation",
             ImmutableList.<Sensor<?>>of());
 
+    public static final ConfigKey<Boolean> ALLOW_CYCLIC_PUBLISHING = ConfigKeys.newBooleanConfigKey(
+            "enricher.allowCyclicPublishing",
+            "Whether to all a transformer to publish to the same sensor (on the same entity)
to "
+                    + "which it's subscribed, thus risking an infinite loop. Defaults to
false. "
+                    + "Use with caution (e.g. if transformer implementation is very selective
about "
+                    + "when to publish, filters out duplicates, etc",
+            false);
+
     protected Entity producer;
     protected Sensor<T> sourceSensor;
     protected Sensor<U> targetSensor;
@@ -84,14 +92,20 @@ public abstract class AbstractTransformer<T,U> extends AbstractEnricher
implemen
             throw new IllegalArgumentException("Enricher "+JavaClassNames.simpleClassName(this)+"
has no "+SOURCE_SENSOR.getName()+" and no "+TRIGGER_SENSORS.getName());
         }
         if (producer.equals(entity) && (targetSensor.equals(sourceSensor) || triggerSensors.contains(targetSensor)))
{
-            // We cannot call getTransformation() here to log the tranformation, as it will
attempt
-            // to resolve the transformation, which will cause the entity initialization
thread to block
-            LOG.error("Refusing to add an enricher which reads and publishes on the same
sensor: "+
-                producer+"->"+targetSensor+" (computing transformation with "+JavaClassNames.simpleClassName(this)+")");
-            // we don't throw because this error may manifest itself after a lengthy deployment,

-            // and failing it at that point simply because of an enricher is not very pleasant
-            // (at least not until we have good re-run support across the board)
-            return;
+            boolean allowCyclicPublishing = Boolean.TRUE.equals(getConfig(ALLOW_CYCLIC_PUBLISHING));
+            if (allowCyclicPublishing) {
+                LOG.debug("Permitting cyclic publishing, though detected enricher will read
and publish on the same sensor: "+
+                    producer+"->"+targetSensor+" (computing transformation with "+JavaClassNames.simpleClassName(this)+")");
+            } else {
+                // We cannot call getTransformation() here to log the tranformation, as it
will attempt
+                // to resolve the transformation, which will cause the entity initialization
thread to block
+                LOG.error("Refusing to add an enricher which reads and publishes on the same
sensor: "+
+                    producer+"->"+targetSensor+" (computing transformation with "+JavaClassNames.simpleClassName(this)+")");
+                // we don't throw because this error may manifest itself after a lengthy
deployment, 
+                // and failing it at that point simply because of an enricher is not very
pleasant
+                // (at least not until we have good re-run support across the board)
+                return;
+            }
         }
         
         if (sourceSensor != null) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/544c73e9/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
index e47d268..591446d 100644
--- a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
@@ -24,6 +24,7 @@ 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.api.sensor.Sensor;
+import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityAsserts;
 import org.apache.brooklyn.core.location.SimulatedLocation;
 import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
@@ -46,7 +47,10 @@ import com.google.common.collect.ImmutableMap;
 public class TransformingEnricherTest extends BrooklynAppUnitTestSupport {
 
     public static final Logger log = LoggerFactory.getLogger(TransformingEnricherTest.class);
-            
+
+    private static final Duration SHORT_WAIT = Duration.millis(250);
+    private static final Duration VERY_SHORT_WAIT = Duration.millis(100);
+    
     TestEntity producer;
     AttributeSensor<Integer> intSensorA;
     AttributeSensor<Integer> intSensorB;
@@ -175,7 +179,7 @@ public class TransformingEnricherTest extends BrooklynAppUnitTestSupport
{
 
         // Short wait; expect us to never re-publish the source-sensor as that would cause
infinite loop.
         producer.sensors().set(intSensorA, 1);
-        EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", Duration.millis(250)),
producer, intSensorA, 1);
+        EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT),
producer, intSensorA, 1);
     }
     
     @Test
@@ -194,7 +198,7 @@ public class TransformingEnricherTest extends BrooklynAppUnitTestSupport
{
                     }}));
 
         producer.sensors().set(intSensorA, 1);
-        EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", Duration.millis(250)),
producer, intSensorA, 1);
+        EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT),
producer, intSensorA, 1);
     }
     
     @Test
@@ -225,17 +229,39 @@ public class TransformingEnricherTest extends BrooklynAppUnitTestSupport
{
         EntityAsserts.assertAttributeEqualsEventually(app, intSensorA, 3);
     }
 
+    @Test
+    public void testAllowCyclicPublishing() throws Exception {
+        app.enrichers().add(EnricherSpec.create(Transformer.class)
+                .configure(Transformer.SOURCE_SENSOR, intSensorA)
+                .configure(Transformer.TARGET_SENSOR, intSensorA)
+                .configure(Transformer.ALLOW_CYCLIC_PUBLISHING, true)
+                .configure(Transformer.TRANSFORMATION_FROM_VALUE, new Function<Integer,
Object>() {
+                    @Override public Object apply(Integer input) {
+                        if (input != null && input < 10) {
+                            return input + 1;
+                        } else {
+                            return Entities.UNCHANGED;
+                        }
+                    }}));
+
+        app.sensors().set(intSensorA, 3);
+
+        EntityAsserts.assertAttributeEqualsEventually(app, intSensorA, 10);
+        EntityAsserts.assertAttributeEqualsContinually(ImmutableMap.of("timeout", VERY_SHORT_WAIT),
app, intSensorA, 10);
+    }
+
+    @Test
     public void testTransformerFailsWithEmptyConfig() throws Exception {
         EnricherSpec<?> spec = EnricherSpec.create(Transformer.class);
 
-        assertAddEnricherThrowsNullPointerException(spec, "Value required");
+        assertAddEnricherThrowsIllegalArgumentException(spec, "Transformer has no");
     }
     
-    private void assertAddEnricherThrowsNullPointerException(EnricherSpec<?> spec,
String expectedPhrase) {
+    private void assertAddEnricherThrowsIllegalArgumentException(EnricherSpec<?> spec,
String expectedPhrase) {
         try {
             app.enrichers().add(spec);
             Asserts.shouldHaveFailedPreviously();
-        } catch (NullPointerException e) {
+        } catch (IllegalArgumentException e) {
             Asserts.expectedFailureContains(e, expectedPhrase);
         }
     }


Mime
View raw message