You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2020/11/17 17:50:38 UTC
[brooklyn-server] 01/03: correct DSL serialization problem and
allow $brooklyn:object to load registered types
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 <al...@cloudsoftcorp.com>
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;