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 0adb476a47929379f15e4b00b542a47cbc7a1fda Author: Alex Heneveld <[email protected]> AuthorDate: Fri May 28 14:17:30 2021 +0100 add depth_in_ancestor tags to all entity specs and entities --- .../catalog/CatalogOsgiYamlTemplateTest.java | 11 +- .../apache/brooklyn/core/mgmt/BrooklynTags.java | 155 ++++++++++++--------- .../core/typereg/AbstractTypePlanTransformer.java | 20 ++- 3 files changed, 119 insertions(+), 67 deletions(-) diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiYamlTemplateTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiYamlTemplateTest.java index a641166..e3b05ac 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiYamlTemplateTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiYamlTemplateTest.java @@ -80,7 +80,9 @@ public class CatalogOsgiYamlTemplateTest extends AbstractYamlTest { EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpecForApplication(mgmt(), "services: [ { type: t1 } ]\n" + "location: localhost"); - + + // parent + List<NamedStringTag> yamls = BrooklynTags.findAllNamedStringTags(BrooklynTags.YAML_SPEC_KIND, spec.getTags()); Assert.assertEquals(yamls.size(), 1, "Expected 1 yaml tag; instead had: "+yamls); String yaml = Iterables.getOnlyElement(yamls).getContents(); @@ -90,18 +92,25 @@ public class CatalogOsgiYamlTemplateTest extends AbstractYamlTest { Assert.assertNotNull(yamlsH); Assert.assertEquals(yamlsH.getSpecList().size(), 1, "Expected 1 yaml tag in hierarchy; instead had: "+yamlsH); + Assert.assertNull(BrooklynTags.getDepthInAncestorTag(spec.getTags())); + + // and child + EntitySpec<?> child = Iterables.getOnlyElement( spec.getChildren() ); Assert.assertEquals(child.getType().getName(), SIMPLE_ENTITY_TYPE); Assert.assertEquals(child.getCatalogItemId(), "t1:"+TEST_VERSION); List<NamedStringTag> yamls2 = BrooklynTags.findAllNamedStringTags(BrooklynTags.YAML_SPEC_KIND, child.getTags()); Assert.assertEquals(yamls2.size(), 1, "Expected 1 yaml tag; instead had: "+yamls); + SpecHierarchyTag yamlsH2 = BrooklynTags.findSpecHierarchyTag( child.getTags() ); Assert.assertNotNull(yamlsH2); Assert.assertEquals(yamlsH2.getSpecList().size(), 1, "Expected 1 yaml tag in hierarchy; instead had: "+yamlsH2); Asserts.assertStringContainsIgnoreCase(yamlsH2.getSpecList().iterator().next().contents.toString(), "# this sample comment should be included", "SimpleEntity"); + + Assert.assertEquals(BrooklynTags.getDepthInAncestorTag(spec.getTags()), (Integer) 1); } private RegisteredType makeItem(String symbolicName, String templateType) { diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java index 78a460c..c8a76d9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java @@ -18,12 +18,14 @@ */ package org.apache.brooklyn.core.mgmt; +import com.google.common.reflect.TypeToken; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.google.common.base.MoreObjects; +import java.util.Set; import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils; import org.apache.brooklyn.util.collections.MutableList; @@ -33,6 +35,7 @@ import com.google.common.annotations.Beta; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.collect.Lists; +import org.apache.brooklyn.util.core.flags.TypeCoercions; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +48,7 @@ public class BrooklynTags { public static final String YAML_SPEC_KIND = "yaml_spec"; public static final String YAML_SPEC_HIERARCHY = "yaml_spec_hierarchy"; + public static final String DEPTH_IN_ANCESTOR = "depth_in_ancestor"; public static final String NOTES_KIND = "notes"; public static final String OWNER_ENTITY_ID = "owner_entity_id"; public static final String ICON_URL = "icon_url"; @@ -53,10 +57,94 @@ public class BrooklynTags { * and does not have to resolve */ public static final Object CATALOG_TEMPLATE = "catalog_template"; + /** find a tag which is a map of size one whose single key matches the key here, and if found return the value + * coerced to the indicated type */ + public static <T> T findSingleKeyMapValue(String key, TypeToken<T> type, Set<Object> tags) { + if (tags==null) return null; + for (Object tag: tags) { + if (tag instanceof Map && ((Map)tag).size()==1 && Objects.equal(key, ((Map)tag).keySet().iterator().next())) { + Object value = ((Map)tag).get(key); + return TypeCoercions.coerce(value, type); + } + } + return null; + } + /** convenience for {@link #findSingleKeyMapValue(String, TypeToken, Set)} */ + public static <T> T findSingleKeyMapValue(String key, Class<T> type, Set<Object> tags) { + return findSingleKeyMapValue(key, TypeToken.of(type), tags); + } + + public static NamedStringTag findFirstNamedStringTag(String kind, Iterable<Object> tags) { + return findFirstOfKind(kind, NamedStringTag.class, tags); + } + + public static List<NamedStringTag> findAllNamedStringTags(String kind, Iterable<Object> tags) { + return findAllOfKind(kind, NamedStringTag.class, tags); + } + + /** @deprecated since 1.1 use {@link #findFirstNamedStringTag(String, Iterable)} */ + @Deprecated + public static NamedStringTag findFirst(String kind, Iterable<Object> tags) { + return findFirstNamedStringTag(kind, tags); + } + + /** @deprecated since 1.1 use {@link #findAllNamedStringTags(String, Iterable)} */ + @Deprecated + public static List<NamedStringTag> findAll(String kind, Iterable<Object> tags) { + return findAllNamedStringTags(kind, tags); + } + public interface HasKind { public String getKind(); } + public static <T extends HasKind> T findFirstOfKind(String kind, Class<T> type, Iterable<Object> tags) { + for (Object o: tags) { + if (type.isInstance(o)) { + if (kind.equals(((T) o).getKind())) { + return (T) o; + } + } else if (o instanceof Map) { + Object k2 = ((Map) o).get("kind"); + if (kind.equals(k2)) { + try { + return BeanWithTypeUtils.newMapper(null, false, null, true).convertValue(o, type); + + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + LOG.warn("Tag '"+o+"' declares kind '"+k2+"' but does not convert to "+type+" (ignoring): "+e); + } + } + } + } + return null; + } + + public static <T extends HasKind> List<T> findAllOfKind(String kind, Class<T> type, Iterable<Object> tags) { + List<T> result = MutableList.of(); + + for (Object o: tags) { + if (type.isInstance(o)) { + if (kind.equals(((T) o).getKind())) { + result.add( (T)o ); + } + } else if (o instanceof Map) { + Object k2 = ((Map) o).get("kind"); + if (kind.equals(k2)) { + try { + result.add( BeanWithTypeUtils.newMapper(null, false, null, true).convertValue(o, type) ); + + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + LOG.warn("Tag '"+o+"' declares kind '"+k2+"' but does not convert to "+type+" (ignoring): "+e); + } + } + } + } + + return result; + } + public static class NamedStringTag implements Serializable, HasKind { private static final long serialVersionUID = 7932098757009051348L; @JsonProperty @@ -282,6 +370,7 @@ public class BrooklynTags { } } + public static NamedStringTag newYamlSpecTag(String contents) { return new NamedStringTag(YAML_SPEC_KIND, contents); } @@ -306,75 +395,13 @@ public class BrooklynTags { return new TraitsTag(interfaces); } - public static <T extends HasKind> T findFirstOfKind(String kind, Class<T> type, Iterable<Object> tags) { - for (Object o: tags) { - if (type.isInstance(o)) { - if (kind.equals(((T) o).getKind())) { - return (T) o; - } - } else if (o instanceof Map) { - Object k2 = ((Map) o).get("kind"); - if (kind.equals(k2)) { - try { - return BeanWithTypeUtils.newMapper(null, false, null, true).convertValue(o, type); - - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - LOG.warn("Tag '"+o+"' declares kind '"+k2+"' but does not convert to "+type+" (ignoring): "+e); - } - } - } - } - return null; - } - - public static <T extends HasKind> List<T> findAllOfKind(String kind, Class<T> type, Iterable<Object> tags) { - List<T> result = MutableList.of(); - - for (Object o: tags) { - if (type.isInstance(o)) { - if (kind.equals(((T) o).getKind())) { - result.add( (T)o ); - } - } else if (o instanceof Map) { - Object k2 = ((Map) o).get("kind"); - if (kind.equals(k2)) { - try { - result.add( BeanWithTypeUtils.newMapper(null, false, null, true).convertValue(o, type) ); - - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - LOG.warn("Tag '"+o+"' declares kind '"+k2+"' but does not convert to "+type+" (ignoring): "+e); - } - } - } - } - - return result; - } public static SpecHierarchyTag findSpecHierarchyTag(Iterable<Object> tags) { return findFirstOfKind(SpecHierarchyTag.KIND, SpecHierarchyTag.class, tags); } - public static NamedStringTag findFirstNamedStringTag(String kind, Iterable<Object> tags) { - return findFirstOfKind(kind, NamedStringTag.class, tags); - } - - public static List<NamedStringTag> findAllNamedStringTags(String kind, Iterable<Object> tags) { - return findAllOfKind(kind, NamedStringTag.class, tags); - } - - /** @deprecated since 1.1 use {@link #findFirstNamedStringTag(String, Iterable)} */ - @Deprecated - public static NamedStringTag findFirst(String kind, Iterable<Object> tags) { - return findFirstNamedStringTag(kind, tags); - } - - /** @deprecated since 1.1 use {@link #findAllNamedStringTags(String, Iterable)} */ - @Deprecated - public static List<NamedStringTag> findAll(String kind, Iterable<Object> tags) { - return findAllNamedStringTags(kind, tags); + public static Integer getDepthInAncestorTag(Set<Object> tags) { + return BrooklynTags.findSingleKeyMapValue(BrooklynTags.DEPTH_IN_ANCESTOR, Integer.class, tags); } } diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java index 14bba3d..ad27456 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java @@ -18,10 +18,11 @@ */ package org.apache.brooklyn.core.typereg; +import java.util.List; import java.util.function.Function; import java.util.function.Supplier; import javax.annotation.Nullable; -import org.apache.brooklyn.api.catalog.BrooklynCatalog; +import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.typereg.RegisteredType; @@ -30,6 +31,7 @@ import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; import org.apache.brooklyn.core.mgmt.BrooklynTags; import org.apache.brooklyn.core.mgmt.BrooklynTags.SpecHierarchyTag; import org.apache.brooklyn.core.mgmt.BrooklynTags.SpecHierarchyTag.SpecSummary; +import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.javalang.JavaClassNames; @@ -196,7 +198,21 @@ public abstract class AbstractTypePlanTransformer implements BrooklynTypePlanTra spec.tag(specTag); } + if (spec instanceof EntitySpec) { + addDepthTagsWhereMissing( ((EntitySpec<?>)spec).getChildren(), 1 ); + } + return spec; } - + + protected void addDepthTagsWhereMissing(List<EntitySpec<?>> children, int depth) { + children.forEach(c -> { + Integer existingDepth = BrooklynTags.getDepthInAncestorTag(c.getTags()); + if (existingDepth==null) { + c.tag(MutableMap.of(BrooklynTags.DEPTH_IN_ANCESTOR, depth)); + addDepthTagsWhereMissing(c.getChildren(), depth+1); + } + }); + } + }
