diff options
author | MichaelMorris <michael.morris@est.tech> | 2022-07-25 23:01:50 +0100 |
---|---|---|
committer | Andr� Schmid <andre.schmid@est.tech> | 2022-08-11 10:32:47 +0000 |
commit | 0f6ae59460165381a8b5da2eea58c2c2efa75f2f (patch) | |
tree | 41774a70177ac52405599f80bd47373103ee1e0b | |
parent | a39a0026eebabe4866c81bcd12143ca40aa30e31 (diff) |
Support unknown data types in service import
Signed-off-by: MichaelMorris <michael.morris@est.tech>
Issue-ID: SDC-4119
Change-Id: I426ebb96e7b354dfd5dfb06a10845c3162055968
18 files changed, 770 insertions, 198 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogic.java index 1d37efef28..aa5706c77f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarBusinessLogic.java @@ -106,7 +106,7 @@ public class CsarBusinessLogic extends BaseBusinessLogic { } } - public CsarInfo getCsarInfo(Resource resource, Resource oldResource, User user, Map<String, byte[]> payload, String csarUUID) { + public OnboardedCsarInfo getCsarInfo(Resource resource, Resource oldResource, User user, Map<String, byte[]> payload, String csarUUID) { Map<String, byte[]> csar = payload; if (csar == null) { final var vendorSoftwareProduct = getCsar(resource, user); @@ -125,7 +125,7 @@ public class CsarBusinessLogic extends BaseBusinessLogic { csarUUID, oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum(), checksum); oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(checksum); } - return new CsarInfo(user, csarUUID, resource.getCsarVersionId(), csar, resource.getName(), toscaYamlCsarStatus.getKey(), + return new OnboardedCsarInfo(user, csarUUID, resource.getCsarVersionId(), csar, resource.getName(), toscaYamlCsarStatus.getKey(), toscaYamlCsarStatus.getValue(), true); } @@ -144,7 +144,7 @@ public class CsarBusinessLogic extends BaseBusinessLogic { } } - public CsarInfo getCsarInfo(Service service, Service oldResource, User user, Map<String, byte[]> payload, String csarUUID) { + public ServiceCsarInfo getCsarInfo(Service service, Service oldResource, User user, Map<String, byte[]> payload, String csarUUID) { Map<String, byte[]> csar = getCsar(service, user, payload, csarUUID); ImmutablePair<String, String> toscaYamlCsarStatus = validateAndParseCsar(service, user, csar, csarUUID).left() .on(this::throwComponentException); @@ -157,7 +157,7 @@ public class CsarBusinessLogic extends BaseBusinessLogic { csarUUID, oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum(), checksum); oldResource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(checksum); } - return new CsarInfo(user, csarUUID, csar, service.getName(), toscaYamlCsarStatus.getKey(), toscaYamlCsarStatus.getValue(), true); + return new ServiceCsarInfo(user, csarUUID, csar, service.getName(), toscaYamlCsarStatus.getKey(), toscaYamlCsarStatus.getValue(), true); } public ParsedToscaYamlInfo getParsedToscaYamlInfo(String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java index dc6f7c4416..49b7bb2f86 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java @@ -21,8 +21,6 @@ */ package org.openecomp.sdc.be.components.csar; -import static org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; -import static org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; import com.google.common.annotations.VisibleForTesting; @@ -37,11 +35,11 @@ import java.util.Optional; import java.util.PriorityQueue; import java.util.Queue; import java.util.Set; -import java.util.regex.Pattern; import lombok.Getter; import lombok.Setter; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.config.NonManoArtifactType; import org.openecomp.sdc.be.config.NonManoConfiguration; @@ -51,13 +49,15 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.NodeTypeInfo; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.tosca.CsarUtils; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; import org.yaml.snakeyaml.Yaml; -public class CsarInfo { +/** + * Provides access to the contents of a CSAR + */ +public abstract class CsarInfo { private static final Logger log = Logger.getLogger(CsarInfo.class); private final NonManoConfiguration nonManoConfiguration; @@ -74,22 +74,21 @@ public class CsarInfo { private String csarVersionId; @Getter @Setter - private Map<String, byte[]> csar; + protected Map<String, byte[]> csar; @Getter private String mainTemplateName; @Getter private String mainTemplateContent; @Getter - private Map<String, Object> mappedToscaMainTemplate; + protected Map<String, Object> mappedToscaMainTemplate; @Getter private Map<String, String> createdNodesToscaResourceNames; private Queue<String> cvfcToCreateQueue; private boolean isUpdate; @Getter private Map<String, Resource> createdNodes; - private Map<String, Object> datatypeDefinitions; + protected Map<String, Object> datatypeDefinitions; private Map<String, Object> policytypeDefinitions; - private List<Map.Entry<String, byte[]>> globalSubstitutes; public CsarInfo(User modifier, String csarUUID, Map<String, byte[]> csar, String vfResourceName, String mainTemplateName, @@ -106,18 +105,11 @@ public class CsarInfo { this.isUpdate = isUpdate; this.createdNodes = new HashMap<>(); this.nonManoConfiguration = NonManoConfigurationManager.getInstance().getNonManoConfiguration(); - this.globalSubstitutes = getGlobalSubstitutes(csar); } - private List<Map.Entry<String, byte[]>> getGlobalSubstitutes(final Map<String, byte[]> csar){ - final List<Map.Entry<String, byte[]>> globalSubstitutesInCsar = new ArrayList<>(); - for (Map.Entry<String, byte[]> entry : csar.entrySet()) { - if (isAServiceTemplate(entry.getKey()) && isGlobalSubstitute(entry.getKey())) { - globalSubstitutesInCsar.add(entry); - } - } - return globalSubstitutesInCsar; - } + public String getVfResourceName() { + return vfResourceName; + } public CsarInfo(final User modifier, final String csarUUID, final String csarVersionId, final Map<String, byte[]> csarContent, final String vfResourceName, final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { @@ -174,34 +166,15 @@ public class CsarInfo { public void setUpdate(boolean isUpdate) { this.isUpdate = isUpdate; } - - public Map<String, NodeTypeInfo> extractTypesInfo() { - Map<String, NodeTypeInfo> nodeTypesInfo = new HashMap<>(); - final Set<String> nodeTypesUsedInNodeTemplates = new HashSet<>(); - for (Map.Entry<String, byte[]> entry : getCsar().entrySet()) { - extractNodeTypeInfo(nodeTypesInfo, nodeTypesUsedInNodeTemplates, entry); - } - if (CollectionUtils.isNotEmpty(globalSubstitutes)) { - setDerivedFrom(nodeTypesInfo); - addGlobalSubstitutionsToNodeTypes(nodeTypesUsedInNodeTemplates, nodeTypesInfo); - } - - markNestedVfc(getMappedToscaMainTemplate(), nodeTypesInfo); - return nodeTypesInfo; - } - public Map<String, Object> getDataTypes() { - if (datatypeDefinitions == null) { - datatypeDefinitions = new HashMap<>(); - for (Map.Entry<String, byte[]> entry : globalSubstitutes) { - final String yamlFileContents = new String(entry.getValue()); - final Map<String, Object> mappedToscaTemplate = new Yaml().load(yamlFileContents); - datatypeDefinitions.putAll(getTypesFromTemplate(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); - } - datatypeDefinitions.putAll(getTypesFromTemplate(mappedToscaMainTemplate, TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); - } - return datatypeDefinitions; - } + public abstract Map<String, NodeTypeInfo> extractTypesInfo(); + + /** + * Get the data types defined in the CSAR + * + * @return map with the data type name as key and representaion of the data type defintion as value + */ + public abstract Map<String, Object> getDataTypes(); public Map<String, Object> getPolicyTypes() { if (policytypeDefinitions == null) { @@ -211,8 +184,8 @@ public class CsarInfo { return policytypeDefinitions; } - @SuppressWarnings("unchecked") - private Map<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type) { + @SuppressWarnings("unchecked") + protected Map<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type) { final Either<Object, ResultStatusEnum> dataTypesEither = findToscaElement(mappedToscaTemplate, type, ToscaElementTypeEnum.MAP); if (dataTypesEither != null && dataTypesEither.isLeft()) { @@ -221,27 +194,7 @@ public class CsarInfo { return Collections.emptyMap(); } - @SuppressWarnings("unchecked") - private void extractNodeTypeInfo(Map<String, NodeTypeInfo> nodeTypesInfo, - final Set<String> nodeTypesUsedInNodeTemplates, Map.Entry<String, byte[]> entry) { - if (isAServiceTemplate(entry.getKey()) && !isGlobalSubstitute(entry.getKey())) { - Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(new String(entry.getValue())); - findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS, ToscaElementTypeEnum.MAP).right() - .on(sub -> handleSubstitutionMappings(nodeTypesInfo, entry, mappedToscaTemplate, (Map<String, Object>) sub)); - final Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, - TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP); - if (nodeTypesEither.isLeft()) { - final Map<String, Map<String, Object>> nodeTemplates = (Map<String, Map<String, Object>>) nodeTypesEither.left().value(); - nodeTypesUsedInNodeTemplates.addAll(findNodeTypesUsedInNodeTemplates(nodeTemplates)); - } - } - } - - private boolean isAServiceTemplate(final String filePath) { - return Pattern.compile(CsarUtils.SERVICE_TEMPLATE_PATH_PATTERN).matcher(filePath).matches(); - } - - private Set<String> findNodeTypesUsedInNodeTemplates(final Map<String, Map<String, Object>> nodeTemplates) { + protected Set<String> findNodeTypesUsedInNodeTemplates(final Map<String, Map<String, Object>> nodeTemplates) { final Set<String> nodeTypes = new HashSet<>(); for (final Map<String, Object> nodeTemplate : nodeTemplates.values()) { nodeTypes.add((String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())); @@ -249,84 +202,8 @@ public class CsarInfo { return nodeTypes; } - private ResultStatusEnum handleSubstitutionMappings(Map<String, NodeTypeInfo> nodeTypesInfo, Map.Entry<String, byte[]> entry, - Map<String, Object> mappedToscaTemplate, Map<String, Object> substitutionMappings) { - final Set<String> nodeTypesDefinedInTemplate = findNodeTypesDefinedInTemplate(mappedToscaTemplate); - if (substitutionMappings.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName()) && !nodeTypesDefinedInTemplate - .contains(substitutionMappings.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName()))) { - NodeTypeInfo nodeTypeInfo = new NodeTypeInfo(); - nodeTypeInfo.setSubstitutionMapping(true); - nodeTypeInfo.setType((String) substitutionMappings.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName())); - nodeTypeInfo.setTemplateFileName(entry.getKey()); - nodeTypeInfo.setMappedToscaTemplate(mappedToscaTemplate); - nodeTypesInfo.put(nodeTypeInfo.getType(), nodeTypeInfo); - } - return ResultStatusEnum.OK; - } - - @SuppressWarnings("unchecked") - private Set<String> findNodeTypesDefinedInTemplate(final Map<String, Object> mappedToscaTemplate) { - final Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, - ToscaElementTypeEnum.MAP); - if (nodeTypesEither.isLeft()) { - final Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); - return nodeTypes.keySet(); - } - return Collections.emptySet(); - } - - private boolean isGlobalSubstitute(String fileName) { - return fileName.equalsIgnoreCase(Constants.GLOBAL_SUBSTITUTION_TYPES_SERVICE_TEMPLATE) || fileName - .equalsIgnoreCase(Constants.ABSTRACT_SUBSTITUTE_GLOBAL_TYPES_SERVICE_TEMPLATE); - } - - @SuppressWarnings("unchecked") - private void setDerivedFrom(Map<String, NodeTypeInfo> nodeTypesInfo) { - for (Map.Entry<String, byte[]> entry : globalSubstitutes) { - String yamlFileContents = new String(entry.getValue()); - Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(yamlFileContents); - Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, - ToscaElementTypeEnum.MAP); - if (nodeTypesEither.isLeft()) { - Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); - for (Map.Entry<String, Object> nodeType : nodeTypes.entrySet()) { - processNodeType(nodeTypesInfo, nodeType); - } - } - } - } - - @SuppressWarnings("unchecked") - private void processNodeType(Map<String, NodeTypeInfo> nodeTypesInfo, Map.Entry<String, Object> nodeType) { - Map<String, Object> nodeTypeMap = (Map<String, Object>) nodeType.getValue(); - if (nodeTypeMap.containsKey(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()) && nodeTypesInfo.containsKey(nodeType.getKey())) { - NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(nodeType.getKey()); - List<String> derivedFrom = new ArrayList<>(); - derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName())); - nodeTypeInfo.setDerivedFrom(derivedFrom); - } - } - - @SuppressWarnings("unchecked") - private void addGlobalSubstitutionsToNodeTypes(final Set<String> nodeTypesUsedInNodeTemplates, final Map<String, NodeTypeInfo> nodeTypesInfo) { - for (Map.Entry<String, byte[]> entry : globalSubstitutes) { - final String yamlFileContents = new String(entry.getValue()); - final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(yamlFileContents); - final Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, - ToscaElementTypeEnum.MAP); - if (nodeTypesEither.isLeft()) { - final Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); - for (final Map.Entry<String, Object> nodeType : nodeTypes.entrySet()) { - if (!nodeTypesInfo.containsKey(nodeType.getKey()) && nodeTypesUsedInNodeTemplates.contains(nodeType.getKey())) { - nodeTypesInfo.put(nodeType.getKey(), buildNodeTypeInfo(nodeType, entry.getKey(), mappedToscaTemplate)); - } - } - } - } - } - @SuppressWarnings("unchecked") - private NodeTypeInfo buildNodeTypeInfo(final Map.Entry<String, Object> nodeType, final String templateFileName, + protected NodeTypeInfo buildNodeTypeInfo(final Map.Entry<String, Object> nodeType, final String templateFileName, final Map<String, Object> mappedToscaTemplate) { final NodeTypeInfo nodeTypeInfo = new NodeTypeInfo(); nodeTypeInfo.setSubstitutionMapping(false); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/OnboardedCsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/OnboardedCsarInfo.java new file mode 100644 index 0000000000..85f64699d4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/OnboardedCsarInfo.java @@ -0,0 +1,205 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.components.csar; + +import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; +import org.apache.commons.collections.CollectionUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; +import org.openecomp.sdc.be.config.NonManoConfiguration; +import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.tosca.CsarUtils; +import org.openecomp.sdc.be.utils.TypeUtils; +import org.openecomp.sdc.common.api.Constants; +import org.yaml.snakeyaml.Yaml; +import fj.data.Either; + +/** + * Provides access to the contents of a CSAR which has been created through the SDC onboarding + * process + */ +public class OnboardedCsarInfo extends CsarInfo { + + private List<Map.Entry<String, byte[]>> globalSubstitutes; + + OnboardedCsarInfo(NonManoConfiguration nonManoConfiguration) { + super(nonManoConfiguration); + } + + public OnboardedCsarInfo(final User modifier, final String csarUUID, final Map<String, byte[]> csar, final String vfResourceName, + final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { + super(modifier, csarUUID, csar, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate); + this.globalSubstitutes = getGlobalSubstitutes(csar); + } + + public OnboardedCsarInfo(final User modifier, final String csarUUID, final String csarVersionId, final Map<String, byte[]> csarContent, + final String vfResourceName, final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { + super(modifier, csarUUID, csarVersionId, csarContent, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate); + this.globalSubstitutes = getGlobalSubstitutes(csar); + } + + private List<Map.Entry<String, byte[]>> getGlobalSubstitutes(final Map<String, byte[]> csar) { + final List<Map.Entry<String, byte[]>> globalSubstitutesInCsar = new ArrayList<>(); + for (Map.Entry<String, byte[]> entry : csar.entrySet()) { + if (isAServiceTemplate(entry.getKey()) && isGlobalSubstitute(entry.getKey())) { + globalSubstitutesInCsar.add(entry); + } + } + return globalSubstitutesInCsar; + } + + public Map<String, NodeTypeInfo> extractTypesInfo() { + final Map<String, NodeTypeInfo> nodeTypesInfo = new HashMap<>(); + final Set<String> nodeTypesUsedInNodeTemplates = new HashSet<>(); + for (Map.Entry<String, byte[]> entry : getCsar().entrySet()) { + extractNodeTypeInfo(nodeTypesInfo, nodeTypesUsedInNodeTemplates, entry); + } + if (CollectionUtils.isNotEmpty(globalSubstitutes)) { + setDerivedFrom(nodeTypesInfo); + addGlobalSubstitutionsToNodeTypes(nodeTypesUsedInNodeTemplates, nodeTypesInfo); + } + + markNestedVfc(getMappedToscaMainTemplate(), nodeTypesInfo); + return nodeTypesInfo; + } + + @SuppressWarnings("unchecked") + private void extractNodeTypeInfo(final Map<String, NodeTypeInfo> nodeTypesInfo, final Set<String> nodeTypesUsedInNodeTemplates, + final Map.Entry<String, byte[]> entry) { + if (isAServiceTemplate(entry.getKey()) && !isGlobalSubstitute(entry.getKey())) { + final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(new String(entry.getValue())); + findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS, ToscaElementTypeEnum.MAP).right() + .on(sub -> handleSubstitutionMappings(nodeTypesInfo, entry, mappedToscaTemplate, (Map<String, Object>) sub)); + final Either<Object, ResultStatusEnum> nodeTypesEither = + findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + final Map<String, Map<String, Object>> nodeTemplates = (Map<String, Map<String, Object>>) nodeTypesEither.left().value(); + nodeTypesUsedInNodeTemplates.addAll(findNodeTypesUsedInNodeTemplates(nodeTemplates)); + } + } + } + + private boolean isAServiceTemplate(final String filePath) { + return Pattern.compile(CsarUtils.SERVICE_TEMPLATE_PATH_PATTERN).matcher(filePath).matches(); + } + + private boolean isGlobalSubstitute(final String fileName) { + return fileName.equalsIgnoreCase(Constants.GLOBAL_SUBSTITUTION_TYPES_SERVICE_TEMPLATE) + || fileName.equalsIgnoreCase(Constants.ABSTRACT_SUBSTITUTE_GLOBAL_TYPES_SERVICE_TEMPLATE); + } + + + private ResultStatusEnum handleSubstitutionMappings(final Map<String, NodeTypeInfo> nodeTypesInfo, final Map.Entry<String, byte[]> entry, + final Map<String, Object> mappedToscaTemplate, final Map<String, Object> substitutionMappings) { + final Set<String> nodeTypesDefinedInTemplate = findNodeTypesDefinedInTemplate(mappedToscaTemplate); + if (substitutionMappings.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName()) + && !nodeTypesDefinedInTemplate.contains(substitutionMappings.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName()))) { + NodeTypeInfo nodeTypeInfo = new NodeTypeInfo(); + nodeTypeInfo.setSubstitutionMapping(true); + nodeTypeInfo.setType((String) substitutionMappings.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName())); + nodeTypeInfo.setTemplateFileName(entry.getKey()); + nodeTypeInfo.setMappedToscaTemplate(mappedToscaTemplate); + nodeTypesInfo.put(nodeTypeInfo.getType(), nodeTypeInfo); + } + return ResultStatusEnum.OK; + } + + @SuppressWarnings("unchecked") + private Set<String> findNodeTypesDefinedInTemplate(final Map<String, Object> mappedToscaTemplate) { + final Either<Object, ResultStatusEnum> nodeTypesEither = + findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + final Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); + return nodeTypes.keySet(); + } + return Collections.emptySet(); + } + + @SuppressWarnings("unchecked") + private void setDerivedFrom(final Map<String, NodeTypeInfo> nodeTypesInfo) { + for (Map.Entry<String, byte[]> entry : globalSubstitutes) { + final String yamlFileContents = new String(entry.getValue()); + final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(yamlFileContents); + Either<Object, ResultStatusEnum> nodeTypesEither = + findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); + for (Map.Entry<String, Object> nodeType : nodeTypes.entrySet()) { + processNodeType(nodeTypesInfo, nodeType); + } + } + } + } + + @SuppressWarnings("unchecked") + private void processNodeType(final Map<String, NodeTypeInfo> nodeTypesInfo, final Map.Entry<String, Object> nodeType) { + final Map<String, Object> nodeTypeMap = (Map<String, Object>) nodeType.getValue(); + if (nodeTypeMap.containsKey(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()) && nodeTypesInfo.containsKey(nodeType.getKey())) { + final NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(nodeType.getKey()); + final List<String> derivedFrom = new ArrayList<>(); + derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName())); + nodeTypeInfo.setDerivedFrom(derivedFrom); + } + } + + @SuppressWarnings("unchecked") + private void addGlobalSubstitutionsToNodeTypes(final Set<String> nodeTypesUsedInNodeTemplates, final Map<String, NodeTypeInfo> nodeTypesInfo) { + for (Map.Entry<String, byte[]> entry : globalSubstitutes) { + final String yamlFileContents = new String(entry.getValue()); + final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(yamlFileContents); + final Either<Object, ResultStatusEnum> nodeTypesEither = + findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + final Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value(); + for (final Map.Entry<String, Object> nodeType : nodeTypes.entrySet()) { + if (!nodeTypesInfo.containsKey(nodeType.getKey()) && nodeTypesUsedInNodeTemplates.contains(nodeType.getKey())) { + nodeTypesInfo.put(nodeType.getKey(), buildNodeTypeInfo(nodeType, entry.getKey(), mappedToscaTemplate)); + } + } + } + } + } + + @Override + public Map<String, Object> getDataTypes() { + if (datatypeDefinitions == null) { + datatypeDefinitions = new HashMap<>(); + for (Map.Entry<String, byte[]> entry : globalSubstitutes) { + final String yamlFileContents = new String(entry.getValue()); + final Map<String, Object> mappedToscaTemplate = new Yaml().load(yamlFileContents); + datatypeDefinitions.putAll(getTypesFromTemplate(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); + } + datatypeDefinitions.putAll(getTypesFromTemplate(mappedToscaMainTemplate, TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); + } + return datatypeDefinitions; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java new file mode 100644 index 0000000000..ca3c92bcbd --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java @@ -0,0 +1,145 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.components.csar; + +import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; +import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.utils.TypeUtils; +import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.yaml.snakeyaml.Yaml; +import fj.data.Either; + +/** + * Provides access to the contents of a Service CSAR + */ +public class ServiceCsarInfo extends CsarInfo { + + private Map<String, Map<String, Object>> mainTemplateImports; + private static final Logger log = Logger.getLogger(ServiceCsarInfo.class); + + public ServiceCsarInfo(final User modifier, final String csarUUID, final Map<String, byte[]> csar, final String vfResourceName, + final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { + super(modifier, csarUUID, csar, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate); + + final Path mainTemplateDir = Paths.get(getMainTemplateName().substring(0, getMainTemplateName().lastIndexOf('/') + 1)); + final Collection<Path> filesHandled = new HashSet<>(); + filesHandled.add(Paths.get(mainTemplateName)); + this.mainTemplateImports = getTemplateImports(csar, new Yaml().load(mainTemplateContent), mainTemplateDir, filesHandled); + } + + private Map<String, Map<String, Object>> getTemplateImports(final Map<String, byte[]> csar, Map<String, Object> mappedToscaMainTemplate, + final Path fileParentDir, final Collection<Path> filesHandled) { + final Map<String, Map<String, Object>> templateImports = new HashMap<>(); + + final List<Path> importFilePaths = getTempateImportFilePaths(mappedToscaMainTemplate, fileParentDir); + + importFilePaths.stream().filter(path -> !filesHandled.contains(path)).forEach( + importFilePath -> { + byte[] importFile = csar.get(importFilePath.toString()); + if (importFile != null) { + filesHandled.add(importFilePath); + Map<String, Object> mappedImportFile = new Yaml().load(new String(csar.get(importFilePath.toString()))); + templateImports.put(importFilePath.toString(), mappedImportFile); + + templateImports.putAll(getTemplateImports(csar, mappedImportFile, importFilePath.getParent(), filesHandled)); + + } else { + log.info("Import {} cannot be found in CSAR", importFilePath.toString()); + } + }); + + return templateImports; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private List<Path> getTempateImportFilePaths(final Map<String, Object> mappedToscaTemplate, final Path fileParentDir) { + final Either<Object, ResultStatusEnum> importsEither = + findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.IMPORTS, ToscaElementTypeEnum.ALL); + + if (importsEither.isLeft()) { + final List importsList = (List) importsEither.left().value(); + if (CollectionUtils.isNotEmpty(importsList)) { + if (importsList.get(0) instanceof String) { + List<Path> importPaths = new ArrayList<>(); + importsList.stream().forEach(importPath -> importPaths.add(Paths.get((String)importPath))); + return importPaths; + } else if (importsList.get(0) instanceof Map) { + return getTemplateImportFilePathsMultiLineGrammar(importsList, fileParentDir); + } + } + + } + return Collections.emptyList(); + } + + @SuppressWarnings("unchecked") + private List<Path> getTemplateImportFilePathsMultiLineGrammar(final List<Map<String, Object>> importsList, final Path fileParentDir) { + final List<Path> importFiles = new ArrayList<>(); + + for (Map<String, Object> importFileMultiLineGrammar : (List<Map<String, Object>>) importsList) { + if (MapUtils.isNotEmpty(importFileMultiLineGrammar)) { + if (importFileMultiLineGrammar.values().iterator().next() instanceof String) { + Path relativePath = Paths.get((String) importFileMultiLineGrammar.get("file")); + Path absolutePath = fileParentDir.resolve(relativePath).normalize(); + importFiles.add(absolutePath); + } else if (importFileMultiLineGrammar.values().iterator().next() instanceof Map) { + importFileMultiLineGrammar.values().forEach(value -> { + Path relativePath = Paths.get((String) ((Map<String, Object>) value).get("file")); + Path absolutePath = fileParentDir == null ? relativePath : fileParentDir.resolve(relativePath).normalize(); + importFiles.add(absolutePath); + }); + } + } + } + return importFiles; + } + + @Override + public Map<String, NodeTypeInfo> extractTypesInfo() { + return Collections.emptyMap(); + } + + @Override + public Map<String, Object> getDataTypes() { + final Map<String, Object> definitions = new HashMap<>(); + mainTemplateImports.entrySet().stream() + .forEach(entry -> definitions.putAll(getTypesFromTemplate(entry.getValue(), TypeUtils.ToscaTagNamesEnum.DATA_TYPES))); + definitions.putAll(getTypesFromTemplate(getMappedToscaMainTemplate(), TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); + return definitions; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java index cad0f28477..60fdc0b3d5 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java @@ -17,10 +17,13 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.components.impl; import fj.data.Either; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -72,17 +75,66 @@ public class DataTypeImportManager { } private Either<List<DataTypeDefinition>, ActionStatus> createDataTypesFromYml(final String dataTypesYml, final String modelName) { - final Either<List<DataTypeDefinition>, ActionStatus> dataTypes = commonImportManager.createElementTypesFromYml(dataTypesYml, + final Either<List<DataTypeDefinition>, ActionStatus> dataTypesEither = commonImportManager.createElementTypesFromYml(dataTypesYml, this::createDataType); - if (dataTypes.isLeft() && StringUtils.isNotEmpty(modelName)) { + if (dataTypesEither.isRight()) { + return dataTypesEither; + } + final List<DataTypeDefinition> dataTypes = dataTypesEither.left().value(); + if (StringUtils.isNotEmpty(modelName)) { final Optional<Model> modelOptional = modelOperation.findModelByName(modelName); if (modelOptional.isPresent()) { - dataTypes.left().value().forEach(dataType -> dataType.setModel(modelName)); - return dataTypes; + dataTypes.forEach(dataType -> dataType.setModel(modelName)); + } else { + return Either.right(ActionStatus.INVALID_MODEL); + } + } + if (log.isTraceEnabled()) { + log.trace("Unsorted datatypes order:"); + dataTypes.stream().forEach(dt -> log.trace(dt.getName())); + } + + long startTime = System.currentTimeMillis(); + List<DataTypeDefinition> sortedDataTypeDefinitions = sortDataTypesByDependencyOrder(dataTypes); + + if (log.isTraceEnabled()) { + long sortTime = System.currentTimeMillis() - startTime; + log.trace("Sorting " + sortedDataTypeDefinitions.size() + " data types from model: " + modelName + " took: " + sortTime); + log.trace("Sorted datatypes order:"); + sortedDataTypeDefinitions.stream().forEach(dt -> log.trace(dt.getName())); + } + return Either.left(sortedDataTypeDefinitions); + } + + private List<DataTypeDefinition> sortDataTypesByDependencyOrder(final List<DataTypeDefinition> dataTypes) { + final List<DataTypeDefinition> sortedDataTypeDefinitions = new ArrayList<>(); + final Map<String, DataTypeDefinition> dataTypeDefinitionsMap = new HashMap<>(); + + dataTypes.forEach(dataType -> { + + int highestDependencyIndex = -1; + for (final String dependencyName : getDependencyTypes(dataType)) { + final DataTypeDefinition dependency = dataTypeDefinitionsMap.get(dependencyName); + final int indexOfDependency = sortedDataTypeDefinitions.lastIndexOf(dependency); + highestDependencyIndex = indexOfDependency > highestDependencyIndex ? indexOfDependency : highestDependencyIndex; } - return Either.right(ActionStatus.INVALID_MODEL); + sortedDataTypeDefinitions.add(highestDependencyIndex + 1, dataType); + dataTypeDefinitionsMap.put(dataType.getName(), dataType); + + } ); + + return sortedDataTypeDefinitions; + } + + private Collection<String> getDependencyTypes(final DataTypeDefinition dataType) { + final Set<String> dependencies = new HashSet<>(); + if (dataType.getDerivedFromName() != null) { + dependencies.add(dataType.getDerivedFromName()); + } + if (dataType.getProperties() != null) { + dataType.getProperties().stream().forEach(property -> dependencies.add(property.getType())); } - return dataTypes; + return dependencies; } private Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat> createDataTypesByDao( diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 1f107e4ec1..b923cbc3a1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -58,6 +58,7 @@ import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; @@ -1041,7 +1042,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { loggerSupportability .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, StatusCode.STARTED, "Starting to create Resource From Csar by user {}", user.getUserId()); - CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID); + OnboardedCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(resource, null, user, csarUIPayload, csarUUID); + Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo(); final String model = resource.getModel(); if (StringUtils.isNotEmpty(model)) { @@ -1057,7 +1059,6 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { policyTypeBusinessLogic.createPolicyTypeFromYaml(new Yaml().dump(policyTypesToCreate), model, true); } } - Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = findNodeTypesArtifactsToHandle( nodeTypesInfo, csarInfo, resource); if (findNodeTypesArtifactsToHandleRes.isRight()) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index 7e15a52b90..e4129a24eb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -48,6 +48,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.ServiceCsarInfo; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; @@ -62,6 +63,7 @@ import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils; import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; @@ -118,6 +120,8 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.StorageException; import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.tosca.CsarUtils; import org.openecomp.sdc.be.ui.model.OperationUi; @@ -130,6 +134,7 @@ import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.beans.factory.annotation.Autowired; import org.yaml.snakeyaml.Yaml; @Getter @@ -167,6 +172,9 @@ public class ServiceImportBusinessLogic { private final ArtifactsBusinessLogic artifactsBusinessLogic; private final IGraphLockOperation graphLockOperation; private final ToscaFunctionService toscaFunctionService; + private final PropertyOperation propertyOperation; + private final DataTypeBusinessLogic dataTypeBusinessLogic; + private ApplicationDataTypeCache applicationDataTypeCache; public ServiceImportBusinessLogic(final GroupBusinessLogic groupBusinessLogic, final ArtifactsBusinessLogic artifactsBusinessLogic, @@ -180,7 +188,8 @@ public class ServiceImportBusinessLogic { final ServiceImportParseLogic serviceImportParseLogic, final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic, final PolicyBusinessLogic policyBusinessLogic, final JanusGraphDao janusGraphDao, - final IGraphLockOperation graphLockOperation, final ToscaFunctionService toscaFunctionService) { + final IGraphLockOperation graphLockOperation, final ToscaFunctionService toscaFunctionService, + final PropertyOperation propertyOperation, final DataTypeBusinessLogic dataTypeBusinessLogic) { this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; this.uiComponentDataConverter = uiComponentDataConverter; this.componentsUtils = componentsUtils; @@ -199,6 +208,13 @@ public class ServiceImportBusinessLogic { this.artifactsBusinessLogic = artifactsBusinessLogic; this.graphLockOperation = graphLockOperation; this.toscaFunctionService = toscaFunctionService; + this.propertyOperation = propertyOperation; + this.dataTypeBusinessLogic = dataTypeBusinessLogic; + } + + @Autowired + public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) { + this.applicationDataTypeCache = applicationDataTypeCache; } public Service createService(Service service, AuditingActionEnum auditingAction, User user, Map<String, byte[]> csarUIPayload, @@ -232,7 +248,13 @@ public class ServiceImportBusinessLogic { protected Service createServiceFromCsar(Service service, User user, Map<String, byte[]> csarUIPayload, String csarUUID) { log.trace("************* created successfully from YAML, resource TOSCA "); try { - CsarInfo csarInfo = csarBusinessLogic.getCsarInfo(service, null, user, csarUIPayload, csarUUID); + ServiceCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(service, null, user, csarUIPayload, csarUUID); + + final Map<String, Object> dataTypesToCreate = getDatatypesToCreate(service.getModel(), csarInfo); + if (MapUtils.isNotEmpty(dataTypesToCreate)) { + dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), service.getModel(), true); + } + Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo(); Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = serviceImportParseLogic .findNodeTypesArtifactsToHandle(nodeTypesInfo, csarInfo, service); @@ -250,6 +272,19 @@ public class ServiceImportBusinessLogic { throw new ComponentException(ActionStatus.GENERAL_ERROR); } } + + private Map<String, Object> getDatatypesToCreate(final String model, final CsarInfo csarInfo) { + final Map<String, Object> dataTypesToCreate = new HashMap<>(); + + for (final Entry<String, Object> dataTypeEntry : csarInfo.getDataTypes().entrySet()){ + final Either<DataTypeDefinition, JanusGraphOperationStatus> result = applicationDataTypeCache.get(model, UniqueIdBuilder.buildDataTypeUid(model, dataTypeEntry.getKey())); + if (result.isRight() && result.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) { + dataTypesToCreate.put(dataTypeEntry.getKey(), dataTypeEntry.getValue()); + log.info("Deploying unknown type " + dataTypeEntry.getKey() + " to model " + model + " from package " + csarInfo.getCsarUUID()); + } + } + return dataTypesToCreate; + } protected Service createServiceFromYaml(Service service, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo, @@ -2545,7 +2580,7 @@ public class ServiceImportBusinessLogic { mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value()); Map<String, Object> nodeTypes = serviceImportParseLogic.getNodeTypesFromTemplate(mappedToscaTemplate); createNodeTypes(yamlName, service, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, - mapToConvert, nodeTypes); + mapToConvert, nodeTypes); return csarInfo.getCreatedNodes(); } catch (Exception e) { log.debug("Exception occured when createResourcesFromYamlNodeTypesList,error is:{}", e.getMessage(), e); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/OnboardedCsarInfoTest.java index 07a8ded378..abdf153155 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/OnboardedCsarInfoTest.java @@ -58,9 +58,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) -public class CsarInfoTest { +public class OnboardedCsarInfoTest { - private CsarInfo csarInfo; + private OnboardedCsarInfo csarInfo; @Mock private User user; @@ -81,12 +81,12 @@ public class CsarInfoTest { new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); } - private CsarInfo createCsarInfo(final String csarFileName, final String mainTemplateName) throws URISyntaxException, ZipException { - final File csarFile = new File(CsarInfoTest.class.getClassLoader().getResource(csarFileName).toURI()); + private OnboardedCsarInfo createCsarInfo(final String csarFileName, final String mainTemplateName) throws URISyntaxException, ZipException { + final File csarFile = new File(OnboardedCsarInfoTest.class.getClassLoader().getResource(csarFileName).toURI()); final Map<String, byte[]> payload = ZipUtils.readZip(csarFile, false); String mainTemplateContent = new String(payload.get(mainTemplateName)); - return new CsarInfo(user, CSAR_UUID, payload, RESOURCE_NAME, + return new OnboardedCsarInfo(user, CSAR_UUID, payload, RESOURCE_NAME, mainTemplateName, mainTemplateContent, true); } @@ -149,7 +149,7 @@ public class CsarInfoTest { @Test public void getSoftwareInformationPathTest() { final NonManoConfiguration nonManoConfigurationMock = Mockito.mock(NonManoConfiguration.class); - final CsarInfo csarInfo = new CsarInfo(nonManoConfigurationMock); + final CsarInfo csarInfo = new OnboardedCsarInfo(nonManoConfigurationMock); final NonManoFolderType testNonManoFolderType = new NonManoFolderType(); testNonManoFolderType.setLocation("sw-location-test"); testNonManoFolderType.setType("informational-test"); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfoTest.java new file mode 100644 index 0000000000..80ecc212f1 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfoTest.java @@ -0,0 +1,81 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.components.csar; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.io.File; +import java.net.URISyntaxException; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; + +@ExtendWith(MockitoExtension.class) +class ServiceCsarInfoTest { + + private ServiceCsarInfo csarInfo; + + @Mock + private User user; + + private static final String CSAR_UUID = "csarUUID"; + private static final String PAYLOAD_NAME = "csars/serviceWithUnknownDataTypes.csar"; + private static final String SERVICE_NAME = "serviceWithDataType"; + private static final String MAIN_TEMPLATE_NAME = "Definitions/service-Servicewithdatatype-template.yml"; + + @BeforeEach + void setup() throws ZipException, URISyntaxException { + csarInfo = createCsarInfo(PAYLOAD_NAME, MAIN_TEMPLATE_NAME); + + new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); + } + + private ServiceCsarInfo createCsarInfo(final String csarFileName, final String mainTemplateName) throws URISyntaxException, ZipException { + final File csarFile = new File(ServiceCsarInfoTest.class.getClassLoader().getResource(csarFileName).toURI()); + final Map<String, byte[]> payload = ZipUtils.readZip(csarFile, false); + String mainTemplateContent = new String(payload.get(mainTemplateName)); + +return new ServiceCsarInfo(user, CSAR_UUID, payload, SERVICE_NAME, mainTemplateName, mainTemplateContent, true); + } + + @SuppressWarnings("unchecked") + @Test + void testGetDataTypes() { + final Map<String, Object> dataTypes = csarInfo.getDataTypes(); + assertEquals(184, dataTypes.size()); + final Map<String, Object> dataTypeDefinition = (Map<String, Object>) dataTypes.get("tosca.datatypes.test_g"); + assertNotNull(dataTypeDefinition); + assertEquals("tosca.datatypes.Root", dataTypeDefinition.get("derived_from")); + assertEquals("tosca.datatypes.test_h", + ((Map<String, Object>) ((Map<String, Object>) dataTypeDefinition.get("properties")).get("prop2")).get("type")); + } + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java index d9525b1590..967beb2235 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java @@ -148,7 +148,7 @@ public class YamlTemplateParsingHandlerTest { when(groupTypeBusinessLogic.getLatestGroupTypeByType(eq(HEAT_GROUP_TYPE), any())).thenReturn(heatGroupType); String main_template_content = new String(csar.get(MAIN_TEMPLATE_NAME)); - CsarInfo csarInfo = new CsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, + CsarInfo csarInfo = new OnboardedCsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, MAIN_TEMPLATE_NAME, main_template_content, true); Resource resource = new Resource(); @@ -163,7 +163,7 @@ public class YamlTemplateParsingHandlerTest { void parseServicePropertiesInfoFromYamlTest() { when(groupTypeBusinessLogic.getLatestGroupTypeByType(eq(HEAT_GROUP_TYPE), any())).thenReturn(heatGroupType); String main_template_content = new String(csar.get(MAIN_TEMPLATE_NAME)); - CsarInfo csarInfo = new CsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, + CsarInfo csarInfo = new OnboardedCsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, MAIN_TEMPLATE_NAME, main_template_content, true); Service service = new Service(); @@ -183,7 +183,7 @@ public class YamlTemplateParsingHandlerTest { void parseRelationshipTemplateInfoFromYamlTest() { when(groupTypeBusinessLogic.getLatestGroupTypeByType(eq(HEAT_GROUP_TYPE), any())).thenReturn(heatGroupType); String main_template_content = new String(csar.get(MAIN_TEMPLATE_NAME)); - CsarInfo csarInfo = new CsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, + CsarInfo csarInfo = new OnboardedCsarInfo(user, CSAR_UUID, csar, RESOURCE_NAME, MAIN_TEMPLATE_NAME, main_template_content, true); Service service = new Service(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypesImportManagerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypesImportManagerTest.java new file mode 100644 index 0000000000..e4e63fc3b7 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypesImportManagerTest.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; +import fj.data.Either; +import java.util.Collections; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ModelOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; + +public class DataTypesImportManagerTest { + + private static final ComponentsUtils componentsUtils = mock(ComponentsUtils.class); + private static final JanusGraphGenericDao janusGraphGenericDao = mock(JanusGraphGenericDao.class); + private static final PropertyOperation propertyOperation = mock(PropertyOperation.class); + private static final ModelOperation modelOperation = mock(ModelOperation.class); + @Spy + private CommonImportManager commonImportManager = new CommonImportManager(componentsUtils, propertyOperation, modelOperation); + + @InjectMocks + private DataTypeImportManager dataTypeImportManager = new DataTypeImportManager(); + + private AutoCloseable closeable; + + @BeforeEach + public void openMocks() { + closeable = MockitoAnnotations.openMocks(this); + } + + @AfterEach + public void releaseMocks() throws Exception { + closeable.close(); + } + + @Test + public void testCreateDataTypes() { + + DataTypeDefinition rootDataTypeDef = new DataTypeDefinition(); + rootDataTypeDef.setName("tosca.datatypes.Root"); + rootDataTypeDef.setProperties(Collections.emptyList()); + DataTypeDefinition testADataTypeDef = new DataTypeDefinition(); + testADataTypeDef.setName("tosca.datatypes.test_a"); + testADataTypeDef.setProperties(Collections.emptyList()); + DataTypeDefinition testCDataTypeDef = new DataTypeDefinition(); + testCDataTypeDef.setName("tosca.datatypes.test_c"); + testCDataTypeDef.setProperties(Collections.emptyList()); + when(propertyOperation.getDataTypeByName("tosca.datatypes.Root", null)).thenReturn(Either.left(rootDataTypeDef)); + when(propertyOperation.getDataTypeByName("tosca.datatypes.test_c", null)).thenReturn(Either.left(testCDataTypeDef)); + + when(propertyOperation.getJanusGraphGenericDao()).thenReturn(janusGraphGenericDao); + when(propertyOperation.getDataTypeByUidWithoutDerived("tosca.datatypes.Root.datatype", true)).thenReturn(Either.left(rootDataTypeDef)); + when(propertyOperation.getDataTypeByUidWithoutDerived("tosca.datatypes.test_a.datatype", true)) + .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(propertyOperation.getDataTypeByUidWithoutDerived("tosca.datatypes.test_b.datatype", true)) + .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(propertyOperation.getDataTypeByUidWithoutDerived("tosca.datatypes.test_c.datatype", true)) + .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(propertyOperation.addDataType(any())).thenReturn(Either.left(testADataTypeDef)); + + String dataTypeYml = + "tosca.datatypes.test_a:\n" + + " derived_from: tosca.datatypes.Root\n" + + " properties:\n" + + " prop2:\n" + + " type: tosca.datatypes.test_b\n" + + "tosca.datatypes.test_b:\n" + + " derived_from: tosca.datatypes.test_c\n" + + " properties:\n" + + " prop2:\n" + + " type: string\n" + + "tosca.datatypes.test_c:\n" + + " derived_from: tosca.datatypes.Root\n" + + " properties:\n" + + " prop1:\n" + + " type: string"; + dataTypeImportManager.createDataTypes(dataTypeYml, "", false); + + ArgumentCaptor<DataTypeDefinition> dataTypeDefinitionCaptor = ArgumentCaptor.forClass(DataTypeDefinition.class); + Mockito.verify(propertyOperation, times(3)).addDataType(dataTypeDefinitionCaptor.capture()); + + assertEquals("tosca.datatypes.test_c", dataTypeDefinitionCaptor.getAllValues().get(0).getName()); + assertEquals("tosca.datatypes.test_b", dataTypeDefinitionCaptor.getAllValues().get(1).getName()); + assertEquals("tosca.datatypes.test_a", dataTypeDefinitionCaptor.getAllValues().get(2).getName()); + } + + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index ff47d75509..cee47ec984 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -64,6 +64,7 @@ import org.openecomp.sdc.be.components.ArtifactsResolver; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo; import org.openecomp.sdc.be.components.csar.YamlTemplateParsingHandler; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; @@ -387,7 +388,7 @@ class ResourceBusinessLogicTest { nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, - new CsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", + new OnboardedCsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", ImportUtilsTest.loadFileNameToJsonString("normative-types-new-webServer.yml"), true), ""); }); } @@ -1876,7 +1877,7 @@ class ResourceBusinessLogicTest { Resource resourceToUpdate = createResourceObject(false); String nodeName = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + "." + "abc"; String jsonContent = ImportUtilsTest.loadFileNameToJsonString("normative-types-new-webServer.yml"); - CsarInfo csarInfo = new CsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", jsonContent, + CsarInfo csarInfo = new OnboardedCsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", jsonContent, true); String nestedResourceName = bl.buildNestedToscaResourceName(resourceToUpdate.getResourceType() .name(), csarInfo.getVfResourceName(), nodeName) @@ -1914,7 +1915,7 @@ class ResourceBusinessLogicTest { setCanWorkOnResource(resourceResponse); String nodeName = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + "." + "abc"; String jsonContent = ImportUtilsTest.loadFileNameToJsonString("normative-types-new-webServer.yml"); - CsarInfo csarInfo = new CsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", jsonContent, + CsarInfo csarInfo = new OnboardedCsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", jsonContent, true); String nestedResourceName = bl.buildNestedToscaResourceName(resourceToUpdate.getResourceType() .name(), csarInfo.getVfResourceName(), nodeName) diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java index 1f45f77f3f..d40bac1585 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java @@ -19,21 +19,28 @@ package org.openecomp.sdc.be.components.impl; import static org.assertj.core.api.Java6Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyList; import static org.mockito.Mockito.anyMap; -import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.contains; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.matches; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.isNull; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.openecomp.sdc.be.components.impl.ServiceImportBusinessLogic.CREATE_RESOURCE; import fj.data.Either; +import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.URISyntaxException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -43,6 +50,7 @@ import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.map.HashedMap; @@ -50,9 +58,11 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.ServiceCsarInfo; import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.impl.utils.CreateServiceFromYamlParameter; @@ -96,6 +106,7 @@ import org.openecomp.sdc.be.model.UploadPropInfo; import org.openecomp.sdc.be.model.UploadReqInfo; import org.openecomp.sdc.be.model.UploadResourceInfo; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; @@ -104,7 +115,10 @@ import org.openecomp.sdc.be.tosca.CsarUtils; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; +import org.yaml.snakeyaml.Yaml; class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTestSetup { @@ -115,6 +129,9 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest private final ServletUtils servletUtils = mock(ServletUtils.class); private final AbstractValidationsServlet servlet = new ArtifactExternalServlet(userBusinessLogic, componentInstanceBusinessLogic, componentsUtils, servletUtils, resourceImportManager, artifactsBusinessLogic); + private final ApplicationDataTypeCache applicationDataTypeCache = mock(ApplicationDataTypeCache.class); + private final DataTypeBusinessLogic dataTypeBusinessLogic = mock(DataTypeBusinessLogic.class); + @InjectMocks private ServiceImportBusinessLogic sIBL; @@ -148,7 +165,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest when(serviceBusinessLogic.validateServiceBeforeCreate(eq(newService), any(User.class), any(AuditingActionEnum.class))) .thenReturn(Either.left(newService)); when(toscaOperationFacade.validateCsarUuidUniqueness(anyString())).thenReturn(StorageOperationStatus.OK); - CsarInfo csarInfo = getCsarInfo(); + ServiceCsarInfo csarInfo = getCsarInfo(); when(csarBusinessLogic.getCsarInfo(any(Service.class), any(), any(User.class), any(Map.class), anyString())).thenReturn(csarInfo); when(serviceImportParseLogic.findNodeTypesArtifactsToHandle(any(Map.class), any(CsarInfo.class), any(Service.class))) .thenReturn(Either.left(new HashMap<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>>())); @@ -183,7 +200,10 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest when(mockJanusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK); when(graphLockOperation.unlockComponentByName(anyString(), anyString(), any(NodeTypeEnum.class))).thenReturn(StorageOperationStatus.OK); when(serviceImportParseLogic.createOutputsOnService(any(Service.class), any(), anyString())).thenReturn(newService); - + + when(applicationDataTypeCache.get(any(), contains("tosca.datatypes.test_"))).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)); + when(applicationDataTypeCache.get(any(), matches("^((?!tosca.datatypes.test_).)*$"))).thenReturn(Either.left(new DataTypeDefinition())); + Service result = sIBL.createService(oldService, AuditingActionEnum.CREATE_RESOURCE, user, payload, payloadName); assertNotNull(result); assertNotNull(result.getComponentInstances()); @@ -195,6 +215,13 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest assertEquals(1, result.getComponentInstances().get(0).getRequirements().size()); assertNotNull(result.getCategories()); assertEquals(1, result.getCategories().size()); + + ArgumentCaptor<String> yaml = ArgumentCaptor.forClass(String.class); + verify(dataTypeBusinessLogic).createDataTypeFromYaml(yaml.capture(), isNull(), anyBoolean()); + Map<String, Object> yamlMap = new Yaml().load(yaml.getValue()); + assertEquals(2, yamlMap.size()); + assertNotNull(yamlMap.get("tosca.datatypes.test_a")); + assertNotNull(yamlMap.get("tosca.datatypes.test_b")); } @Test @@ -222,7 +249,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Service oldService = createServiceObject(true); String csarUUID = "valid_vf"; Map<String, byte[]> payload = crateCsarFromPayload(); - CsarInfo csarInfo = getCsarInfo(); + ServiceCsarInfo csarInfo = getCsarInfo(); Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> map = new HashedMap(); @@ -240,7 +267,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Resource resource = createOldResource(); String topologyTemplateYaml = getMainTemplateContent("service_import_template.yml"); String yamlName = "group.yml"; - CsarInfo csarInfo = getCsarInfo(); + ServiceCsarInfo csarInfo = getCsarInfo(); Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate = new HashMap<>(); String nodeName = "org.openecomp.resource.derivedFrom.zxjTestImportServiceAb.test"; @@ -2342,14 +2369,28 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest return mainTemplateContent; } - protected CsarInfo getCsarInfo() { + protected ServiceCsarInfo getCsarInfo() { String csarUuid = "0010"; User user = new User("jh0003"); - Map<String, byte[]> csar = crateCsarFromPayload(); - String vfReousrceName = "resouceName"; - String mainTemplateName = "mainTemplateName"; - String mainTemplateContent = getMainTemplateContent("service_import_template.yml"); - return new CsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + + try { + File csarFile = new File( + ServiceImportBusinessLogicTest.class.getClassLoader().getResource("csars/service-Ser09080002-csar.csar").toURI()); + Map<String, byte[]> csar = ZipUtils.readZip(csarFile, false); + + String vfReousrceName = "resouceName"; + String mainTemplateName = "Definitions/service_import_template.yml"; + + Optional<String> keyOp = csar.keySet().stream().filter(k -> k.endsWith("service-Ser09080002-template.yml")).findAny(); + byte[] mainTemplateService = keyOp.map(csar::get).orElse(null); + assertNotNull(mainTemplateService); + final String mainTemplateContent = new String(mainTemplateService); + + return new ServiceCsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + } catch (URISyntaxException | ZipException e) { + fail(e); + } + return null; } protected CsarUtils.NonMetaArtifactInfo getNonMetaArtifactInfo() { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBussinessLogicBaseTestSetup.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBussinessLogicBaseTestSetup.java index c8fd87ca3b..06594dc180 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBussinessLogicBaseTestSetup.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBussinessLogicBaseTestSetup.java @@ -44,6 +44,7 @@ import org.openecomp.sdc.ElementOperationMock; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.OnboardedCsarInfo; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.impl.utils.CreateServiceFromYamlParameter; import org.openecomp.sdc.be.components.validation.UserValidations; @@ -673,7 +674,7 @@ public class ServiceImportBussinessLogicBaseTestSetup extends BaseBusinessLogicM String mainTemplateName = "mainTemplateName"; String mainTemplateContent = getMainTemplateContent(); final Service service = createServiceObject(false); - CsarInfo csarInfo = new CsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + CsarInfo csarInfo = new OnboardedCsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); return csarInfo; } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogicTest.java index c564f59398..b3154efe62 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogicTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyMap; @@ -33,7 +34,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import fj.data.Either; +import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.util.ArrayList; @@ -44,6 +47,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.Optional; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.lang3.tuple.ImmutablePair; import org.glassfish.grizzly.http.util.HttpStatus; @@ -54,6 +58,7 @@ import org.mockito.MockitoAnnotations; import org.openecomp.sdc.ElementOperationMock; import org.openecomp.sdc.be.auditing.impl.AuditingManager; import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.ServiceCsarInfo; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; @@ -103,16 +108,14 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; class ServiceImportParseLogicTest extends ServiceImportBussinessLogicBaseTestSetup { private static final String RESOURCE_NAME = "My-Resource_Name with space"; private static final String RESOURCE_TOSCA_NAME = "My-Resource_Tosca_Name"; - private static final String GENERIC_ROOT_NAME = "tosca.nodes.Root"; - private static final String GENERIC_VF_NAME = "org.openecomp.resource.abstract.nodes.VF"; - private static final String GENERIC_CR_NAME = "org.openecomp.resource.abstract.nodes.CR"; - private static final String GENERIC_PNF_NAME = "org.openecomp.resource.abstract.nodes.PNF"; private static final String RESOURCE_CATEGORY1 = "Network Layer 2-3"; private static final String RESOURCE_SUBCATEGORY = "Router"; @@ -2074,16 +2077,25 @@ class ServiceImportParseLogicTest extends ServiceImportBussinessLogicBaseTestSet protected CsarInfo getCsarInfo() { String csarUuid = "0010"; User user = new User(); - Map<String, byte[]> csar = new HashMap<>(); - String vfReousrceName = "resouceName"; - String mainTemplateName = "mainTemplateName"; - String mainTemplateContent = null; + File csarFile; try { - mainTemplateContent = loadFileNameToJsonString("service_import_template.yml"); - } catch (IOException e) { - e.printStackTrace(); + csarFile = new File( + ServiceImportBusinessLogicTest.class.getClassLoader().getResource("csars/service-Ser09080002-csar.csar").toURI()); + Map<String, byte[]> csar = ZipUtils.readZip(csarFile, false); + + String vfReousrceName = "resouceName"; + String mainTemplateName = "Definitions/service_import_template.yml"; + + Optional<String> keyOp = csar.keySet().stream().filter(k -> k.endsWith("service-Ser09080002-template.yml")).findAny(); + byte[] mainTemplateService = keyOp.map(csar::get).orElse(null); + assertNotNull(mainTemplateService); + final String mainTemplateContent = new String(mainTemplateService); + + return new ServiceCsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + } catch (URISyntaxException | ZipException e) { + fail(e); } - return new CsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + return null; } private String loadFileNameToJsonString(String fileName) throws IOException { diff --git a/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar b/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar Binary files differnew file mode 100644 index 0000000000..a65850469d --- /dev/null +++ b/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar diff --git a/catalog-be/src/test/resources/csars/serviceWithUnknownDataTypes.csar b/catalog-be/src/test/resources/csars/serviceWithUnknownDataTypes.csar Binary files differnew file mode 100644 index 0000000000..ffd209978f --- /dev/null +++ b/catalog-be/src/test/resources/csars/serviceWithUnknownDataTypes.csar diff --git a/catalog-be/src/test/resources/valid_vf.csar b/catalog-be/src/test/resources/valid_vf.csar Binary files differindex 01bf159071..cb9be9bc7e 100644 --- a/catalog-be/src/test/resources/valid_vf.csar +++ b/catalog-be/src/test/resources/valid_vf.csar |