This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit ff24c90745b8e94657e095539f3c8c0fe01cdccb Author: Alex Heneveld <[email protected]> AuthorDate: Tue Nov 17 17:25:43 2020 +0000 correct DSL serialization problem and allow $brooklyn:object to load registered types --- .../brooklyn/spi/dsl/DslDeferredFunctionCall.java | 27 ++++++++++++++-------- .../spi/dsl/methods/BrooklynDslCommon.java | 22 +++++++++++++++++- .../spi/dsl/methods/DslToStringHelpers.java | 2 +- .../brooklyn/util/core/ClassLoaderUtils.java | 10 ++++++-- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java index 30b8416..9ef74d0 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java @@ -30,6 +30,7 @@ import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslToStringHelpers; import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; import org.apache.brooklyn.util.core.task.ImmediateSupplier; import org.apache.brooklyn.util.core.task.Tasks; +import org.apache.brooklyn.util.core.task.ValueResolver; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.javalang.Reflections; @@ -84,7 +85,7 @@ public class DslDeferredFunctionCall extends BrooklynDslDeferredSupplier<Object> } protected Maybe<Object> invokeOnDeferred(Object obj, boolean immediate) { - Maybe<?> resolvedMaybe = resolve(obj, immediate); + Maybe<?> resolvedMaybe = resolve(obj, immediate, true); if (resolvedMaybe.isPresent()) { Object instance = resolvedMaybe.get(); @@ -93,7 +94,11 @@ public class DslDeferredFunctionCall extends BrooklynDslDeferredSupplier<Object> object + " evaluates to null (wanting to call " + toStringF(fnName, args) + ")"); } - return invokeOn(instance); + Maybe<Object> tentative = invokeOn(instance); + if (tentative.isAbsent()) { + return tentative; + } + return (Maybe) resolve(tentative.get(), immediate, false); } else { if (immediate) { return Maybe.absent(new ImmediateSupplier.ImmediateValueNotAvailableException("Could not evaluate immediately: " + obj)); @@ -183,13 +188,17 @@ public class DslDeferredFunctionCall extends BrooklynDslDeferredSupplier<Object> } } - protected Maybe<?> resolve(Object object, boolean immediate) { - return Tasks.resolving(object, Object.class) - .context(entity().getExecutionContext()) - .deep() - .immediately(immediate) - .iterator() - .nextOrLast(DslFunctionSource.class); + protected Maybe<?> resolve(Object object, boolean immediate, boolean dslFunctionSource) { + ValueResolver<Object> r = Tasks.resolving(object, Object.class) + .context(entity().getExecutionContext()) + .deep() + .immediately(immediate); + if (dslFunctionSource) { + return r.iterator() + .nextOrLast(DslFunctionSource.class); + } else { + return r.getMaybe(); + } } private static void checkCallAllowed(Method m) { diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java index d027b30..fa96c84 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import java.util.*; +import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils; import static org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils.resolved; @@ -45,6 +46,7 @@ import org.apache.brooklyn.core.config.external.ExternalConfigSupplier; import org.apache.brooklyn.core.entity.EntityDynamicType; import org.apache.brooklyn.core.entity.EntityInternal; import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; +import org.apache.brooklyn.core.mgmt.classloading.OsgiBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.internal.ExternalConfigSupplierRegistry; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider; @@ -52,6 +54,7 @@ import org.apache.brooklyn.core.objs.AbstractConfigurationSupportInternal; import org.apache.brooklyn.core.objs.BrooklynObjectInternal; import org.apache.brooklyn.core.resolve.jackson.BrooklynJacksonSerializationUtils; import org.apache.brooklyn.core.sensor.DependentConfiguration; +import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.apache.brooklyn.util.collections.Jsonya; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; @@ -68,6 +71,7 @@ import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.javalang.Reflections; import org.apache.brooklyn.util.javalang.coerce.TypeCoercer; import org.apache.brooklyn.util.net.Urls; +import org.apache.brooklyn.util.os.Os; import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes; import org.apache.brooklyn.util.yaml.Yamls; import org.apache.commons.beanutils.BeanUtils; @@ -328,7 +332,7 @@ public class BrooklynDslCommon { try { type = new ClassLoaderUtils(BrooklynDslCommon.class).loadClass(mappedTypeName); } catch (ClassNotFoundException e) { - LOG.debug("Cannot load class " + typeName + " for DLS object; assuming it is in OSGi bundle; will defer its loading"); + LOG.debug("Cannot load class " + typeName + " for DSL 'object'; assuming it is in OSGi bundle; will defer its loading"); return new DslObject(mappedTypeName, constructorArgs, objectFields, brooklynConfig); } @@ -667,6 +671,9 @@ public class BrooklynDslCommon { @Override @JsonIgnore public Maybe<Object> getImmediately() { + // TODO reconcile with "bean-with-type" usage and constructors; + // for now, if it's a registered type we use that to get the java instance but we ignore fields on it + final Class<?> clazz = getOrLoadType(); final ExecutionContext executionContext = entity().getExecutionContext(); @@ -720,6 +727,8 @@ public class BrooklynDslCommon { .body(new Callable<Object>() { @Override public Object call() throws Exception { + // TODO de-dupe with getImmediately + Map<String, Object> resolvedFields = MutableMap.copyOf(Maps.transformValues(fields, resolver)); Map<String, Object> resolvedConfig = MutableMap.copyOf(Maps.transformValues(config, resolver)); List<Object> resolvedConstructorArgs = MutableList.copyOf(Lists.transform(constructorArgs, resolver)); @@ -737,12 +746,23 @@ public class BrooklynDslCommon { @JsonIgnore protected Class<?> getOrLoadType() { Class<?> type = this.type; + if (type == null) { EntityInternal entity = entity(); try { if (entity==null) { throw new IllegalStateException("Cannot invoke without a Task running the context of an entity"); } + RegisteredType rt = managementContext().getTypeRegistry().get(typeName, RegisteredTypeLoadingContexts.loader(new OsgiBrooklynClassLoadingContext(entity))); + if (rt!=null) { + Object inst = managementContext().getTypeRegistry().create(rt, null, null); + if (inst!=null) { + // we ignore the actually instance for now; see comments at start of this class + return inst.getClass(); + } + } + + // fall back to trying to load as a class type = new ClassLoaderUtils(BrooklynDslCommon.class, entity).loadClass(typeName); } catch (ClassNotFoundException e) { throw Exceptions.propagate(e); diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslToStringHelpers.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslToStringHelpers.java index 03b1a33..8bf4460 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslToStringHelpers.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslToStringHelpers.java @@ -44,7 +44,7 @@ public class DslToStringHelpers { } /** convenience for functions, inserting parentheses and commas */ - public static String fn(String functionName, Iterable<Object> args) { + public static String fn(String functionName, Iterable<?> args) { StringBuilder out = new StringBuilder(); out.append(BrooklynDslCommon.PREFIX); out.append(functionName); diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java index 91dc577..db80482 100644 --- a/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java +++ b/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java @@ -287,8 +287,14 @@ public class ClassLoaderUtils { CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, catalogItemId); if (item != null) { BrooklynClassLoadingContextSequential loader = new BrooklynClassLoadingContextSequential(mgmt); - loader.add(newClassLoadingContextForCatalogItems(mgmt, item.getCatalogItemId(), - item.getCatalogItemIdSearchPath())); + try { + loader.add(newClassLoadingContextForCatalogItems(mgmt, item.getCatalogItemId(), + item.getCatalogItemIdSearchPath())); + } catch (UnsupportedOperationException e) { + // normal if item comes from the type; could suppress load attempt + } catch (Exception e) { + log.warn("Error accessing looking up "+className+" relative to "+catalogItemId+" (ignoring, will try loading other ways but may fail): "+e, e); + } cls = dispatcher.tryLoadFrom(loader, className); if (cls.isPresent()) { return cls;
