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 5026b145da941652985114ba12dc97661b7e08c8 Author: Alex Heneveld <[email protected]> AuthorDate: Fri Nov 4 16:16:12 2022 +0000 fix edge case where types won't coerce as supertypes aren't set --- .../brooklyn/camp/brooklyn/AbstractYamlTest.java | 8 ++- .../camp/brooklyn/AddChildrenEffectorYamlTest.java | 5 +- .../camp/brooklyn/CustomTypeConfigYamlTest.java | 5 +- .../brooklyn/CustomTypeInitializerYamlTest.java | 77 +++++++++++----------- .../brooklyn/camp/brooklyn/WorkflowYamlTest.java | 17 +++-- .../core/resolve/jackson/BrooklynJacksonType.java | 7 ++ .../core/workflow/WorkflowExecutionContext.java | 2 +- .../core/workflow/WorkflowStepResolution.java | 2 +- .../workflow/steps/SetVariableWorkflowStep.java | 4 +- .../resolve/jackson/BrooklynJacksonTypeTest.java | 5 +- ...klynRegisteredTypeJacksonSerializationTest.java | 16 ++--- .../core/test/BrooklynAppUnitTestSupport.java | 17 +++++ .../brooklyn/core/workflow/WorkflowBasicTest.java | 6 +- .../workflow/WorkflowInputOutputExtensionTest.java | 32 +++++++-- 14 files changed, 126 insertions(+), 77 deletions(-) diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java index baeeb4a4ad..8141099ef9 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java @@ -20,7 +20,6 @@ package org.apache.brooklyn.camp.brooklyn; import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.Reader; import java.util.Collection; import java.util.Map; @@ -47,6 +46,7 @@ import org.apache.brooklyn.core.mgmt.EntityManagementUtils; import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult; import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests.Builder; import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; @@ -246,7 +246,11 @@ public abstract class AbstractYamlTest { protected <T extends Application> EntitySpec<T> createAppEntitySpec(String... yaml) { return (EntitySpec<T>) EntityManagementUtils.createEntitySpecForApplication(mgmt(), CampTypePlanTransformer.FORMAT, joinLines(yaml)); } - + + protected RegisteredType addBean(String name, String version, RegisteredType.TypeImplementationPlan plan) { + return BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt(), name, version, plan); + } + protected void addCatalogItems(Iterable<String> catalogYaml) { addCatalogItems(joinLines(catalogYaml)); } diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AddChildrenEffectorYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AddChildrenEffectorYamlTest.java index 476c374a8e..2bbb49f2ba 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AddChildrenEffectorYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AddChildrenEffectorYamlTest.java @@ -215,13 +215,12 @@ public class AddChildrenEffectorYamlTest extends AbstractYamlTest { @Test public void testAddChildrenWithServicesBlock_RegisteredType() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry( - RegisteredTypes.bean("add-child", "1", + addBean("add-child", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+AddChildrenEffector.class.getName()+"\n" + "brooklyn.config:\n" + " name: add\n"+ - " blueprint_yaml: OVERRIDE")), false); + " blueprint_yaml: OVERRIDE")); testAddChildrenWithServicesBlock(() -> makeAppAndAddChild(Strings.lines( " - type: add-child", diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeConfigYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeConfigYamlTest.java index ae2d3aa443..a840a74d1a 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeConfigYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeConfigYamlTest.java @@ -216,10 +216,8 @@ public class CustomTypeConfigYamlTest extends AbstractYamlTest { } private void registerCustomType() { - RegisteredType bean = RegisteredTypes.bean("custom-type", "1", + addBean("custom-type", "1", new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, TestingCustomType.class.getName())); - bean = RegisteredTypes.addSuperType(bean, TestingCustomType.class); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(bean, false); } @Test @@ -336,6 +334,7 @@ public class CustomTypeConfigYamlTest extends AbstractYamlTest { " type: " + CustomTypeConfigYamlTest.TestingCustomType.class.getName(), " x: foo2", " - id: custom-type", + " format: bean-with-type", " item:", " type: custom-type-0", " y: bar"); diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeInitializerYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeInitializerYamlTest.java index 4eb70c38e2..2acfac34a7 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeInitializerYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/CustomTypeInitializerYamlTest.java @@ -18,11 +18,7 @@ */ package org.apache.brooklyn.camp.brooklyn; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonCreator.Mode; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.google.common.base.Predicates; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntityInitializer; import org.apache.brooklyn.api.entity.EntityLocal; @@ -31,10 +27,8 @@ import org.apache.brooklyn.core.entity.EntityInitializers.AddTags; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypePlanTransformer; import org.apache.brooklyn.core.resolve.jackson.BrooklynRegisteredTypeJacksonSerializationTest.SampleBean; import org.apache.brooklyn.core.test.entity.TestEntity; -import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; -import org.apache.brooklyn.core.typereg.RegisteredTypes; import org.apache.brooklyn.test.Asserts; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.core.config.ConfigBag; @@ -153,8 +147,8 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredType() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, CustomTypeInitializerYamlTest.TestingCustomInitializerType.class.getName())), false); + addBean("custom-type", "1", + new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, CustomTypeInitializerYamlTest.TestingCustomInitializerType.class.getName())); Entity testEntity = deployWithTestingCustomInitializerType("custom-type"); assertInitializerRanAndXY(testEntity, null, null); @@ -162,8 +156,8 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredTypeWithArgUsingField() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, CustomTypeInitializerYamlTest.TestingCustomInitializerType.class.getName())), false); + addBean("custom-type", "1", + new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, CustomTypeInitializerYamlTest.TestingCustomInitializerType.class.getName())); Entity testEntity = deployWithTestingCustomInitializerType("custom-type", " x: foo"); @@ -172,8 +166,8 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredTypeWithArgUsingConfigBag() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName())), false); + addBean("custom-type", "1", + new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName())); Entity testEntity = deployWithTestingCustomInitializerType("custom-type", " brooklyn.config:", @@ -183,8 +177,8 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredTypeWithArgUsingConfigBagAndField() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName())), false); + addBean("custom-type", "1", + new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName())); Entity testEntity = deployWithTestingCustomInitializerType("custom-type", " y: bar", @@ -195,10 +189,10 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredTypeWithArgUsingInheritedFieldAndLocalConfigBag() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", + addBean("custom-type", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName()+"\n" + - "y: bar")), false); + "y: bar")); Entity testEntity = deployWithTestingCustomInitializerType("custom-type", " brooklyn.config:", @@ -208,11 +202,11 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerTypeSpecifiedAsRegisteredTypeWithArgUsingInheritedConfigBagAndLocalField() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", + addBean("custom-type", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeAcceptingConfigBag.class.getName()+"\n" + "brooklyn.config:\n" + - " x: foo")), false); + " x: foo")); Entity testEntity = deployWithTestingCustomInitializerType("custom-type", " y: bar"); @@ -235,11 +229,13 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testOldStyleCustomInitializerTypeSpecifiedAsRegisteredTypeFails() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, - "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeOldStyleAcceptingConfigBagOnly.class.getName())), false); - - Asserts.assertFailsWith(() ->deployWithTestingCustomInitializerType("custom-type"), + Asserts.assertFailsWith(() -> { + addBean("custom-type", "1", + new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, + "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeOldStyleAcceptingConfigBagOnly.class.getName())); + deployWithTestingCustomInitializerType("custom-type"); + return null; + }, e -> Asserts.expectedFailureContainsIgnoreCase(e, TestingCustomInitializerTypeOldStyleAcceptingConfigBagOnly.class.getName(), "no creators", "cannot construct")); } @@ -280,9 +276,9 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerFinalPatternTakingFields() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", + addBean("custom-type", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, - "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeFinal.class.getName())), false); + "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeFinal.class.getName())); Entity entity = deployWithTestingCustomInitializerType("custom-type", " z: hi"); @@ -299,10 +295,10 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerFinalPatternOverridingFields() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", + addBean("custom-type", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeFinal.class.getName()+"\n" + - "z: hi1")), false); + "z: hi1")); Entity entity = deployWithTestingCustomInitializerType("custom-type", " z: hi2"); @@ -311,27 +307,30 @@ public class CustomTypeInitializerYamlTest extends AbstractYamlTest { @Test public void testCustomInitializerFinalPatternUsingConfigBagWithTypeNotSupported() throws Exception { - // we're allowed to add - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("custom-type", "1", - new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, - "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeFinal.class.getName()+"\n" + - "brooklyn.config:\n" + - " z: hi1")), false); // but deployment fails as we don't have a json setter; cannot use final var pattern with bean-with-type - Asserts.assertFailsWith(() -> deployWithTestingCustomInitializerType("custom-type"), - e -> Asserts.expectedFailureContainsIgnoreCase(e, "unrecognized field", "brooklyn.config", "hi1")); + Asserts.assertFailsWith(() -> { + // we're allowed to add + addBean("custom-type", "1", + new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, + "type: "+CustomTypeInitializerYamlTest.TestingCustomInitializerTypeFinal.class.getName()+"\n" + + "brooklyn.config:\n" + + " z: hi1")); + deployWithTestingCustomInitializerType("custom-type"); + return null; + }, + e -> Asserts.expectedFailureContainsIgnoreCase(e, "unrecognized field", "brooklyn.config")); } // also test the stock initializer @Test public void testAddTags() throws Exception { - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("add-tags", "1", + addBean("add-tags", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, - "type: "+ AddTags.class.getName())), false); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(RegisteredTypes.bean("sample-bean", "1", + "type: "+ AddTags.class.getName())); + addBean("sample-bean", "1", new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, - "type: "+ SampleBean.class.getName())), false); + "type: "+ SampleBean.class.getName())); Entity ent = deployWithTestingCustomInitializerType("add-tags", " tags:", " - t1", diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java index 945e472355..6025815a66 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlTest.java @@ -30,6 +30,7 @@ import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.location.MachineLocation; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.api.typereg.RegisteredType; @@ -42,6 +43,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle; import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils; import org.apache.brooklyn.core.sensor.Sensors; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; @@ -82,19 +84,16 @@ public class WorkflowYamlTest extends AbstractYamlTest { @SuppressWarnings("deprecation") static RegisteredType addRegisteredTypeBean(ManagementContext mgmt, String symName, Class<?> clazz) { - RegisteredType rt = RegisteredTypes.bean(symName, VERSION, + return BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt, symName, VERSION, new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, clazz.getName())); - ((BasicBrooklynTypeRegistry)mgmt.getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); - return rt; } - static RegisteredType addRegisteredTypeSpec(ManagementContext mgmt, String symName, Class<?> clazz) { + static RegisteredType addRegisteredTypeSpec(ManagementContext mgmt, String symName, Class<?> clazz, Class<? extends BrooklynObject> superClazz) { RegisteredType rt = RegisteredTypes.spec(symName, VERSION, new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, clazz.getName())); - RegisteredTypes.addSuperType(rt, Policy.class); - - ((BasicBrooklynTypeRegistry)mgmt.getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); - return rt; + RegisteredTypes.addSuperType(rt, superClazz); + mgmt.getCatalog().validateType(rt, null, false); + return mgmt.getTypeRegistry().get(rt.getSymbolicName(), rt.getVersion()); } public static void addWorkflowTypes(ManagementContext mgmt) { @@ -105,7 +104,7 @@ public class WorkflowYamlTest extends AbstractYamlTest { addRegisteredTypeBean(mgmt, "workflow-effector", WorkflowEffector.class); addRegisteredTypeBean(mgmt, "workflow-sensor", WorkflowSensor.class); - addRegisteredTypeSpec(mgmt, "workflow-policy", WorkflowPolicy.class); + addRegisteredTypeSpec(mgmt, "workflow-policy", WorkflowPolicy.class, Policy.class); } @BeforeMethod(alwaysRun = true) diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonType.java b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonType.java index 02d0db717b..e184d3a2f9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonType.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonType.java @@ -144,6 +144,13 @@ public class BrooklynJacksonType extends SimpleType implements TypeVariable<Gene for (Object x : t.getSuperTypes()) { if (x instanceof Class) return (Class<?>) x; } + + // we should throw; but there is one place we need to assume Object, and that is if we are + // adding multiple things to catalog, we assume parent type is object first even if it cannot be resolved. + // see CustomTypeConfigYamlTest.TestRegisteredType_InheritFromPeer + + // throw new IllegalStateException("Accessing concrete type of unresolved registered type "+t); + return Object.class; } 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 87d7e5f830..7c5ace49f0 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 @@ -507,7 +507,7 @@ public class WorkflowExecutionContext { public TypeToken<?> lookupType(String typeName, Supplier<TypeToken<?>> ifUnset) { if (Strings.isBlank(typeName)) return ifUnset.get(); BrooklynClassLoadingContext loader = getEntity() != null ? RegisteredTypes.getClassLoadingContext(getEntity()) : null; - return new BrooklynTypeNameResolution.BrooklynTypeNameResolver("", loader, true, true).getTypeToken(typeName); + return new BrooklynTypeNameResolution.BrooklynTypeNameResolver("workflow", loader, true, true).getTypeToken(typeName); } /** as {@link #resolve(Object, TypeToken)} but without type coercion */ diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java index 24cdb4af1b..635396a793 100644 --- a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java +++ b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowStepResolution.java @@ -94,7 +94,7 @@ public class WorkflowStepResolution { try { Object def0 = defM !=null ? defM : def; - def = BeanWithTypeUtils.convert(mgmt, def0, TypeToken.of(WorkflowStepDefinition.class), true, loader, false); + def = BeanWithTypeUtils.convert(mgmt, def0, TypeToken.of(WorkflowStepDefinition.class), true, loader, true); if (def instanceof WorkflowStepDefinition.WorkflowStepDefinitionWithSpecialDeserialization) { def = ((WorkflowStepDefinition.WorkflowStepDefinitionWithSpecialDeserialization)def).applySpecialDefinition(mgmt, def0, typeBestGuess, (WorkflowStepDefinition.WorkflowStepDefinitionWithSpecialDeserialization) def); diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetVariableWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetVariableWorkflowStep.java index c43bcbe577..302d11384e 100644 --- a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetVariableWorkflowStep.java +++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/SetVariableWorkflowStep.java @@ -243,9 +243,9 @@ public class SetVariableWorkflowStep extends WorkflowStepDefinition { try { ObjectMapper mapper; if ("yaml".equals(specialCoercionMode)) - mapper = BeanWithTypeUtils.newYamlMapper(context.getManagementContext(), false, null, true); + mapper = BeanWithTypeUtils.newYamlMapper(context.getManagementContext(), true, null, true); else if ("json".equals(specialCoercionMode)) - mapper = BeanWithTypeUtils.newMapper(context.getManagementContext(), false, null, true); + mapper = BeanWithTypeUtils.newMapper(context.getManagementContext(), true, null, true); else throw new IllegalArgumentException("Unknown special coercion mode '" + specialCoercionMode + "'"); diff --git a/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonTypeTest.java index 74e511407d..d2f2f9de68 100644 --- a/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonTypeTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynJacksonTypeTest.java @@ -52,7 +52,10 @@ public class BrooklynJacksonTypeTest { public static TypeToken<?> parseTestTypes(String s1) { return BrooklynTypeNameResolution.parseTypeToken(s1, s2 -> { if ("foo".equals(s2)) - return Maybe.of(BrooklynJacksonType.asTypeToken(RegisteredTypes.bean("foo", "1", new BasicTypeImplementationPlan("x", null)))); + return Maybe.of(BrooklynJacksonType.asTypeToken( + RegisteredTypes.addSuperType( + RegisteredTypes.bean("foo", "1", new BasicTypeImplementationPlan("x", null)), Object.class + ))); if ("iterable".equals(s2)) return Maybe.of(TypeToken.of(Iterable.class)); return BrooklynTypeNameResolution.getTypeTokenForBuiltInTypeName(s2); }).get(); diff --git a/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynRegisteredTypeJacksonSerializationTest.java b/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynRegisteredTypeJacksonSerializationTest.java index dbfa7bd538..30ea7877af 100644 --- a/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynRegisteredTypeJacksonSerializationTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/resolve/jackson/BrooklynRegisteredTypeJacksonSerializationTest.java @@ -24,6 +24,7 @@ import org.apache.brooklyn.api.entity.EntityInitializer; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.sensor.StaticSensor; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport; import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; @@ -76,9 +77,8 @@ public class BrooklynRegisteredTypeJacksonSerializationTest extends BrooklynMgmt @Test public void testDeserializeAlias() throws Exception { - RegisteredType rt = RegisteredTypes.bean("sample", "1", + BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt,"sample", "1", new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, SampleBean.class.getName())); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); Object impl = deser("{\"type\":\"sample\",\"x\":\"hello\"}"); Asserts.assertInstanceOf(impl, SampleBean.class); @@ -87,13 +87,12 @@ public class BrooklynRegisteredTypeJacksonSerializationTest extends BrooklynMgmt @Test public void testSimpleBeanRegisteredType() throws Exception { - RegisteredType rt = RegisteredTypes.bean("sample-hello", "1", + RegisteredType rt = BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt, "sample-hello", "1", new BasicTypeImplementationPlan(BeanWithTypeUtils.FORMAT, "type: " + SampleBean.class.getName() + "\n" + - "x: hello\n" + - "y: hi" - )); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); + "x: hello\n" + + "y: hi" + )); Object impl = mgmt().getTypeRegistry().create(rt, null, null); Asserts.assertInstanceOf(impl, SampleBean.class); Asserts.assertEquals(((SampleBean)impl).x, "hello"); @@ -114,11 +113,10 @@ public class BrooklynRegisteredTypeJacksonSerializationTest extends BrooklynMgmt @Test public void testExtendedListBeanRegisteredType() throws Exception { - RegisteredType rt = RegisteredTypes.bean("list-extended", "1", + RegisteredType rt = BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt, "list-extended", "1", new BasicTypeImplementationPlan(BeanWithTypeUtils.FORMAT, "type: " + ListExtended.class.getName() )); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); Object impl = mgmt().getTypeRegistry().create(rt, null, null); Asserts.assertInstanceOf(impl, ListExtended.class); diff --git a/core/src/test/java/org/apache/brooklyn/core/test/BrooklynAppUnitTestSupport.java b/core/src/test/java/org/apache/brooklyn/core/test/BrooklynAppUnitTestSupport.java index 3d02fe7f49..27514a2d7f 100644 --- a/core/src/test/java/org/apache/brooklyn/core/test/BrooklynAppUnitTestSupport.java +++ b/core/src/test/java/org/apache/brooklyn/core/test/BrooklynAppUnitTestSupport.java @@ -19,10 +19,19 @@ package org.apache.brooklyn.core.test; import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.entity.BrooklynConfigKeys; import org.apache.brooklyn.core.test.entity.TestApplication; +import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; +import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; +import org.apache.brooklyn.core.typereg.RegisteredTypes; +import org.apache.brooklyn.test.Asserts; +import org.apache.brooklyn.util.exceptions.Exceptions; import org.testng.annotations.BeforeMethod; +import java.util.Collection; + /** * To be extended by unit/integration tests. * <p> @@ -52,4 +61,12 @@ public class BrooklynAppUnitTestSupport extends BrooklynMgmtUnitTestSupport { app = mgmt.getEntityManager().createEntity(appSpec); } + @SuppressWarnings("deprecation") + public static RegisteredType addRegisteredTypeBean(ManagementContext mgmt, String symName, String version, RegisteredType.TypeImplementationPlan plan) { + RegisteredType rt = RegisteredTypes.bean(symName, version, plan); + Collection<Throwable> errors = mgmt.getCatalog().validateType(rt, null, true); + if (!errors.isEmpty()) Asserts.fail(Exceptions.propagate("Failed to validate", errors)); + // the resolved type is added, not necessarily type above which will be unresolved + return mgmt.getTypeRegistry().get(symName, version); + } } diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java index 182b9722ba..8de3bf29b9 100644 --- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java @@ -34,6 +34,7 @@ import org.apache.brooklyn.core.entity.Dumper; import org.apache.brooklyn.core.entity.EntityAsserts; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils; import org.apache.brooklyn.core.sensor.Sensors; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport; import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; @@ -60,16 +61,15 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; + public class WorkflowBasicTest extends BrooklynMgmtUnitTestSupport { static final String VERSION = "0.1.0-SNAPSHOT"; @SuppressWarnings("deprecation") public static RegisteredType addRegisteredTypeBean(ManagementContext mgmt, String symName, Class<?> clazz) { - RegisteredType rt = RegisteredTypes.bean(symName, VERSION, + return BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt, symName, VERSION, new BasicTypeImplementationPlan(JavaClassNameTypePlanTransformer.FORMAT, clazz.getName())); - ((BasicBrooklynTypeRegistry)mgmt.getTypeRegistry()).addToLocalUnpersistedTypeRegistry(rt, false); - return rt; } protected void loadTypes() { diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java index bee53967f3..33ebd0242a 100644 --- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowInputOutputExtensionTest.java @@ -26,9 +26,10 @@ import org.apache.brooklyn.core.entity.EntityAsserts; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypePlanTransformer; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils; import org.apache.brooklyn.core.sensor.Sensors; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport; -import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry; import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan; +import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer; import org.apache.brooklyn.core.typereg.RegisteredTypes; import org.apache.brooklyn.core.workflow.steps.LogWorkflowStep; import org.apache.brooklyn.entity.stock.BasicApplication; @@ -38,6 +39,7 @@ import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.text.StringEscapes; import org.apache.brooklyn.util.text.Strings; @@ -45,6 +47,7 @@ import org.testng.Assert; import org.testng.annotations.Test; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -118,9 +121,9 @@ public class WorkflowInputOutputExtensionTest extends BrooklynMgmtUnitTestSuppor } public RegisteredType addBeanWithType(String typeName, String version, String plan) { - RegisteredType type = RegisteredTypes.bean(typeName, version, new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, plan)); - ((BasicBrooklynTypeRegistry)mgmt().getTypeRegistry()).addToLocalUnpersistedTypeRegistry(type, false); - return type; + loadTypes(); + return BrooklynAppUnitTestSupport.addRegisteredTypeBean(mgmt, typeName, version, + new BasicTypeImplementationPlan(BeanWithTypePlanTransformer.FORMAT, plan)); } ClassLogWatcher lastLogWatcher; @@ -435,6 +438,27 @@ public class WorkflowInputOutputExtensionTest extends BrooklynMgmtUnitTestSuppor checkLet("json", MutableMap.of("x", 1), MutableMap.of("x", 1)); } + public static class MockObject { + String id; + String name; + } + + @Test + public void testLetYamlCoercion() throws Exception { + addBeanWithType("mock-object", "1", "type: " + MockObject.class.getName()); + Object result = invokeWorkflowStepsWithLogging(MutableList.of( + MutableMap.<String, Object>of("step", "let x1", "value", + "ignore\n" + + "---\n" + + " id: x\n" + + " name: foo"), + "let yaml mock-object result = ${x1}", + "return ${result}")); + Asserts.assertThat(result, r -> r instanceof MockObject); + Asserts.assertEquals(((MockObject)result).id, "x"); + Asserts.assertEquals(((MockObject)result).name, "foo"); + } + @Test public void testOutputYamlAndJson() throws Exception { Object output = invokeWorkflowStepsWithLogging(MutableList.of(
