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 b96795f7ae55f440d3e8c44ab155922571498307
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Feb 2 13:52:07 2023 +0000

    add type info support for effector parameters
---
 .../apache/brooklyn/core/config/ConfigKeys.java    | 31 +++++++++++++++++-----
 .../AddEffectorInitializerAbstractProto.java       |  4 ++-
 .../apache/brooklyn/core/effector/Effectors.java   | 24 +++++++++--------
 .../brooklyn/core/typereg/RegisteredTypes.java     | 16 +++++++++++
 .../core/workflow/WorkflowExecutionContext.java    |  3 ++-
 .../core/flags/BrooklynTypeNameResolution.java     | 18 ++++++++-----
 6 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java 
b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
index dc7dabb2a2..8982196e88 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
@@ -22,6 +22,7 @@ import java.util.Map;
 
 import javax.annotation.Nonnull;
 
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.config.ConfigInheritance.ConfigInheritanceContext;
 import org.apache.brooklyn.config.ConfigKey;
 import 
org.apache.brooklyn.core.config.BasicConfigKey.BasicConfigKeyOverwriting;
@@ -30,6 +31,7 @@ import 
org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
 import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
 import 
org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.flags.BrooklynTypeNameResolution;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
@@ -255,22 +257,34 @@ public class ConfigKeys {
     
     public static class DynamicKeys {
 
-        // TODO see below
-//        public static final ConfigKey<String> TYPE = 
ConfigKeys.newStringConfigKey("type");
+        public static final ConfigKey<Object> TYPE = 
ConfigKeys.newConfigKey(Object.class, "type", "type of this key or parameter, 
as a string or class or TypeToken");
         public static final ConfigKey<String> NAME = 
ConfigKeys.newStringConfigKey("name");
         public static final ConfigKey<String> DESCRIPTION = 
ConfigKeys.newStringConfigKey("description");
         public static final ConfigKey<Object> DEFAULT_VALUE = 
ConfigKeys.newConfigKey(Object.class, "defaultValue");
         
         public static ConfigKey<?> newInstance(ConfigBag keyDefs) {
-            String typeName = Strings.toString(keyDefs.getStringKey("type"));
-            if (Strings.isNonBlank(typeName)) {
+            return newInstance(keyDefs, null);
+        }
+        public static ConfigKey<?> newInstance(ConfigBag keyDefs, 
BrooklynClassLoadingContext loader) {
+            Object typeName = keyDefs.getStringKey("type");
+            TypeToken type = TypeToken.of(Object.class);
+            if (typeName!=null) {
+                if (typeName instanceof String) {
+                    type = new 
BrooklynTypeNameResolution.BrooklynTypeNameResolver("dynamic config key", 
loader, true, true)
+                            .getTypeToken((String) typeName);
+                } else if (typeName instanceof TypeToken) {
+                    type = (TypeToken) typeName;
+                } else if (typeName instanceof Class) {
+                    type = TypeToken.of((Class)typeName);
+                } else {
+                    throw new IllegalArgumentException("Invalid type 
definition for config key");
+                }
                 // could do dynamic typing - see TYPE key commented out above; 
also see AddSensor.getType for type lookup
                 // but we don't want that, because the rules for this are 
subtle (not universal), and
                 // it is implemented on jackson conversion instead, which 
coercion will do in some cases
 //                log.warn("Setting 'type' is not currently supported for 
dynamic config keys; ignoring in definition of "+keyDefs);
             }
-            
-            Class<Object> type = Object.class;
+
             String name = keyDefs.get(NAME);
             String description = keyDefs.get(DESCRIPTION);
             Object defaultValue = keyDefs.get(DEFAULT_VALUE);
@@ -284,11 +298,14 @@ public class ConfigKeys {
         
         /** creates a new {@link ConfigKey} given a name (e.g. as a key in a 
larger map) and a map of other definition attributes */
         public static ConfigKey<?> newNamedInstance(String name, Map<?,?> 
keyDefs) {
+            return newNamedInstance(name, keyDefs, null);
+        }
+        public static ConfigKey<?> newNamedInstance(String name, Map<?,?> 
keyDefs, BrooklynClassLoadingContext loader) {
             ConfigBag defs = ConfigBag.newInstance(keyDefs);
             String oldName = defs.put(NAME, name);
             if (oldName!=null && !oldName.equals(name))
                 log.warn("Dynamic key '"+oldName+"' being overridden as key 
'"+name+"' in "+keyDefs);
-            return newInstance(defs);
+            return newInstance(defs, loader);
         }
 
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/effector/AddEffectorInitializerAbstractProto.java
 
b/core/src/main/java/org/apache/brooklyn/core/effector/AddEffectorInitializerAbstractProto.java
index 7dce0e0cb7..e0940f902a 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/effector/AddEffectorInitializerAbstractProto.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/effector/AddEffectorInitializerAbstractProto.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.effector.ParameterType;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.MapConfigKey;
@@ -78,7 +79,8 @@ public abstract class AddEffectorInitializerAbstractProto 
extends EntityInitiali
         EffectorBuilder<T> eff = Effectors.effector(type, name);
         eff.description(params.get(EFFECTOR_DESCRIPTION));
 
-        
Effectors.parseParameters(params.get(EFFECTOR_PARAMETER_DEFS)).forEach(p -> 
eff.parameter(p));
+        BrooklynClassLoadingContext loader = null;  // we need an entity or 
mgmt context to get a loader, but we don't need to resolve the types so no big 
deal
+        Effectors.parseParameters(params.get(EFFECTOR_PARAMETER_DEFS), 
loader).forEach(p -> eff.parameter(p));
 
         return eff;
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java 
b/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
index 2daeb87159..670a7b5f2e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
@@ -18,15 +18,16 @@
  */
 package org.apache.brooklyn.core.effector;
 
-import java.util.*;
-import java.util.function.Consumer;
-
-import javax.annotation.Nullable;
-
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.effector.ParameterType;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory;
@@ -44,11 +45,9 @@ import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
+import javax.annotation.Nullable;
+import java.util.*;
+import java.util.function.Consumer;
 
 public class Effectors {
 
@@ -248,6 +247,9 @@ public class Effectors {
     }
 
     public static Collection<ParameterType<?>> 
parseParameters(Map<String,Object> paramDefs) {
+        return parseParameters(paramDefs, null);
+    }
+    public static Collection<ParameterType<?>> 
parseParameters(Map<String,Object> paramDefs, BrooklynClassLoadingContext 
loader) {
         Set<ParameterType<?>> result = MutableSet.of();
         if (paramDefs==null) return result;
 
@@ -263,7 +265,7 @@ public class Effectors {
                 if (!(value instanceof Map))
                     throw new IllegalArgumentException("Illegal argument of 
type "+value.getClass()+" value '"+value+"' supplied as parameter definition "
                             + "'"+paramName);
-                
result.add(Effectors.asParameterType(ConfigKeys.DynamicKeys.newNamedInstance(paramName,
 (Map<?, ?>) value)));
+                
result.add(Effectors.asParameterType(ConfigKeys.DynamicKeys.newNamedInstance(paramName,
 (Map<?, ?>) value, loader)));
             }
         }
         return result;
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java 
b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index ec88e89ae6..572cc26e9a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -38,6 +38,7 @@ import 
org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
 import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
 import org.apache.brooklyn.api.typereg.ManagedBundle;
@@ -48,6 +49,7 @@ import 
org.apache.brooklyn.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.EntityAdjuncts;
 import org.apache.brooklyn.core.mgmt.BrooklynTags;
 import org.apache.brooklyn.core.mgmt.BrooklynTags.NamedStringTag;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
@@ -796,6 +798,20 @@ public class RegisteredTypes {
         return CatalogUtils.getClassLoadingContext(entity);
     }
 
+    /** gets the loading context for the entity associated with a brooklyn 
object;
+     * throws if not possible.
+     *
+     * in future it might look at an adjunct's origin also, preferring that. */
+    public static Maybe<BrooklynClassLoadingContext> 
getClassLoadingContextMaybe(BrooklynObject bo) {
+        if (bo instanceof EntityAdjuncts.EntityAdjunctProxyable) {
+            bo = ((EntityAdjuncts.EntityAdjunctProxyable)bo).getEntity();
+        }
+        if (!(bo instanceof Entity)) {
+            return Maybe.absent("Unable to get loading context for "+bo);
+        }
+        return Maybe.of(CatalogUtils.getClassLoadingContext((Entity) bo));
+    }
+
     public static BrooklynClassLoadingContext 
getClassLoadingContext(ManagementContext mgmt, Entity optionalEntity) {
         return optionalEntity!=null ? 
CatalogUtils.getClassLoadingContext(optionalEntity) : 
JavaBrooklynClassLoadingContext.create(mgmt);
     }
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
index 2e9e0581d8..c05562c97e 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowExecutionContext.java
@@ -227,7 +227,8 @@ public class WorkflowExecutionContext {
 
         // parameter defs
         Map<String,ConfigKey<?>> parameters = MutableMap.of();
-        
Effectors.parseParameters(paramsDefiningWorkflow.get(WorkflowCommonConfig.PARAMETER_DEFS)).forEach(p
 -> parameters.put(p.getName(), Effectors.asConfigKey(p)));
+        Maybe<BrooklynClassLoadingContext> loader = 
RegisteredTypes.getClassLoadingContextMaybe(entityOrAdjunctWhereRunning);
+        
Effectors.parseParameters(paramsDefiningWorkflow.get(WorkflowCommonConfig.PARAMETER_DEFS),
 loader.orNull()).forEach(p -> parameters.put(p.getName(), 
Effectors.asConfigKey(p)));
         if (extraConfigKeys!=null) extraConfigKeys.forEach(p -> 
parameters.put(p.getName(), p));
 
         // inputs, unresolved first
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/flags/BrooklynTypeNameResolution.java
 
b/core/src/main/java/org/apache/brooklyn/util/core/flags/BrooklynTypeNameResolution.java
index 2be8992791..bd77e37e91 100644
--- 
a/core/src/main/java/org/apache/brooklyn/util/core/flags/BrooklynTypeNameResolution.java
+++ 
b/core/src/main/java/org/apache/brooklyn/util/core/flags/BrooklynTypeNameResolution.java
@@ -51,6 +51,8 @@ import org.apache.commons.lang3.reflect.TypeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.annotation.Nullable;
+
 public class BrooklynTypeNameResolution {
 
     private static Logger LOG = 
LoggerFactory.getLogger(BrooklynTypeNameResolution.class);
@@ -133,13 +135,13 @@ public class BrooklynTypeNameResolution {
             this(context, mgmt, null, false, mgmt != null);
         }
         /** resolver supporting configurable sources of types */
-        public BrooklynTypeNameResolver(String context, 
BrooklynClassLoadingContext loader, boolean allowJavaType, boolean 
allowRegisteredTypes) {
-            this(context, loader.getManagementContext(), loader, 
allowJavaType, allowRegisteredTypes);
+        public BrooklynTypeNameResolver(String context, @Nullable 
BrooklynClassLoadingContext loader, boolean allowJavaType, boolean 
allowRegisteredTypes) {
+            this(context, loader==null ? null : loader.getManagementContext(), 
loader, allowJavaType, allowRegisteredTypes);
         }
-        private BrooklynTypeNameResolver(String context, ManagementContext 
mgmt, BrooklynClassLoadingContext loader, boolean allowJavaType, boolean 
allowRegisteredTypes) {
+        private BrooklynTypeNameResolver(String context, @Nullable 
ManagementContext mgmt, BrooklynClassLoadingContext loader, boolean 
allowJavaType, boolean allowRegisteredTypes) {
             this.context = context;
             this.mgmt = mgmt;
-            this.loader = loader==null ? 
JavaBrooklynClassLoadingContext.create(mgmt) : loader;
+            this.loader = loader==null ? mgmt==null ? null : 
JavaBrooklynClassLoadingContext.create(mgmt) : loader;
             this.allowJavaType = allowJavaType;
             this.allowRegisteredTypes = allowRegisteredTypes;
 
@@ -152,8 +154,12 @@ public class BrooklynTypeNameResolution {
             }
 
             if (allowRegisteredTypes) {
-                rules.put("Brooklyn registered types",
-                        s -> mgmt.getTypeRegistry().getMaybe(s, 
RegisteredTypeLoadingContexts.loader(loader)).map(BrooklynJacksonType::asTypeToken));
+                if (mgmt==null) {
+                    // registered types not available if no mgmt context 
supplied
+                } else {
+                    rules.put("Brooklyn registered types",
+                            s -> mgmt.getTypeRegistry().getMaybe(s, 
RegisteredTypeLoadingContexts.loader(loader)).map(BrooklynJacksonType::asTypeToken));
+                }
             }
         }
 

Reply via email to