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 eea854541d334213652d3d2ac51b0b24915c463b Author: Alex Heneveld <[email protected]> AuthorDate: Fri Apr 14 15:48:35 2023 +0100 don't use native type id for yaml serialization allows our 'type:' deserialization to be used in contexts where we will subsequently deserialize --- .../brooklyn/camp/brooklyn/WorkflowYamlTest.java | 35 ++++++++++++++++++++++ .../core/resolve/jackson/BeanWithTypeUtils.java | 18 +++++++++-- .../util/json/BrooklynJacksonSerializerTest.java | 7 ++++- 3 files changed, 57 insertions(+), 3 deletions(-) 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 d6991f7b9b..e761a9bd0a 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 @@ -1212,4 +1212,39 @@ public class WorkflowYamlTest extends AbstractYamlTest { EntityAsserts.assertAttributeEquals(entity, Sensors.newBooleanSensor("ran"), true); } + @Test + public void testAddPolicyWithDslFromDeployableBlueprint() throws Exception { + // this is not a nice pattern, relying on the fact that output is not a string in order to give the right output + Entity app = createAndStartApplication( + "services:", + "- type: " + BasicEntity.class.getName(), + " brooklyn.initializers:", + " - type: workflow-effector", + " name: foo", + " steps:", + " - return yes", + " - type: workflow-effector", + " name: bar", + " steps:", + " - type: add-policy", + " interpolation_mode: disabled", + " blueprint:", + " type: workflow-policy", + " triggers: [ s ]", + " brooklyn.config:", + " steps:", + " - type: workflow", + " steps:", + " - step: invoke-effector", + " entity: $brooklyn:self()", // note we refer to parent + " effector: foo", + " - step: set-sensor result = ${output}"); + Entity entity = Iterables.getOnlyElement(app.getChildren()); + entity.invoke(entity.getEntityType().getEffectorByName("bar").get(), null).get(); + + entity.sensors().set(Sensors.newStringSensor("s"), "run"); + EntityAsserts.assertAttributeEventually(entity, Sensors.newSensor(Object.class, "result"), v -> v!=null); + EntityAsserts.assertAttributeEquals(entity, Sensors.newSensor(Object.class, "result"), "yes"); + } + } diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BeanWithTypeUtils.java b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BeanWithTypeUtils.java index 2e0462e9b9..f04e7fc6c9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BeanWithTypeUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/resolve/jackson/BeanWithTypeUtils.java @@ -68,7 +68,10 @@ public class BeanWithTypeUtils { } public static ObjectMapper newYamlMapper(ManagementContext mgmt, boolean allowRegisteredTypes, BrooklynClassLoadingContext loader, boolean allowPojoJavaTypes) { - ObjectMapper mapper = applyCommonMapperConfig(newSimpleYamlMapper(), mgmt, allowRegisteredTypes, loader, allowPojoJavaTypes); + return newYamlMapper(mgmt, allowRegisteredTypes, loader, allowPojoJavaTypes, false); + } + public static ObjectMapper newYamlMapper(ManagementContext mgmt, boolean allowRegisteredTypes, BrooklynClassLoadingContext loader, boolean allowPojoJavaTypes, boolean allowYamlTagsForType) { + ObjectMapper mapper = applyCommonMapperConfig(newSimpleYamlMapper(allowYamlTagsForType), mgmt, allowRegisteredTypes, loader, allowPojoJavaTypes); mapper = mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; } @@ -97,12 +100,23 @@ public class BeanWithTypeUtils { } public static YAMLMapper newSimpleYamlMapper() { + return newSimpleYamlMapper(false); + } + public static YAMLMapper newSimpleYamlMapper(boolean allowYamlTagsForType) { // for use with json maps (no special type resolution, even the field "type" is ignored); // do not split lines as that makes output harder to read - return YAMLMapper.builder().build().enable(YAMLGenerator.Feature.MINIMIZE_QUOTES) + YAMLMapper result = YAMLMapper.builder().build() + .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES) .enable(YAMLGenerator.Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS) //otherwise "1" becomes 1 .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) .disable(YAMLGenerator.Feature.SPLIT_LINES); + if (!allowYamlTagsForType) { + // whether to use !<type> tags; normally not, use the same type / (type) keys as done for json + // if we know we will be deserializing it using one of these jackson deserializers, it could be enabled, + // though not sure if there is any point. note that snakeyaml does not support custom types by default. + result.disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID); + } + return result; } public static boolean isPureJson(Object o) { diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java index 79fc689b80..6dc29c9ccd 100644 --- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java +++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/util/json/BrooklynJacksonSerializerTest.java @@ -523,8 +523,13 @@ public class BrooklynJacksonSerializerTest { // and same with yaml out = mapperY.writerFor(Object.class).writeValueAsString(in); // Asserts.assertStringContains(out, "\"(type)\":\""+EntitySpec.class.getName()+"\""); - Asserts.assertStringContains(out, "!<"+EntitySpec.class.getName()+">"); + Asserts.assertStringContains(out, EntitySpec.class.getName()); + + // when we used tags this was done, but we don't use tags (this mapper supports it but snake yaml does not) + // see org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils.newSimpleYamlMapper(boolean) +// Asserts.assertStringContains(out, "!<"+EntitySpec.class.getName()+">"); Asserts.assertStringContains(out, "type: "+TestEntity.class.getName()); + in2 = mapperY.readerFor(SpecHolder.class).readValue(out); // map = (Map) in2.specU.get(); // Asserts.assertEquals( TypeCoercions.coerce(map, EntitySpec.class).getType(), TestEntity.class);
