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 0d6852920bb7fdc31d3160a08d4a63042ec05589 Merge: 0adb476 dd07beb Author: Alex Heneveld <[email protected]> AuthorDate: Fri May 28 14:48:17 2021 +0100 Merge branch 'master' into depth-tags Resolve the catalog yaml spec tags .../brooklyn/catalog/CatalogYamlEntityTest.java | 8 ++++++- .../apache/brooklyn/core/mgmt/BrooklynTags.java | 22 +++++++++++++------ .../core/typereg/AbstractTypePlanTransformer.java | 18 +++++++++------- .../brooklyn/rest/transform/TypeTransformer.java | 25 ++++++++++++++++++---- 4 files changed, 54 insertions(+), 19 deletions(-) diff --cc camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java index e45bae4,6658654..f99eb5c --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java @@@ -265,9 -271,9 +271,9 @@@ public class CatalogYamlEntityTest exte assertEquals(entity.getEntityType().getName(), TestEntity.class.getName()); // tests that the plan tag was set - assertTrue(entity.tags().getTags().stream().anyMatch(tag -> tag instanceof BrooklynTags.SpecTag)); - BrooklynTags.SpecTag specTag = (BrooklynTags.SpecTag) entity.tags().getTags().stream().filter(tag -> tag instanceof BrooklynTags.SpecTag).findAny().orElse(null); + BrooklynTags.SpecHierarchyTag specTag = BrooklynTags.findSpecHierarchyTag(entity.tags().getTags()); + Assert.assertNotNull(specTag); - assertEquals(specTag.getSpecList().size(), 2); + assertEquals(specTag.getSpecList().size(), 3); deleteCatalogRegisteredType(referencedSymbolicName); deleteCatalogRegisteredType(referrerSymbolicName); diff --cc core/src/main/java/org/apache/brooklyn/core/mgmt/BrooklynTags.java index c8a76d9,d5ce619..3eefe5d --- 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,15 -18,13 +18,12 @@@ */ 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.ListIterator; --import java.util.Map; ++import java.util.*; 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; import com.fasterxml.jackson.annotation.JsonIgnore; @@@ -44,11 -39,8 +41,11 @@@ import org.slf4j.LoggerFactory @Beta public class BrooklynTags { + private static final Logger LOG = LoggerFactory.getLogger(BrooklynTags.class); + public static final String YAML_SPEC_KIND = "yaml_spec"; -- public static final String YAML_SPEC_HIERARCHY = "yaml_spec_hierarchy"; ++ public static final String YAML_SPEC_HIERARCHY = "yaml_spec_hierarchy"; // TODO rename spec_hierarchy, have spec_source for catalog which gets removed + 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"; @@@ -181,98 -85,16 +178,99 @@@ } } - public static class SpecTag implements Serializable { + public static class SpecHierarchyTag implements Serializable, HasKind { private static final long serialVersionUID = 3805124696862755492L; + public static final String KIND = YAML_SPEC_HIERARCHY; + + public static class SpecSummary implements Serializable { + @JsonProperty + public final String summary; + @JsonProperty + public final String format; + @JsonProperty + public final Object contents; + ++ private SpecSummary() { this(null, null, null); }; //for JSON + public SpecSummary(String summary, String format, Object contents) { + this.summary = summary; + this.format = format; + this.contents = contents; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SpecSummary that = (SpecSummary) o; + return java.util.Objects.equals(summary, that.summary) && java.util.Objects.equals(format, that.format) && java.util.Objects.equals(contents, that.contents); + } + + @Override + public int hashCode() { + return java.util.Objects.hash(summary, format, contents); + } + + @Override + public String toString() { + return "SpecSummary{" + + "summary='" + summary + '\'' + + ", format='" + format + '\'' + + ", contents=" + contents + + '}'; + } + } + + public static Builder builder() { return new Builder(); } + public static Builder builder(SpecSummary base) { return new Builder(base); } + + public static class Builder { + private String summary; + private String format; + private Object contents; + + private Builder() {} + private Builder(SpecSummary base) { + summary = base.summary; + format = base.format; + contents = base.contents; + } + + public Builder summary(final String summary) { + this.summary = summary; + return this; + } + + public Builder format(final String format) { + this.format = format; + return this; + } + + public Builder contents(final Object contents) { + this.contents = contents; + return this; + } + + + public SpecSummary buildSpecSummary() { + return new SpecSummary(summary, format, contents); + } + + public SpecHierarchyTag buildSpecHierarchyTag() { + return new SpecHierarchyTag(BrooklynTags.YAML_SPEC_HIERARCHY, MutableList.of(buildSpecSummary())); + } + } + @JsonProperty - final String kind; + String kind; @JsonProperty - final List<Object> specList; + List<SpecSummary> specList; + + // for JSON + private SpecHierarchyTag() {} - public SpecTag(@JsonProperty("kind")String kind, @JsonProperty("specList")List<Object> specList) { + private SpecHierarchyTag(String kind, List<SpecSummary> specList) { this.kind = kind; this.specList = specList; } @@@ -307,20 -129,45 +305,32 @@@ return specList; } - public void push(SpecTag currentSpecTag) { - List<Object> specs = currentSpecTag.getSpecList(); - ListIterator<Object> li = specs.listIterator(specs.size()); - while (li.hasPrevious()) { - specList.add(0, li.previous()); - } - } - } - - public static class HierarchySpecTagBuilder { - private String format; - private String summary; - private Object contents; - - public HierarchySpecTagBuilder format(final String format) { - this.format = format; - return this; + public void push(SpecSummary newFirstSpecTag) { + // usually the list has a single element here, if + specList.add(0, newFirstSpecTag); } - - public HierarchySpecTagBuilder summary(final String summary) { - this.summary = summary; - return this; + public void push(SpecHierarchyTag newFirstSpecs) { + // usually the list has a single element here, if - newFirstSpecs.getSpecList().forEach(this::push); ++ List<SpecSummary> l = MutableList.copyOf(newFirstSpecs.getSpecList()); ++ Collections.reverse(l); ++ l.forEach(this::push); } - public HierarchySpecTagBuilder contents(final Object contents) { - this.contents = contents; - return this; + public SpecSummary pop() { + if (getSpecList().isEmpty()) return null; + return getSpecList().remove(0); } - - public SpecTag build() { - return new SpecTag(BrooklynTags.YAML_SPEC_HIERARCHY, MutableList.of( - MutableMap.of( - "format", format, - "summary", summary, - "contents", contents - ) - )); ++ public boolean modifyHeadSummary(java.util.function.Function<String, String> previousSummaryModification) { ++ if (!getSpecList().isEmpty() && previousSummaryModification!=null) { ++ SpecSummary oldHead = pop(); ++ SpecSummary newPrevHead = SpecHierarchyTag.builder(oldHead).summary( ++ previousSummaryModification.apply(oldHead.summary)).buildSpecSummary(); ++ push(newPrevHead); ++ return true; ++ } ++ return false; + } } public static class ListTag<T> { diff --cc core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java index ad27456,393614d..e97ac0f --- a/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/AbstractTypePlanTransformer.java @@@ -167,52 -161,30 +167,54 @@@ public abstract class AbstractTypePlanT protected abstract Object createBean(RegisteredType type, RegisteredTypeLoadingContext context) throws Exception; - protected AbstractBrooklynObjectSpec<?,?> decorateWithHierarchySpecTag(AbstractBrooklynObjectSpec<?, ?> spec, RegisteredType type, final String format, final String summary) { - final String specSummary = Strings.isBlank(summary) - ? format + " plan for " + (Strings.isNonBlank(type.getSymbolicName())? type.getSymbolicName() : type.getDisplayName()) - : summary; - - BrooklynTags.SpecTag currentSpecTag = new BrooklynTags.HierarchySpecTagBuilder() + protected AbstractBrooklynObjectSpec<?,?> decorateWithHierarchySpecTag(AbstractBrooklynObjectSpec<?, ?> spec, RegisteredType type, + final String format, @Nullable final String summary, + @Nullable Function<String,String> previousSummaryModification) { + final String specSummary = Strings.isNonBlank(summary) + ? summary + : format + " plan" + + (Strings.isNonBlank(type.getSymbolicName()) - ? "for type "+type.getSymbolicName() ++ ? " for type "+type.getSymbolicName() + : Strings.isNonBlank(type.getDisplayName()) - ? "for "+type.getDisplayName() ++ ? " for "+type.getDisplayName() + : ""); + + BrooklynTags.SpecHierarchyTag.Builder currentSpecTagBuilder = BrooklynTags.SpecHierarchyTag.builder() .format(format) .summary(specSummary) - .contents(type.getPlan().getPlanData()) - .build(); + .contents(type.getPlan().getPlanData()); - Object rtSpecTag = type.getTags().stream().filter(tag -> tag instanceof BrooklynTags.SpecTag).findAny().orElse(null); - if(rtSpecTag != null) { - currentSpecTag.push((BrooklynTags.SpecTag)rtSpecTag); + SpecHierarchyTag specTag = BrooklynTags.findSpecHierarchyTag(spec.getTags()); + if (specTag != null) { - if (!specTag.getSpecList().isEmpty() && previousSummaryModification!=null) { - SpecSummary oldHead = specTag.pop(); - SpecSummary newPrevHead = SpecHierarchyTag.builder(oldHead).summary( - previousSummaryModification.apply(oldHead.summary)).buildSpecSummary(); - specTag.push(newPrevHead); - } ++ specTag.modifyHeadSummary(previousSummaryModification); + specTag.push(currentSpecTagBuilder.buildSpecSummary()); + } else { + specTag = currentSpecTagBuilder.buildSpecHierarchyTag(); + spec.tag(specTag); } - Object specTagObj = spec.getTag(tag -> tag instanceof BrooklynTags.SpecTag); - if(specTagObj != null) { - BrooklynTags.SpecTag specTag = (BrooklynTags.SpecTag) specTagObj; - specTag.push(currentSpecTag); - } else { - spec.tag(currentSpecTag); ++ // TODO rename key as spec_sources ++ SpecSummary source = BrooklynTags.findSingleKeyMapValue(BrooklynTags.YAML_SPEC_HIERARCHY, SpecSummary.class, type.getTags()); ++ if (source != null) { ++ specTag.modifyHeadSummary(s -> "Converted for catalog to "+s); ++ specTag.push(source); + } ++ + 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); + } + }); + } + } diff --cc rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java index 2eb5c35,741c887..84f38b5 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java @@@ -18,6 -18,6 +18,7 @@@ */ package org.apache.brooklyn.rest.transform; ++import org.apache.brooklyn.core.mgmt.BrooklynTags.SpecHierarchyTag; import static org.apache.brooklyn.rest.util.WebResourceUtils.serviceUriBuilder; import java.net.URI; @@@ -98,6 -98,19 +99,22 @@@ public class TypeTransformer result.setExtraField("iconUrlSource", item.getIconUrl()); } } + + // adding tag type spec hierarchy using hierarchy tag - BrooklynTags.SpecTag currentSpecTag = new BrooklynTags.HierarchySpecTagBuilder() ++ SpecHierarchyTag currentSpecTag = SpecHierarchyTag.builder() + .format(StringUtils.isBlank(item.getPlan().getPlanFormat()) ? CampTypePlanTransformer.FORMAT : item.getPlan().getPlanFormat()) + // the default type implementation is camp in this location, but hierarchy tag provides the original implementation, so it takes precedence. + .summary((StringUtils.isBlank(item.getPlan().getPlanFormat()) ? CampTypePlanTransformer.FORMAT : item.getPlan().getPlanFormat()) + " implementation") + .contents(item.getPlan().getPlanData()) - .build(); - BrooklynTags.SpecTag specTag = BrooklynTags.findHierarchySpecTag(BrooklynTags.YAML_SPEC_HIERARCHY, item.getTags()); ++ .buildSpecHierarchyTag(); ++ ++ SpecHierarchyTag specTag = BrooklynTags.findSpecHierarchyTag(item.getTags()); + if(specTag!= null){ ++ currentSpecTag.modifyHeadSummary(s -> "Converted to "+s); + currentSpecTag.push(specTag); + } ++ + result.setExtraField("specList", currentSpecTag.getSpecList()); if (detail) { if (RegisteredTypes.isSubtypeOf(item, Entity.class)) {
