Enrichers: support producer as Task for deferred supplier
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/9402f850 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/9402f850 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/9402f850 Branch: refs/heads/master Commit: 9402f8508c67fa520be4c1d67f9e0d18f82b589b Parents: f380b58 Author: Aled Sage <[email protected]> Authored: Thu Oct 15 16:34:57 2015 +0200 Committer: Aled Sage <[email protected]> Committed: Thu Oct 15 21:19:34 2015 +0100 ---------------------------------------------------------------------- .../brooklyn/enricher/stock/Enrichers.java | 13 +- .../stock/EnricherWithDeferredSupplierTest.java | 132 +++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9402f850/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 64da60b..2ce2b21 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 @@ -27,6 +27,7 @@ import java.util.Map; import java.util.Set; import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.sensor.EnricherSpec; @@ -493,6 +494,7 @@ public class Enrichers { protected final Boolean propagatingAll; protected final Iterable<? extends Sensor<?>> propagatingAllBut; protected Entity fromEntity; + protected Task<? extends Entity> fromEntitySupplier; public AbstractPropagatorBuilder(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) { super(Propagator.class); @@ -520,6 +522,10 @@ public class Enrichers { this.fromEntity = checkNotNull(val); return self(); } + public B from(Task<? extends Entity> val) { + this.fromEntitySupplier = checkNotNull(val); + return self(); + } @Override protected String getDefaultUniqueTag() { List<String> summary = MutableList.of(); @@ -539,11 +545,15 @@ public class Enrichers { summary.add("ALL_BUT:"+com.google.common.base.Joiner.on(",").join(allBut)); } - return "propagating["+fromEntity.getId()+":"+com.google.common.base.Joiner.on(",").join(summary)+"]"; + // TODO What to use as the entity id if using fromEntitySupplier? + String fromId = (fromEntity != null) ? fromEntity.getId() : fromEntitySupplier.getId(); + + return "propagating["+fromId+":"+com.google.common.base.Joiner.on(",").join(summary)+"]"; } public EnricherSpec<? extends Enricher> build() { return super.build().configure(MutableMap.builder() .putIfNotNull(Propagator.PRODUCER, fromEntity) + .putIfNotNull(Propagator.PRODUCER, fromEntitySupplier) .putIfNotNull(Propagator.SENSOR_MAPPING, propagating) .putIfNotNull(Propagator.PROPAGATING_ALL, propagatingAll) .putIfNotNull(Propagator.PROPAGATING_ALL_BUT, propagatingAllBut) @@ -555,6 +565,7 @@ public class Enrichers { return Objects.toStringHelper(this) .omitNullValues() .add("fromEntity", fromEntity) + .add("fromEntitySupplier", fromEntitySupplier) .add("propagating", propagating) .add("propagatingAll", propagatingAll) .add("propagatingAllBut", propagatingAllBut) http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9402f850/core/src/test/java/org/apache/brooklyn/enricher/stock/EnricherWithDeferredSupplierTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/EnricherWithDeferredSupplierTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnricherWithDeferredSupplierTest.java new file mode 100644 index 0000000..9727403 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnricherWithDeferredSupplierTest.java @@ -0,0 +1,132 @@ +/* + * 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.NoSuchElementException; +import java.util.concurrent.Callable; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.mgmt.TaskFactory; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.effector.EffectorTasks; +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.entity.EntityInternal; +import org.apache.brooklyn.core.entity.EntityPredicates; +import org.apache.brooklyn.core.location.SimulatedLocation; +import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; +import org.apache.brooklyn.core.sensor.BasicAttributeSensor; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.test.EntityTestUtils; +import org.apache.brooklyn.util.core.task.DeferredSupplier; +import org.apache.brooklyn.util.core.task.TaskBuilder; +import org.apache.brooklyn.util.exceptions.Exceptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class EnricherWithDeferredSupplierTest extends BrooklynAppUnitTestSupport { + + public static final Logger log = LoggerFactory.getLogger(EnricherWithDeferredSupplierTest.class); + + protected static final ConfigKey<String> TAG = ConfigKeys.newStringConfigKey("mytag"); + + TestEntity producer; + TestEntity target; + AttributeSensor<Integer> sensor; + + @Test + public void testProducerUsingDeferredSupplier() throws Exception { + producer = app.createAndManageChild(EntitySpec.create(TestEntity.class) + .configure(TAG, "myproducer")); + target = app.createAndManageChild(EntitySpec.create(TestEntity.class)); + sensor = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a"); + + app.start(ImmutableList.of(new SimulatedLocation())); + + producer.sensors().set(sensor, 3); + + target.enrichers().add(Enrichers.builder() + .propagating(sensor) + .from(new EntityDeferredSupplier("myproducer").newTask()) + .build()); + + EntityTestUtils.assertAttributeEqualsEventually(target, sensor, 3); + } + + // TODO This is a cut-down version of DslComponent, from the camp project + public static class EntityDeferredSupplier implements DeferredSupplier<Entity>, TaskFactory<Task<Entity>> { + + private static final Logger log = LoggerFactory.getLogger(EntityDeferredSupplier.class); + + private final String tag; + + EntityDeferredSupplier(String tag) { + this.tag = tag; + } + + protected final static EntityInternal entity() { + // rely on implicit ThreadLocal for now + return (EntityInternal) EffectorTasks.findEntity(); + } + + @Override + public final synchronized Entity get() { + try { + if (log.isDebugEnabled()) + log.debug("Queuing task to resolve child "+tag); + Entity result = Entities.submit(entity(), newTask()).get(); + if (log.isDebugEnabled()) + log.debug("Resolved "+result+" from child "+tag); + return result; + } catch (Exception e) { + throw Exceptions.propagate(e); + } + } + + @Override + public Task<Entity> newTask() { + return TaskBuilder.<Entity>builder() + .displayName(toString()) + .tag(BrooklynTaskTags.TRANSIENT_TASK_TAG) + .body(new Callable<Entity>() { + public Entity call() { + EntityInternal entity = entity(); + Collection<Entity> entitiesToSearch = entity.getManagementContext().getEntityManager().getEntities(); + Optional<Entity> result = Iterables.tryFind(entitiesToSearch, EntityPredicates.configEqualTo(TAG, tag)); + + if (result.isPresent()) { + return result.get(); + } else { + throw new NoSuchElementException("No entity matching id " + tag+" in "+entitiesToSearch); + } + }}) + .build(); + } + } +}
