better REST coercion and coerce String->Date wrt REST this improves how deferred suppliers are evaluated, both timing and in entity's execution context
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/30c3029e Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/30c3029e Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/30c3029e Branch: refs/heads/master Commit: 30c3029ef22bb387ef121cc043bcfd495cfc9837 Parents: 9fe4c7c Author: Alex Heneveld <[email protected]> Authored: Thu Jun 4 16:53:41 2015 +0100 Committer: Alex Heneveld <[email protected]> Committed: Wed Jun 10 18:38:17 2015 +0100 ---------------------------------------------------------------------- .../java/brooklyn/catalog/BrooklynCatalog.java | 1 + .../brooklyn/config/render/RendererHints.java | 10 +-- .../brooklyn/enricher/basic/Transformer.java | 3 +- .../java/brooklyn/util/flags/TypeCoercions.java | 8 +++ .../java/brooklyn/util/task/ValueResolver.java | 11 +++ .../resources/AbstractBrooklynRestResource.java | 72 +++++++++++++++++--- .../rest/resources/EffectorResource.java | 2 +- .../rest/resources/EntityConfigResource.java | 15 ++-- .../brooklyn/rest/resources/EntityResource.java | 4 +- .../brooklyn/rest/resources/SensorResource.java | 13 ++-- .../brooklyn/rest/resources/UsageResource.java | 2 +- .../rest/transform/EffectorTransformer.java | 2 +- 12 files changed, 102 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java b/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java index 82b865d..19d0fa9 100644 --- a/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java +++ b/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java @@ -75,6 +75,7 @@ public interface BrooklynCatalog { public ClassLoader getRootClassLoader(); /** creates a spec for the given catalog item, throwing exceptions if any problems */ + // TODO this should be cached on the item and renamed getSpec(...), else we re-create it too often (every time catalog is listed) <T,SpecT> SpecT createSpec(CatalogItem<T,SpecT> item); /** throws exceptions if any problems http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/core/src/main/java/brooklyn/config/render/RendererHints.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/config/render/RendererHints.java b/core/src/main/java/brooklyn/config/render/RendererHints.java index 247b4f4..60f89d7 100644 --- a/core/src/main/java/brooklyn/config/render/RendererHints.java +++ b/core/src/main/java/brooklyn/config/render/RendererHints.java @@ -113,13 +113,15 @@ public class RendererHints { } /** Applies the (first) display value hint registered against the given target to the given initialValue */ - public static Object applyDisplayValueHint(AttributeSensor<?> target, Object initialValue) { return _applyDisplayValueHint(target, initialValue); } + public static Object applyDisplayValueHint(AttributeSensor<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } /** as {@link #applyDisplayValueHint(AttributeSensor, Object)} */ - public static Object applyDisplayValueHint(ConfigKey<?> target, Object initialValue) { return _applyDisplayValueHint(target, initialValue); } + public static Object applyDisplayValueHint(ConfigKey<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } /** as {@link #applyDisplayValueHint(AttributeSensor, Object)} */ - public static Object applyDisplayValueHint(Class<?> target, Object initialValue) { return _applyDisplayValueHint(target, initialValue); } + public static Object applyDisplayValueHint(Class<?> target, Object initialValue) { return applyDisplayValueHintUnchecked(target, initialValue); } - private static Object _applyDisplayValueHint(Object target, Object initialValue) { return _applyDisplayValueHint(target, initialValue, true); } + /** as {@link #applyDisplayValueHint(AttributeSensor, Object)}, but without type checking; public for those few cases where we may have lost the type */ + @Beta + public static Object applyDisplayValueHintUnchecked(Object target, Object initialValue) { return _applyDisplayValueHint(target, initialValue, true); } @SuppressWarnings("rawtypes") private static Object _applyDisplayValueHint(Object target, Object initialValue, boolean includeClass) { Iterable<RendererHints.DisplayValue> hints = RendererHints._getHintsFor(target, RendererHints.DisplayValue.class); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/core/src/main/java/brooklyn/enricher/basic/Transformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/enricher/basic/Transformer.java b/core/src/main/java/brooklyn/enricher/basic/Transformer.java index 224f201..c6c88a6 100644 --- a/core/src/main/java/brooklyn/enricher/basic/Transformer.java +++ b/core/src/main/java/brooklyn/enricher/basic/Transformer.java @@ -26,7 +26,6 @@ import org.slf4j.LoggerFactory; import brooklyn.config.ConfigKey; import brooklyn.entity.Entity; import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.basic.EntityLocal; import brooklyn.event.AttributeSensor; import brooklyn.event.Sensor; @@ -135,7 +134,7 @@ public class Transformer<T,U> extends AbstractEnricher implements SensorEventLis // external events; they can submit tasks and block on them (or even better, have a callback architecture); // however that is a non-trivial refactoring return (U) Tasks.resolving(targetValueRaw).as(targetSensor.getType()) - .context( ((EntityInternal)entity).getExecutionContext() ) + .context(entity) .description("Computing sensor "+targetSensor+" from "+targetValueRaw) .timeout(Duration.millis(200)) .getMaybe().orNull(); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/core/src/main/java/brooklyn/util/flags/TypeCoercions.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java index d93528a..dcc00e8 100644 --- a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java +++ b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java @@ -32,6 +32,7 @@ import java.net.InetAddress; import java.net.URI; import java.net.URL; import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -63,6 +64,7 @@ import brooklyn.util.net.UserAndHostAndPort; import brooklyn.util.text.StringEscapes.JavaStringEscapes; import brooklyn.util.text.Strings; import brooklyn.util.time.Duration; +import brooklyn.util.time.Time; import brooklyn.util.yaml.Yamls; import com.google.common.base.CaseFormat; @@ -695,6 +697,12 @@ public class TypeCoercions { return BigInteger.valueOf(input); } }); + registerAdapter(String.class, Date.class, new Function<String,Date>() { + @Override + public Date apply(final String input) { + return Time.parseDate(input); + } + }); registerAdapter(String.class, Class.class, new Function<String,Class>() { @Override public Class apply(final String input) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/core/src/main/java/brooklyn/util/task/ValueResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/util/task/ValueResolver.java b/core/src/main/java/brooklyn/util/task/ValueResolver.java index cf95650..3a15bbd 100644 --- a/core/src/main/java/brooklyn/util/task/ValueResolver.java +++ b/core/src/main/java/brooklyn/util/task/ValueResolver.java @@ -28,6 +28,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.EntityInternal; import brooklyn.management.ExecutionContext; import brooklyn.management.Task; import brooklyn.management.TaskAdaptable; @@ -130,6 +132,10 @@ public class ValueResolver<T> implements DeferredSupplier<T> { this.exec = exec; return this; } + /** as {@link #context(ExecutionContext)} for use from an entity */ + public ValueResolver<T> context(Entity entity) { + return context(entity!=null ? ((EntityInternal)entity).getExecutionContext() : null); + } /** sets a message which will be displayed in status reports while it waits (e.g. the name of the config key being looked up) */ public ValueResolver<T> description(String description) { @@ -279,6 +285,11 @@ public class ValueResolver<T> implements DeferredSupplier<T> { String description = getDescription(); Task<Object> vt = exec.submit(Tasks.<Object>builder().body(callable).name("Resolving dependent value").description(description).build()); + // TODO to handle immediate resolution, it would be nice to be able to submit + // so it executes in the current thread, + // or put a marker in the target thread or task while it is running that the task + // should never wait on anything other than another value being resolved + // (though either could recurse infinitely) Maybe<Object> vm = Durations.get(vt, timer); vt.cancel(true); if (vm.isAbsent()) return (Maybe<T>)vm; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/AbstractBrooklynRestResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/AbstractBrooklynRestResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/AbstractBrooklynRestResource.java index 0f49caf..d9dee55 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/AbstractBrooklynRestResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/AbstractBrooklynRestResource.java @@ -20,6 +20,7 @@ package brooklyn.rest.resources; import io.brooklyn.camp.CampPlatform; +import javax.annotation.Nullable; import javax.servlet.ServletContext; import javax.ws.rs.core.Context; @@ -27,6 +28,9 @@ import org.codehaus.jackson.map.ObjectMapper; import brooklyn.config.BrooklynServerConfig; import brooklyn.config.BrooklynServiceAttributes; +import brooklyn.config.render.RendererHints; +import brooklyn.entity.Entity; +import brooklyn.entity.basic.EntityLocal; import brooklyn.management.ManagementContext; import brooklyn.management.ManagementContextInjectable; import brooklyn.rest.util.BrooklynRestResourceUtils; @@ -36,13 +40,8 @@ import brooklyn.util.guava.Maybe; import brooklyn.util.task.Tasks; import brooklyn.util.time.Duration; -import com.google.common.annotations.VisibleForTesting; - public abstract class AbstractBrooklynRestResource implements ManagementContextInjectable { - @VisibleForTesting - public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ"; - // can be injected by jersey when ManagementContext in not injected manually // (seems there is no way to make this optional so note it _must_ be injected; // most of the time that happens for free, but with test framework it doesn't, @@ -85,15 +84,66 @@ public abstract class AbstractBrooklynRestResource implements ManagementContextI return mapper; } - /** returns an object which jersey will handle nicely, converting to json, - * sometimes wrapping in quotes if needed (for outermost json return types) */ + /** @deprecated since 0.7.0 use {@link #getValueForDisplay(Object, boolean, boolean, Boolean, EntityLocal, Duration)} */ @Deprecated protected Object getValueForDisplay(Object value, boolean preferJson, boolean isJerseyReturnValue) { - Object immediate = getImmediateValue(value); - return WebResourceUtils.getValueForDisplay(mapper(), immediate, preferJson, isJerseyReturnValue); + return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(isJerseyReturnValue).resolve(); + } + + protected RestValueResolver resolving(Object v) { + return new RestValueResolver(v).mapper(mapper()); } - private Object getImmediateValue(Object value) { - return Tasks.resolving(value).as(Object.class).defaultValue(null).timeout(Duration.ZERO).swallowExceptions().get(); + public static class RestValueResolver { + final private Object valueToResolve; + private @Nullable ObjectMapper mapper; + private boolean preferJson; + private boolean isJerseyReturnValue; + private @Nullable Boolean raw; + private @Nullable Entity entity; + private @Nullable Duration timeout; + private @Nullable Object rendererHintSource; + + public static RestValueResolver resolving(Object v) { return new RestValueResolver(v); } + + private RestValueResolver(Object v) { valueToResolve = v; } + + public RestValueResolver mapper(ObjectMapper mapper) { this.mapper = mapper; return this; } + + /** whether JSON is the ultimate product; + * main effect here is to give null for null if true, else to give empty string + * <p> + * conversion to JSON for complex types is done subsequently (often by the framework) + * <p> + * default is true */ + public RestValueResolver preferJson(boolean preferJson) { this.preferJson = preferJson; return this; } + /** whether an outermost string must be wrapped in quotes, because a String return object is treated as + * already JSON-encoded + * <p> + * default is false */ + public RestValueResolver asJerseyOutermostReturnValue(boolean asJerseyReturnJson) { + isJerseyReturnValue = asJerseyReturnJson; + return this; + } + public RestValueResolver raw(Boolean raw) { this.raw = raw; return this; } + public RestValueResolver context(Entity entity) { this.entity = entity; return this; } + public RestValueResolver timeout(Duration timeout) { this.timeout = timeout; return this; } + public RestValueResolver renderAs(Object rendererHintSource) { this.rendererHintSource = rendererHintSource; return this; } + + public Object resolve() { + Object valueResult = getImmediateValue(valueToResolve, entity); + if (valueResult==UNRESOLVED) valueResult = valueToResolve; + if (rendererHintSource!=null && Boolean.FALSE.equals(raw)) { + valueResult = RendererHints.applyDisplayValueHintUnchecked(rendererHintSource, valueResult); + } + return WebResourceUtils.getValueForDisplay(mapper, valueResult, preferJson, isJerseyReturnValue); + } + + private static Object UNRESOLVED = "UNRESOLVED".toCharArray(); + + private static Object getImmediateValue(Object value, @Nullable Entity context) { + return Tasks.resolving(value).as(Object.class).defaultValue(UNRESOLVED).timeout(Duration.ZERO).context(context).swallowExceptions().get(); + } + } protected CampPlatform camp() { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java index 2cfd8f6..69ded4e 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java @@ -98,7 +98,7 @@ public class EffectorResource extends AbstractBrooklynRestResource implements Ef if (timeout == null || timeout.isEmpty() || "never".equalsIgnoreCase(timeout)) { result = t.get(); } else { - long timeoutMillis = "always".equalsIgnoreCase(timeout) ? 0 : Time.parseTimeString(timeout); + long timeoutMillis = "always".equalsIgnoreCase(timeout) ? 0 : Time.parseElapsedTime(timeout); try { if (timeoutMillis == 0) throw new TimeoutException(); result = t.get(timeoutMillis, TimeUnit.MILLISECONDS); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java index 0984ebf..219d67a 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java @@ -27,7 +27,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import brooklyn.config.ConfigKey; -import brooklyn.config.render.RendererHints; import brooklyn.entity.Entity; import brooklyn.entity.basic.Entities; import brooklyn.entity.basic.EntityInternal; @@ -41,6 +40,7 @@ import brooklyn.rest.transform.EntityTransformer; import brooklyn.rest.util.WebResourceUtils; import brooklyn.util.flags.TypeCoercions; import brooklyn.util.text.Strings; +import brooklyn.util.time.Duration; import com.google.common.base.Function; import com.google.common.base.Predicates; @@ -55,7 +55,7 @@ public class EntityConfigResource extends AbstractBrooklynRestResource implement @Override public List<EntityConfigSummary> list(final String application, final String entityToken) { final EntityLocal entity = brooklyn().getEntity(application, entityToken); - + // TODO merge with keys which have values return Lists.newArrayList(transform( entity.getEntityType().getConfigKeys(), new Function<ConfigKey<?>, EntityConfigSummary>() { @@ -76,10 +76,8 @@ public class EntityConfigResource extends AbstractBrooklynRestResource implement Map<String, Object> result = Maps.newLinkedHashMap(); for (Map.Entry<ConfigKey<?>, ?> ek : source.entrySet()) { Object value = ek.getValue(); - if (Boolean.FALSE.equals(raw)) { - value = RendererHints.applyDisplayValueHint(ek.getKey(), value); - } - result.put(ek.getKey().getName(), getValueForDisplay(value, true, false)); + result.put(ek.getKey().getName(), + resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).raw(raw).context(entity).timeout(Duration.ZERO).renderAs(ek.getKey()).resolve()); } return result; } @@ -98,10 +96,7 @@ public class EntityConfigResource extends AbstractBrooklynRestResource implement EntityLocal entity = brooklyn().getEntity(application, entityToken); ConfigKey<?> ck = findConfig(entity, configKeyName); Object value = ((EntityInternal)entity).config().getRaw(ck).orNull(); - if (Boolean.FALSE.equals(raw)) { - value = RendererHints.applyDisplayValueHint(ck, value); - } - return getValueForDisplay(value, preferJson, true); + return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(true).raw(raw).context(entity).timeout(Duration.millis(100)).renderAs(ck).resolve(); } private ConfigKey<?> findConfig(EntityLocal entity, String configKeyName) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java index 3e94068..eb677e2 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java @@ -155,7 +155,7 @@ public class EntityResource extends AbstractBrooklynRestResource implements Enti @Override public List<Object> listTags(String applicationId, String entityId) { Entity entity = brooklyn().getEntity(applicationId, entityId); - return (List<Object>) getValueForDisplay(MutableList.copyOf(entity.tags().getTags()), true, true); + return (List<Object>) resolving(MutableList.copyOf(entity.tags().getTags())).preferJson(true).resolve(); } @Override @@ -220,6 +220,6 @@ public class EntityResource extends AbstractBrooklynRestResource implements Enti NamedStringTag spec = BrooklynTags.findFirst(BrooklynTags.YAML_SPEC_KIND, entity.tags().getTags()); if (spec == null) return null; - return (String) getValueForDisplay(spec.getContents(), true, true); + return (String) WebResourceUtils.getValueForDisplay(spec.getContents(), true, true); } } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java index 708685d..6e49acc 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java @@ -27,7 +27,6 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.config.render.RendererHints; import brooklyn.entity.basic.EntityInternal; import brooklyn.entity.basic.EntityLocal; import brooklyn.event.AttributeSensor; @@ -40,6 +39,7 @@ import brooklyn.rest.filter.HaHotStateRequired; import brooklyn.rest.transform.SensorTransformer; import brooklyn.rest.util.WebResourceUtils; import brooklyn.util.text.Strings; +import brooklyn.util.time.Duration; import com.google.common.base.Function; import com.google.common.collect.Lists; @@ -73,10 +73,8 @@ public class SensorResource extends AbstractBrooklynRestResource implements Sens for (AttributeSensor<?> sensor : sensors) { Object value = entity.getAttribute(findSensor(entity, sensor.getName())); - if (Boolean.FALSE.equals(raw)) { - value = RendererHints.applyDisplayValueHint(sensor, value); - } - sensorMap.put(sensor.getName(), getValueForDisplay(value, true, false)); + sensorMap.put(sensor.getName(), + resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).raw(raw).context(entity).timeout(Duration.ZERO).renderAs(sensor).resolve()); } return sensorMap; } @@ -85,10 +83,7 @@ public class SensorResource extends AbstractBrooklynRestResource implements Sens final EntityLocal entity = brooklyn().getEntity(application, entityToken); AttributeSensor<?> sensor = findSensor(entity, sensorName); Object value = entity.getAttribute(sensor); - if (Boolean.FALSE.equals(raw)) { - value = RendererHints.applyDisplayValueHint(sensor, value); - } - return getValueForDisplay(value, preferJson, true); + return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(true).raw(raw).context(entity).timeout(Duration.millis(100)).renderAs(sensor).resolve(); } @Override http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java index 88dfe3a..4251712 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java @@ -256,7 +256,7 @@ public class UsageResource extends AbstractBrooklynRestResource implements Usage } private Date parseDate(String toParse, Date def) { - return (toParse == null) ? def : Time.parseDateString(toParse, DATE_FORMATTER.get()); + return (toParse == null) ? def : Time.parseDate(toParse, DATE_FORMATTER.get()); } private String format(Date date) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30c3029e/usage/rest-server/src/main/java/brooklyn/rest/transform/EffectorTransformer.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/transform/EffectorTransformer.java b/usage/rest-server/src/main/java/brooklyn/rest/transform/EffectorTransformer.java index 1d15abe..925ed8f 100644 --- a/usage/rest-server/src/main/java/brooklyn/rest/transform/EffectorTransformer.java +++ b/usage/rest-server/src/main/java/brooklyn/rest/transform/EffectorTransformer.java @@ -76,7 +76,7 @@ public class EffectorTransformer { protected static EffectorSummary.ParameterSummary<?> parameterSummary(Entity entity, ParameterType<?> parameterType) { try { Maybe<?> defaultValue = Tasks.resolving(parameterType.getDefaultValue()).as(parameterType.getParameterClass()) - .context(entity!=null ? ((EntityInternal)entity).getExecutionContext() : null).timeout(Duration.millis(50)).getMaybe(); + .context(entity).timeout(Duration.millis(50)).getMaybe(); return new ParameterSummary(parameterType.getName(), parameterType.getParameterClassName(), parameterType.getDescription(), WebResourceUtils.getValueForDisplay(defaultValue.orNull(), true, false));
