From: MichaelMorris Date: Tue, 15 Dec 2020 16:12:59 +0000 (+0000) Subject: Support for category specific metadata X-Git-Tag: 1.8.1~29 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F25%2F116625%2F7;p=sdc.git Support for category specific metadata Signed-off-by: MichaelMorris Issue-ID: SDC-3412 Change-Id: I87392cc21dc25253b558bdc1d453d99659d049fa --- diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java index 4330c0de43..d49284eab0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java @@ -25,7 +25,9 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.MetadataKeyEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.category.CategoryDefinition; @@ -40,6 +42,7 @@ import org.springframework.stereotype.Component; import org.yaml.snakeyaml.Yaml; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -226,7 +229,7 @@ public class CategoriesImportManager { } private List createServiceCategories(Map categories) { - List categroiesDef = new ArrayList<>(); + List categoriesDef = new ArrayList<>(); String catName = null; List icons = null; for (Entry entry : categories.entrySet()) { @@ -242,10 +245,29 @@ public class CategoriesImportManager { final boolean useServiceSubstitutionForNestedServices = useServiceSubstitutionForNestedServicesProperty == null ? false : (Boolean) useServiceSubstitutionForNestedServicesProperty; catDef.setUseServiceSubstitutionForNestedServices(useServiceSubstitutionForNestedServices); - categroiesDef.add(catDef); + catDef.setMetadataKeys(getMetadataKeys(category)); + categoriesDef.add(catDef); } - return categroiesDef; + return categoriesDef; + } + + private List getMetadataKeys(Map parentObject) { + Map metadataKeys = (Map) parentObject.getOrDefault(MetadataKeyEnum.METADATA_KEYS.getName(), Collections.EMPTY_MAP); + List metadataKeyDefs = new ArrayList<>(); + for (Entry metadataKey : metadataKeys.entrySet()) { + Map metadataKeyInfo = (Map) metadataKey.getValue(); + MetadataKeyDataDefinition metadataKeyDef = new MetadataKeyDataDefinition(); + String metadataKeyName = (String) metadataKeyInfo.get(MetadataKeyEnum.NAME.getName()); + metadataKeyDef.setName(metadataKeyName); + final Object mandatoryProperty = metadataKeyInfo.get(MetadataKeyEnum.MANDATORY.getName()); + final boolean mandatory = mandatoryProperty == null ? false : (Boolean) mandatoryProperty; + metadataKeyDef.setMandatory(mandatory); + List validValues = (List) metadataKeyInfo.get(MetadataKeyEnum.VALID_VALUES.getName()); + metadataKeyDef.setValidValues(validValues); + metadataKeyDefs.add(metadataKeyDef); + } + return metadataKeyDefs; } private List createResourceCategories(Map categoryPerType) { @@ -268,6 +290,7 @@ public class CategoriesImportManager { subDef.setIcons(subcategoryIcons); normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subcategoryName); subDef.setNormalizedName(normalizedName); + subDef.setMetadataKeys(getMetadataKeys(subcategoryInfo)); subcateDef.add(subDef); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 5c8d9c6c6d..6131eb5850 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -35,6 +35,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -67,6 +68,7 @@ import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterProp import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.model.ArtifactDefinition; @@ -410,37 +412,40 @@ public class ToscaExportHandler { } } - private ToscaMetadata convertMetadata(Component component) { + private Map convertMetadata(Component component) { return convertMetadata(component, false, null); } - private ToscaMetadata convertMetadata(Component component, boolean isInstance, + private Map convertMetadata(Component component, boolean isInstance, ComponentInstance componentInstance) { - ToscaMetadata toscaMetadata = new ToscaMetadata(); - toscaMetadata.setInvariantUUID(component.getInvariantUUID()); - toscaMetadata.setUUID(component.getUUID()); - toscaMetadata.setDescription(component.getDescription()); - toscaMetadata.setName(component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + Map toscaMetadata = new LinkedHashMap<>(); + toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID()); + toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID()); + toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription()); List categories = component.getCategories(); CategoryDefinition categoryDefinition = categories.get(0); - toscaMetadata.setCategory(categoryDefinition.getName()); + toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName()); if (isInstance) { - toscaMetadata.setVersion(component.getVersion()); - toscaMetadata.setCustomizationUUID(componentInstance.getCustomizationUUID()); + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),component.getVersion()); + toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID()); if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) { - toscaMetadata.setVersion(componentInstance.getComponentVersion()); - toscaMetadata.setSourceModelInvariant(componentInstance.getSourceModelInvariant()); - toscaMetadata.setSourceModelUuid(componentInstance.getSourceModelUuid()); - toscaMetadata.setSourceModelName(componentInstance.getSourceModelName()); + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),componentInstance.getComponentVersion()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(),componentInstance.getSourceModelInvariant()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(),componentInstance.getSourceModelUuid()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(),componentInstance.getSourceModelName()); if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) { - toscaMetadata.setName(componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue()); + toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), + componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue()); } else if (componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution) { - toscaMetadata.setName(componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution.getDisplayValue()); + toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), + componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution + .getDisplayValue()); } - toscaMetadata.setDescription(componentInstance.getDescription()); + toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(),componentInstance.getDescription()); } } @@ -449,33 +454,37 @@ public class ToscaExportHandler { Resource resource = (Resource) component; if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) { - toscaMetadata.setType(componentInstance.getOriginType().getDisplayValue()); + toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue()); } else { - toscaMetadata.setType(resource.getResourceType().name()); + toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name()); } - toscaMetadata.setSubcategory(categoryDefinition.getSubcategories().get(0).getName()); - toscaMetadata.setResourceVendor(resource.getVendorName()); - toscaMetadata.setResourceVendorRelease(resource.getVendorRelease()); - toscaMetadata.setResourceVendorModelNumber(resource.getResourceVendorModelNumber()); + toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(),resource.getVendorRelease()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(),resource.getResourceVendorModelNumber()); break; case SERVICE: Service service = (Service) component; - toscaMetadata.setType(component.getComponentType().getValue()); - toscaMetadata.setServiceType(service.getServiceType()); - toscaMetadata.setServiceRole(service.getServiceRole()); - toscaMetadata.setServiceFunction(service.getServiceFunction()); - toscaMetadata.setEnvironmentContext(service.getEnvironmentContext()); - resolveInstantiationTypeAndSetItToToscaMetaData(toscaMetadata, service); + toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(),component.getComponentType().getValue()); + toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(),service.getServiceType()); + toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(),service.getServiceRole()); + toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(),service.getServiceFunction()); + toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(),service.getEnvironmentContext()); + toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType()); if (!isInstance) { // DE268546 - toscaMetadata.setServiceEcompNaming(((Service) component).isEcompGeneratedNaming()); - toscaMetadata.setEcompGeneratedNaming(((Service) component).isEcompGeneratedNaming()); - toscaMetadata.setNamingPolicy(((Service) component).getNamingPolicy()); + toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); + toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); + toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(),service.getNamingPolicy()); } break; default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); } + + for (final String key: component.getCategorySpecificMetadata().keySet()) { + toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key)); + } return toscaMetadata; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java index 04515b297c..50a8f3da3b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java @@ -37,7 +37,7 @@ public class ToscaNodeTemplate { private String type; private List directives; - private ToscaMetadata metadata; + private Map metadata; private String description; private Map properties; private List> requirements; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java index 742e8bb233..7fc60d1b5d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java @@ -20,104 +20,29 @@ package org.openecomp.sdc.be.tosca.model; -import org.apache.commons.lang3.tuple.Triple; -import org.openecomp.sdc.be.model.Component; - import java.util.List; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.model.Component; +@Getter +@Setter public class ToscaTemplate { private String tosca_definitions_version; - private ToscaMetadata metadata; + private Map metadata; private List>> imports; private Map interface_types; private Map data_types; private Map node_types; private ToscaTopolgyTemplate topology_template; - private List> dependencies; - public ToscaTemplate(String tosca_definitions_version) { - this.tosca_definitions_version = tosca_definitions_version; - } - - public Map getNode_types() { - return node_types; - } - - public void setNode_types(Map node_types) { - this.node_types = node_types; - } - - - public List>> getImports() { - return imports; - } - - public void setImports(List>> imports) { - this.imports = imports; - } - - public String getTosca_definitions_version() { - return tosca_definitions_version; - } - - public void setTosca_definitions_version(String tosca_definitions_version) { - this.tosca_definitions_version = tosca_definitions_version; - } - - public ToscaMetadata getMetadata() { - return metadata; - } - - public void setMetadata(ToscaMetadata metadata) { - this.metadata = metadata; - } - - public ToscaTopolgyTemplate getTopology_template() { - return topology_template; - } - - public void setTopology_template(ToscaTopolgyTemplate topology_template) { - this.topology_template = topology_template; - } - - public List> getDependencies() { - return dependencies; - } - - public void setDependencies(List> dependencies) { - this.dependencies = dependencies; - } - - public Map getInterface_types() { - return interface_types; - } - - // public void setInterface_types(Map interface_types) { - // this.interface_types = interface_types; - // } - - public void setInterface_types(Map interface_types) { - this.interface_types = interface_types; - + public ToscaTemplate(final String toscaDefinitionsVersion) { + this.tosca_definitions_version = toscaDefinitionsVersion; } - /** - * Gets data_types map. - * @return Current data_types map. - */ - public Map getData_types() { - return data_types; - } - - /** - * Sets data_types map. - * @param data_types New data_types map. - */ - public void setData_types(Map data_types) { - this.data_types = data_types; - } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java index d54fc98c9a..b03e12fb6e 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java @@ -433,10 +433,8 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { componentInstance.setOriginType(OriginTypeEnum.ServiceProxy); componentInstance.setSourceModelInvariant("targetModelInvariant"); - ToscaMetadata result; - // default test - result = Deencapsulation.invoke(testSubject, "convertMetadata", component, isInstance, componentInstance); + Map result = Deencapsulation.invoke(testSubject, "convertMetadata", component, isInstance, componentInstance); Assert.assertNotNull(result); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplateTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplateTest.java index 7c28e9f03d..e8f53f015c 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplateTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplateTest.java @@ -124,7 +124,7 @@ public class ToscaNodeTemplateTest { @Test public void testGetMetadata() throws Exception { ToscaNodeTemplate testSubject; - ToscaMetadata result; + Map result; // default test testSubject = createTestSubject(); @@ -135,7 +135,7 @@ public class ToscaNodeTemplateTest { @Test public void testSetMetadata() throws Exception { ToscaNodeTemplate testSubject; - ToscaMetadata metadata = null; + Map metadata = null; // default test testSubject = createTestSubject(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java index 36674a702b..13bb415bc0 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java @@ -104,7 +104,7 @@ public class ToscaTemplateTest { @Test public void testGetMetadata() throws Exception { ToscaTemplate testSubject; - ToscaMetadata result; + Map result; // default test testSubject = createTestSubject(); @@ -115,7 +115,7 @@ public class ToscaTemplateTest { @Test public void testSetMetadata() throws Exception { ToscaTemplate testSubject; - ToscaMetadata metadata = null; + Map metadata = null; // default test testSubject = createTestSubject(); diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java index 11dcdceaaf..f3e64b11c6 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/GraphVertex.java @@ -167,6 +167,20 @@ public class GraphVertex { } return null; } + + public void setJsonMetadataField(String field, Object value) { + if (metadataJson == null) { + metadataJson = new HashMap<>(); + } + metadataJson.put(field, value); + } + + public Object getJsonMetadataField(String field) { + if (metadataJson != null) { + return metadataJson.get(field); + } + return null; + } /** * Updates metadata json with current metadataProperties. Note that already existing property containing in metadata json can be overrided by new value if metadataProperties contains the same property (by key). Note that metadata json can contain diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java index da6e5d5d44..8581895681 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java @@ -126,7 +126,8 @@ public enum GraphPropertiesDictionary { CONSTANT_UUID ("constantUuidNew", String.class, false, true), CONTACTS ("contacts", String.class, false, false), //categorys - ICONS ("icons", String.class, false, false), + ICONS ("icons", String.class, false, false), + METADATA_KEYS ("metadataKeys", String.class, false, false), USE_SERVICE_SUBSTITUTION_FOR_NESTED_SERVICES ("useServiceSubstitutionForNestedServices", Boolean.class, false, false), //relation CAPABILITY_OWNER_ID ("capOwnerId", String.class, false, false), diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/CategoryData.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/CategoryData.java index 8db7b53017..613f91d841 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/CategoryData.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/CategoryData.java @@ -24,6 +24,7 @@ import com.google.gson.reflect.TypeToken; import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import java.lang.reflect.Type; @@ -60,6 +61,11 @@ public class CategoryData extends GraphNode { List iconsfromJson = getGson() .fromJson((String) properties.get(GraphPropertiesDictionary.ICONS.getProperty()), listType); categoryDataDefinition.setIcons(iconsfromJson); + + final Type metadataKeylistType = new TypeToken>() {}.getType(); + final List metadataKeysfromJson = getGson() + .fromJson((String) properties.get(GraphPropertiesDictionary.METADATA_KEYS.getProperty()), metadataKeylistType); + categoryDataDefinition.setMetadataKeys(metadataKeysfromJson); } @Override @@ -82,6 +88,7 @@ public class CategoryData extends GraphNode { // addIfExists(map, GraphPropertiesDictionary.ICONS, icons); addIfExists(map, GraphPropertiesDictionary.ICONS, categoryDataDefinition.getIcons()); addIfExists(map, GraphPropertiesDictionary.USE_SERVICE_SUBSTITUTION_FOR_NESTED_SERVICES, categoryDataDefinition.isUseServiceSubstitutionForNestedServices()); + addIfExists(map, GraphPropertiesDictionary.METADATA_KEYS, categoryDataDefinition.getMetadataKeys()); return map; } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/SubCategoryData.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/SubCategoryData.java index cbae4561e1..13976035b6 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/SubCategoryData.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/SubCategoryData.java @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.resources.data.category; import com.google.gson.reflect.TypeToken; import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -59,6 +60,11 @@ public class SubCategoryData extends GraphNode { List iconsfromJson = getGson() .fromJson((String) properties.get(GraphPropertiesDictionary.ICONS.getProperty()), listType); subCategoryDataDefinition.setIcons(iconsfromJson); + + final Type metadataKeylistType = new TypeToken>() {}.getType(); + final List metadataKeysfromJson = getGson() + .fromJson((String) properties.get(GraphPropertiesDictionary.METADATA_KEYS.getProperty()), metadataKeylistType); + subCategoryDataDefinition.setMetadataKeys(metadataKeysfromJson); } public SubCategoryDataDefinition getSubCategoryDataDefinition() { @@ -80,6 +86,7 @@ public class SubCategoryData extends GraphNode { // String icons=getGson().toJson(subCategoryDataDefinition.getIcons()); // addIfExists(map, GraphPropertiesDictionary.ICONS, icons); addIfExists(map, GraphPropertiesDictionary.ICONS, subCategoryDataDefinition.getIcons()); + addIfExists(map, GraphPropertiesDictionary.METADATA_KEYS, subCategoryDataDefinition.getMetadataKeys()); return map; } } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java index bf9c3275a6..7b188ac978 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java @@ -29,6 +29,7 @@ import static org.apache.commons.collections.MapUtils.isEmpty; import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Maps; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -89,6 +90,14 @@ public abstract class Component implements PropertiesOwner { private Map interfaces; private List dataTypes; private SubstitutionFilterDataDefinition substitutionFilter; + + public void setCategorySpecificMetadata(final Map categorySpecificMetadata) { + componentMetadataDefinition.getMetadataDataDefinition().setCategorySpecificMetadata(categorySpecificMetadata); + } + public Map getCategorySpecificMetadata() { + final Map categorySpecificMetadata = componentMetadataDefinition.getMetadataDataDefinition().getCategorySpecificMetadata(); + return categorySpecificMetadata == null ? Collections.emptyMap() : categorySpecificMetadata; + } public Component(ComponentMetadataDefinition componentMetadataDefinition) { this.componentMetadataDefinition = componentMetadataDefinition; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/ToscaElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/ToscaElement.java index ce9e5e0c43..baea051538 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/ToscaElement.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/ToscaElement.java @@ -85,11 +85,14 @@ public abstract class ToscaElement { } public void setMetadataValue(JsonPresentationFields name, Object value) { + setMetadataValue(name.getPresentation(), value); + } + + public void setMetadataValue(String name, Object value) { if (metadata == null) { metadata = new HashMap<>(); } - metadata.put(name.getPresentation(), value); - + metadata.put(name, value); } // -------------------- public String getUUID() { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java index 3109107f03..76f952b4c4 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java @@ -39,6 +39,7 @@ import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapAttributesDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty; import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition; @@ -1189,6 +1190,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation { Type listTypeCat = new TypeToken>() {}.getType(); List iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS.getProperty()), listTypeCat); category.setIcons(iconsfromJsonCat); + + final Type metadataKeysTypeCat = new TypeToken>() {}.getType(); + final List metadataKeysfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.METADATA_KEYS), metadataKeysTypeCat); + category.setMetadataKeys(metadataKeysfromJsonCat); + categories.add(category); toscaElement.setCategories(categories); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java index bc77d20ed5..3ae39fdc4a 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementOperation.java @@ -54,6 +54,7 @@ import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; @@ -330,7 +331,7 @@ public abstract class ToscaElementOperation extends BaseOperation { nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ARCHIVED, toscaElement.getMetadataValue(JsonPresentationFields.IS_ARCHIVED)); nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.ARCHIVE_TIME, toscaElement.getMetadataValue(JsonPresentationFields.ARCHIVE_TIME)); nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_VSP_ARCHIVED, toscaElement.getMetadataValue(JsonPresentationFields.IS_VSP_ARCHIVED)); - toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue())); + toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(e.getKey(), e.getValue())); nodeTypeVertex.setUniqueId(toscaElement.getUniqueId()); nodeTypeVertex.setType(toscaElement.getComponentType()); @@ -1046,6 +1047,12 @@ public abstract class ToscaElementOperation extends BaseOperation { subcategory.setUniqueId((String) subCategoryV.property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value()); subcategory.setNormalizedName(subCategoryNormalizedName); subcategory.setName((String) subCategoryV.property(GraphPropertyEnum.NAME.getProperty()).value()); + + Type listTypeSubcat = new TypeToken>() { + }.getType(); + List metadataKeys = getGson().fromJson((String) subCategoryV.property(GraphPropertyEnum.METADATA_KEYS.getProperty()).value(), listTypeSubcat); + subcategory.setMetadataKeys(metadataKeys); + Either parentVertex = janusGraphDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse); Vertex categoryV = parentVertex.left().value(); String categoryNormalizedName = (String) categoryV.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value(); @@ -1077,6 +1084,11 @@ public abstract class ToscaElementOperation extends BaseOperation { category.setName((String) categoryV.property(GraphPropertyEnum.NAME.getProperty()).value()); category.setUseServiceSubstitutionForNestedServices((Boolean) categoryV.property(GraphPropertyEnum.USE_SUBSTITUTION_FOR_NESTED_SERVICES.getProperty()).orElse(false)); + Type listTypeCat = new TypeToken>() { + }.getType(); + List metadataKeys = getGson().fromJson((String) categoryV.property(GraphPropertyEnum.METADATA_KEYS.getProperty()).value(), listTypeCat); + category.setMetadataKeys(metadataKeys); + categories.add(category); catalogComponent.setCategories(categories); return JanusGraphOperationStatus.OK; @@ -1104,6 +1116,10 @@ public abstract class ToscaElementOperation extends BaseOperation { List iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat); subcategory.setIcons(iconsfromJsonSubcat); + final Type metadataKeysTypeCat = new TypeToken>() {}.getType(); + final List metadataKeysfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.METADATA_KEYS), metadataKeysTypeCat); + subcategory.setMetadataKeys(metadataKeysfromJsonCat); + Either parentVertex = janusGraphDao .getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse); if (parentVertex.isRight()) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java index 146d5d6c80..bbda9776f7 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java @@ -39,10 +39,12 @@ import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionaryExtractor; +import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; @@ -105,6 +107,8 @@ import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; @@ -776,6 +780,7 @@ public class ModelConverter { } else { resource.setResourceVendorModelNumber(""); } + } else if (component.getComponentType() == ComponentTypeEnum.SERVICE) { Service service = (Service) component; if (((String) toscaElement.getMetadataValue(JsonPresentationFields.SERVICE_TYPE)) != null){ @@ -803,6 +808,41 @@ public class ModelConverter { component.setUUID((String) toscaElement.getMetadataValue(JsonPresentationFields.UUID)); component.setIsDeleted((Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED)); component.setToscaType(toscaElement.getToscaType().getValue()); + final List metadataKeys = getCategorySpecificMetadataKeys(toscaElement); + if (CollectionUtils.isNotEmpty(metadataKeys)) { + final Map categorySpecificMetadata = new HashMap<>(); + for (final String metadataKey: metadataKeys) { + categorySpecificMetadata.put(metadataKey, (String) toscaElement.getMetadata().get(metadataKey)); + } + component.setCategorySpecificMetadata(categorySpecificMetadata ); + } + } + + private static List getCategorySpecificMetadataKeys(final ToscaElement toscaElement){ + final List metadataKeys = new ArrayList<>(); + final Optional category = getCategory(toscaElement); + if (category.isPresent()) { + if (CollectionUtils.isNotEmpty(category.get().getMetadataKeys())) { + for (final MetadataKeyDataDefinition metadataKey: category.get().getMetadataKeys()) { + metadataKeys.add(metadataKey.getName()); + } + } + final Optional subCategory = getSubCategory(category.get()); + if (subCategory.isPresent() && CollectionUtils.isNotEmpty(subCategory.get().getMetadataKeys())) { + for (final MetadataKeyDataDefinition metadataKey: subCategory.get().getMetadataKeys()) { + metadataKeys.add(metadataKey.getName()); + } + } + } + return metadataKeys; + } + + private static Optional getCategory(ToscaElement toscaElement) { + return CollectionUtils.isEmpty(toscaElement.getCategories()) ? Optional.empty() : Optional.of(toscaElement.getCategories().get(0)); + } + + private static Optional getSubCategory(CategoryDefinition category) { + return CollectionUtils.isEmpty(category.getSubcategories()) ? Optional.empty() : Optional.of(category.getSubcategories().get(0)); } private static NodeType convertToNodeType(Component component) { @@ -1345,6 +1385,10 @@ public class ModelConverter { toscaElement.setMetadataValue(JsonPresentationFields.TAGS, component.getTags()); toscaElement.setMetadataValue(JsonPresentationFields.INVARIANT_UUID, component.getInvariantUUID()); toscaElement.setMetadataValue(JsonPresentationFields.CONTACT_ID, component.getContactId()); + for (final String key: component.getCategorySpecificMetadata().keySet()) { + toscaElement.setMetadataValue(key, component.getCategorySpecificMetadata().get(key)); + } + final List dataTypes = component.getDataTypes(); if (CollectionUtils.isNotEmpty(dataTypes)) { toscaElement.setDataTypes(dataTypes.stream() diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java index c8d7bdfb7c..971f966d5f 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceMetadata.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.ui.model; import java.util.List; +import java.util.Map; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -42,6 +43,7 @@ public class UiResourceMetadata extends UiComponentMetadata { private String licenseType; private String toscaResourceName; private List derivedFrom; + private Map categorySpecificMetadata; public UiResourceMetadata(List categories, List derivedFrom, @@ -55,6 +57,7 @@ public class UiResourceMetadata extends UiComponentMetadata { this.licenseType = metadata.getLicenseType(); this.toscaResourceName = metadata.getToscaResourceName(); this.derivedFrom = derivedFrom; + this.categorySpecificMetadata = metadata.getCategorySpecificMetadata(); } } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java index e1fe5876e6..6aec7bca36 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiServiceMetadata.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.ui.model; import java.util.List; +import java.util.Map; import lombok.Getter; import lombok.Setter; import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; @@ -38,6 +39,7 @@ public class UiServiceMetadata extends UiComponentMetadata { private String environmentContext; private String instantiationType; private String serviceFunction; + private Map categorySpecificMetadata; public UiServiceMetadata(List categories, ServiceMetadataDataDefinition metadata) { super(categories, metadata); @@ -49,6 +51,7 @@ public class UiServiceMetadata extends UiComponentMetadata { this.environmentContext = metadata.getEnvironmentContext(); this.instantiationType = metadata.getInstantiationType(); this.serviceFunction = metadata.getServiceFunction(); + this.categorySpecificMetadata = metadata.getCategorySpecificMetadata(); } } diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java index a8a201d9eb..654b074d9b 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java @@ -303,6 +303,7 @@ public class ToscaElementLifecycleOperationTest extends ModelTestBase { metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_CATEGORY.getName()); metadataProperties.put(GraphPropertyEnum.NAME, categoryName); metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName)); + metadataProperties.put(GraphPropertyEnum.METADATA_KEYS, "[]"); cat.setMetadataProperties(metadataProperties); cat.updateMetadataJsonWithCurrentMetadataProperties(); @@ -314,6 +315,7 @@ public class ToscaElementLifecycleOperationTest extends ModelTestBase { metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.RESOURCE_SUBCATEGORY.getName()); metadataProperties.put(GraphPropertyEnum.NAME, subcategory); metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(subcategory)); + metadataProperties.put(GraphPropertyEnum.METADATA_KEYS, "[]"); subCat.setMetadataProperties(metadataProperties); subCat.updateMetadataJsonWithCurrentMetadataProperties(); @@ -337,6 +339,7 @@ public class ToscaElementLifecycleOperationTest extends ModelTestBase { metadataProperties.put(GraphPropertyEnum.LABEL, VertexTypeEnum.SERVICE_CATEGORY.getName()); metadataProperties.put(GraphPropertyEnum.NAME, categoryName); metadataProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normalizeCategoryName4Uniqueness(categoryName)); + metadataProperties.put(GraphPropertyEnum.METADATA_KEYS, "[]"); cat.setMetadataProperties(metadataProperties); cat.updateMetadataJsonWithCurrentMetadataProperties(); diff --git a/catalog-ui/src/app/models/category.ts b/catalog-ui/src/app/models/category.ts index 15df98569d..64588d0c44 100644 --- a/catalog-ui/src/app/models/category.ts +++ b/catalog-ui/src/app/models/category.ts @@ -28,6 +28,7 @@ export interface ICategoryBase { normalizedName:string; uniqueId:string; icons:Array; + metadataKeys: IMetadataKey[]; //custom properties filterTerms:string; @@ -46,3 +47,9 @@ export interface ISubCategory extends ICategoryBase { export interface IGroup extends ICategoryBase { } + +export interface IMetadataKey { + name:string; + mandatory:boolean + validValues: string[]; +} diff --git a/catalog-ui/src/app/models/component-metadata.ts b/catalog-ui/src/app/models/component-metadata.ts index 8a4b257f55..186cd8aa39 100644 --- a/catalog-ui/src/app/models/component-metadata.ts +++ b/catalog-ui/src/app/models/component-metadata.ts @@ -21,6 +21,7 @@ import { CapabilitiesGroup, RequirementsGroup } from 'app/models'; import { ComponentType } from 'app/utils'; import { IMainCategory } from './category'; +import { Metadata } from "app/models/metadata"; /** * Created by obarda on 4/18/2017. */ @@ -53,6 +54,7 @@ export interface IComponentMetadata { vspArchived: boolean; selectedCategory: string; filterTerm: string; + categorySpecificMetadata: Metadata; // Resource only resourceType: string; @@ -115,6 +117,7 @@ export class ComponentMetadata implements IComponentMetadata { public toscaResourceName: string; public selectedCategory: string; public filterTerm: string; + public categorySpecificMetadata: Metadata = new Metadata(); // Resource only public resourceType: string; @@ -192,6 +195,7 @@ export class ComponentMetadata implements IComponentMetadata { this.toscaResourceName = response.toscaResourceName; this.capabilities = response.capabilities; this.requirements = response.requirements; + this.categorySpecificMetadata = response.categorySpecificMetadata; return this; } diff --git a/catalog-ui/src/app/models/components/component.ts b/catalog-ui/src/app/models/components/component.ts index a0706b4157..1d48151be8 100644 --- a/catalog-ui/src/app/models/components/component.ts +++ b/catalog-ui/src/app/models/components/component.ts @@ -35,6 +35,7 @@ import {Requirement} from "../requirement"; import {Relationship} from "../graph/relationship"; import { PolicyInstance } from "app/models/graph/zones/policy-instance"; import { GroupInstance } from "../graph/zones/group-instance"; +import { Metadata } from "app/models/metadata"; // import {} @@ -142,6 +143,7 @@ export abstract class Component implements IComponent { public archived:boolean; public vspArchived: boolean; public componentMetadata: ComponentMetadata; + public categorySpecificMetadata: Metadata = new Metadata(); constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) { if (component) { @@ -198,12 +200,36 @@ export abstract class Component implements IComponent { this.policies = component.policies; this.archived = component.archived; this.vspArchived = component.vspArchived; + + if (component.categorySpecificMetadata && component.categories && component.categories[0]){ + this.copyCategoryMetadata(component); + this.copySubcategoryMetadata(component); + } } //custom properties this.componentService = componentService; } + private copyCategoryMetadata = (component:Component):void => { + if (component.categories[0].metadataKeys){ + for (let key of Object.keys(component.categorySpecificMetadata)) { + if (component.categories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + this.categorySpecificMetadata[key] = component.categorySpecificMetadata[key]; + } + } + } + } + private copySubcategoryMetadata = (component:Component):void => { + if (component.categories[0].subcategories && component.categories[0].subcategories[0] && component.categories[0].subcategories[0].metadataKeys){ + for (let key of Object.keys(component.categorySpecificMetadata)) { + if (component.categories[0].subcategories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + this.categorySpecificMetadata[key] = component.categorySpecificMetadata[key]; + } + } + } + } + public setUniqueId = (uniqueId:string):void => { this.uniqueId = uniqueId; }; @@ -543,6 +569,11 @@ export abstract class Component implements IComponent { this.archived = componentMetadata.archived || false; this.vspArchived = componentMetadata.vspArchived; this.componentMetadata = componentMetadata; + if (componentMetadata.categorySpecificMetadata){ + this.categorySpecificMetadata = componentMetadata.categorySpecificMetadata; + } else { + this.categorySpecificMetadata = new Metadata(); + } } public toJSON = ():any => { diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap index fdd0dcf75c..7fcb62dbd3 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/__snapshots__/info-tab.component.spec.ts.snap @@ -50,6 +50,7 @@ exports[`InfoTabComponent can load instance 1`] = ` +
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html index 71545f8143..cafe93e103 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.html @@ -116,6 +116,14 @@ {{component.customizationUUID}}
+ + +
+ + {{metadata.value}} +
+
+
diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts index 6915d651f1..388e4b5542 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/info-tab/info-tab.component.spec.ts @@ -19,6 +19,8 @@ import _ from "lodash"; import { TranslateService } from "../../../../../shared/translator/translate.service"; import { SdcUiServices } from "onap-ui-angular"; import { Component as TopologyTemplate, FullComponentInstance, ComponentInstance } from '../../../../../../../app/models'; +import {KeyValuePipe} from "../../../../../pipes/key-value.pipe"; + describe('InfoTabComponent', () => { @@ -48,7 +50,7 @@ describe('InfoTabComponent', () => { const configure: ConfigureFn = testBed => { testBed.configureTestingModule({ imports: [ ], - declarations: [ InfoTabComponent, TranslatePipe ], + declarations: [ InfoTabComponent, TranslatePipe, KeyValuePipe ], schemas: [ NO_ERRORS_SCHEMA ], providers: [ { provide: Store, useValue: {} }, diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts index e10dc98fac..cab4b6c236 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts @@ -24,12 +24,13 @@ import {ModalsHandler, ValidationUtils, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FL ResourceType, ComponentState, instantiationType, ComponentFactory} from "app/utils"; import { EventListenerService, ProgressService} from "app/services"; import {CacheService, OnboardingService, ImportVSPService} from "app/services-ng2"; -import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component} from "app/models"; +import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component, IMetadataKey} from "app/models"; import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; import {Dictionary} from "lodash"; import { PREVIOUS_CSAR_COMPONENT } from "../../../../utils/constants"; import { Observable, Subject } from "rxjs"; - +import { MetadataEntry } from "app/models/metadataEntry"; +import { Metadata } from "app/models/metadata"; export class Validation { componentNameValidationPattern:RegExp; @@ -630,6 +631,20 @@ export class GeneralViewModel { this.$scope.component.selectedCategory = this.$scope.componentCategories.selectedCategory; this.$scope.component.categories = this.convertCategoryStringToOneArray(); this.$scope.component.icon = DEFAULT_ICON; + if (this.$scope.component.categories[0].metadataKeys) { + for (let metadataKey of this.$scope.component.categories[0].metadataKeys) { + if (!this.$scope.component.categorySpecificMetadata[metadataKey.name]) { + this.$scope.component.categorySpecificMetadata[metadataKey.name] = ""; + } + } + } + if (this.$scope.component.categories[0].subcategories && this.$scope.component.categories[0].subcategories[0].metadataKeys) { + for (let metadataKey of this.$scope.component.categories[0].subcategories[0].metadataKeys) { + if (!this.$scope.component.categorySpecificMetadata[metadataKey.name]) { + this.$scope.component.categorySpecificMetadata[metadataKey.name] = ""; + } + } + } }; this.$scope.onEcompGeneratedNamingChange = (): void => { @@ -645,11 +660,51 @@ export class GeneralViewModel { }; this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload); + + this.$scope.isMetadataKeyMandatory = (key: string): boolean => { + let metadataKey = this.getMetadataKey(this.$scope.component.categories, key); + return metadataKey && metadataKey.mandatory; + } + + this.$scope.getMetadataKeyValidValues = (key: string): string[] => { + let metadataKey = this.getMetadataKey(this.$scope.component.categories, key); + if (metadataKey) { + return metadataKey.validValues; + } + return []; + } + + this.$scope.isMetadataKeyForComponentCategory = (key: string): boolean => { + return this.getMetadataKey(this.$scope.component.categories, key) != null; + } + } private setUnsavedChanges = (hasChanges: boolean): void => { this.$state.current.data.unsavedChanges = hasChanges; } + private getMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + let metadataKey = this.getSubcategoryMetadataKey(this.$scope.component.categories, key); + if (!metadataKey){ + return this.getCategoryMetadataKey(this.$scope.component.categories, key); + } + return metadataKey; + } + + private getSubcategoryMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + if (categories[0].subcategories && categories[0].subcategories[0].metadataKeys && categories[0].subcategories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + return categories[0].subcategories[0].metadataKeys.find(metadataKey => metadataKey.name == key); + } + return null; + } + + private getCategoryMetadataKey(categories: IMainCategory[], key: string) : IMetadataKey { + if (categories[0].metadataKeys && categories[0].metadataKeys.some(metadataKey => metadataKey.name == key)) { + return categories[0].metadataKeys.find(metadataKey => metadataKey.name == key); + } + return null; + } + } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html index 42a8aa3e68..a04948e460 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html @@ -114,6 +114,65 @@
+ + + +
+ +
+ + +
+ +
+
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index cad8fc78df..fd4a3826b3 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -228,6 +228,7 @@ "NEW_SERVICE_RESOURCE_ERROR_RESOURCE_DESCRIPTION_REQUIRED": "Description is required.", "NEW_SERVICE_RESOURCE_ERROR_VENDOR_NAME_REQUIRED": "Vendor name is required.", "NEW_SERVICE_RESOURCE_ERROR_VENDOR_RELEASE_REQUIRED": "Vendor Release is required.", + "NEW_SERVICE_RESOURCE_ERROR_REQUIRED": "Value is required.", "NEW_SERVICE_RESOURCE_ERROR_TEMPLATE_REQUIRED": "Template is required.", "NEW_SERVICE_RESOURCE_ERROR_TAG_PATTERN": "{{text}}", "NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE": "Invalid Tosca file", diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/CategoryDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/CategoryDataDefinition.java index cf0117f74a..5758dbeaf5 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/CategoryDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/CategoryDataDefinition.java @@ -40,6 +40,7 @@ public class CategoryDataDefinition extends ToscaDataDefinition { private String uniqueId; private List icons; private boolean useServiceSubstitutionForNestedServices = false; + private List metadataKeys; public CategoryDataDefinition(CategoryDataDefinition c) { this.name = c.name; @@ -47,6 +48,7 @@ public class CategoryDataDefinition extends ToscaDataDefinition { this.uniqueId = c.uniqueId; this.icons = c.icons; this.useServiceSubstitutionForNestedServices = c.useServiceSubstitutionForNestedServices; + this.metadataKeys = c.metadataKeys; } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/MetadataKeyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/MetadataKeyDataDefinition.java new file mode 100644 index 0000000000..4d8a197473 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/MetadataKeyDataDefinition.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.be.datatypes.category; + +import java.util.List; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@ToString +@NoArgsConstructor +public class MetadataKeyDataDefinition extends ToscaDataDefinition { + private String name; + private List validValues; + private boolean mandatory; + + public MetadataKeyDataDefinition(MetadataKeyDataDefinition metadataKeyDataDefinition) { + this.name = metadataKeyDataDefinition.name; + this.validValues = metadataKeyDataDefinition.validValues; + this.mandatory = metadataKeyDataDefinition.mandatory; + } +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/SubCategoryDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/SubCategoryDataDefinition.java index 986f79fd4b..38d7027e49 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/SubCategoryDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/SubCategoryDataDefinition.java @@ -21,113 +21,32 @@ package org.openecomp.sdc.be.datatypes.category; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; - +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; import java.util.List; +@Getter +@Setter +@EqualsAndHashCode(callSuper = false) +@ToString +@NoArgsConstructor public class SubCategoryDataDefinition extends ToscaDataDefinition { private String name; private String normalizedName; private String uniqueId; private List icons; - - public SubCategoryDataDefinition() { - - } + private List metadataKeys; public SubCategoryDataDefinition(SubCategoryDataDefinition c) { this.name = c.name; this.normalizedName = c.normalizedName; this.uniqueId = c.uniqueId; this.icons = c.icons; + this.metadataKeys = c.metadataKeys; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getNormalizedName() { - return normalizedName; - } - - public void setNormalizedName(String normalizedName) { - this.normalizedName = normalizedName; - } - - public String getUniqueId() { - return uniqueId; - } - - public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; - } - - public List getIcons() { - return icons; - } - - public void setIcons(List icons) { - this.icons = icons; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((normalizedName == null) ? 0 : normalizedName.hashCode()); - result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); - result = prime * result + ((icons == null) ? 0 : icons.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - SubCategoryDataDefinition other = (SubCategoryDataDefinition) obj; - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - if (normalizedName == null) { - if (other.normalizedName != null) { - return false; - } - } else if (!normalizedName.equals(other.normalizedName)) { - return false; - } - if (uniqueId == null) { - if (other.uniqueId != null) { - return false; - } - } else if (!uniqueId.equals(other.uniqueId)) { - return false; - } - if (icons == null) { - return other.icons == null; - } else { - return icons.equals(other.icons); - } - } - - @Override - public String toString() { - return "SubCategoryDataDefinition [name=" + name + ", normalizedName=" + normalizedName + ", uniqueId=" - + uniqueId + ", icons=" + icons + "]"; - } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ComponentMetadataDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ComponentMetadataDataDefinition.java index e1d0d96d9a..96cccf62bb 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ComponentMetadataDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ComponentMetadataDataDefinition.java @@ -131,6 +131,9 @@ public abstract class ComponentMetadataDataDefinition extends ToscaDataDefinitio @Getter @Setter private Boolean isVspArchived = false; + @Getter + @Setter + private Map categorySpecificMetadata; public ComponentMetadataDataDefinition(ComponentMetadataDataDefinition other) { this.uniqueId = other.getUniqueId(); @@ -157,6 +160,7 @@ public abstract class ComponentMetadataDataDefinition extends ToscaDataDefinitio this.isArchived = other.isArchived; this.isVspArchived = other.isVspArchived; this.archiveTime = other.getArchiveTime(); + this.categorySpecificMetadata = other.getCategorySpecificMetadata(); } public ComponentMetadataDataDefinition(JsonPresentationFieldsExtractor extractor) { @@ -245,4 +249,5 @@ public abstract class ComponentMetadataDataDefinition extends ToscaDataDefinitio * @return */ public abstract String getActualComponentType(); + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java index 70f76030bd..44a0d23d1c 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GraphPropertyEnum.java @@ -54,6 +54,7 @@ public enum GraphPropertyEnum { LAST_LOGIN_TIME("lastLoginTime", Long.class, false, false), //used for category (old format, no json for categories) ICONS("icons", String.class, false, false), + METADATA_KEYS("metadataKeys", String.class, false, false), USE_SUBSTITUTION_FOR_NESTED_SERVICES("useServiceSubstitutionForNestedServices", Boolean.class, false, false), DATA_TYPES("data_types", Map.class, false, false), diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java index 436f958893..34382df716 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java @@ -48,6 +48,10 @@ public enum JsonPresentationFields { DERIVED_FROM("derivedFrom", null), VENDOR_NAME("vendorName", null), VENDOR_RELEASE("vendorRelease", null), + CATEGORY("category", null), + SUB_CATEGORY("subcategory", null), + RESOURCE_VENDOR("resourceVendor", null), + RESOURCE_VENDOR_RELEASE("resourceVendorRelease", null), RESOURCE_VENDOR_MODEL_NUMBER("reourceVendorModelNumber", null), SERVICE_TYPE("serviceType", null), SERVICE_ROLE("serviceRole", null), diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/MetadataKeyEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/MetadataKeyEnum.java new file mode 100644 index 0000000000..0ed8eab720 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/MetadataKeyEnum.java @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.be.datatypes.enums; + +import lombok.Getter; + +public enum MetadataKeyEnum { + METADATA_KEYS("metadataKeys"), + NAME("name"), + MANDATORY("mandatory"), + VALID_VALUES("validValues"); + + @Getter + private final String name; + + MetadataKeyEnum(final String name) { + this.name = name; + } + +}