diff options
Diffstat (limited to 'catalog-be/src/main')
3 files changed, 154 insertions, 10 deletions
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 58f3dc337c..50a7014f10 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2732,3 +2732,17 @@ errors: message: "Missing TOSCA function '%1'.", messageId: "SVC4172" } + + #-----------SVC4173--------------------------- + RELATIONSHIP_TEMPLATE_NOT_FOUND: { + code: 404, + message: "Relationship_templates entry not found in TOSCA CSAR.", + messageId: "SVC4173" + } + + #-----------SVC4174--------------------------- + RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND: { + code: 404, + message: "Relationship_templates definition not found in TOSCA CSAR.", + messageId: "SVC4174" + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java index 940363bce4..a68bbf3a2d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java @@ -29,6 +29,8 @@ import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaLis import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaMapElement; import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; import static org.openecomp.sdc.be.components.impl.ImportUtils.loadYamlAsStrictMap; +import static org.openecomp.sdc.be.datatypes.enums.MetadataKeyEnum.NAME; +import static org.openecomp.sdc.be.model.tosca.ToscaType.STRING; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ARTIFACTS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ATTRIBUTES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITIES; @@ -38,15 +40,20 @@ import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.FILE; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.GET_INPUT; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.GROUPS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IMPLEMENTATION; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INTERFACES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IS_PASSWORD; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.MEMBERS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TYPE; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OUTPUTS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.POLICIES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.RELATIONSHIP; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.RELATIONSHIP_TEMPLATES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIREMENTS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_FILTERS; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS; @@ -66,7 +73,9 @@ import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -108,6 +117,9 @@ import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; import org.openecomp.sdc.be.model.UploadPropInfo; import org.openecomp.sdc.be.model.UploadReqInfo; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition; +import org.openecomp.sdc.be.ui.model.OperationUi; +import org.openecomp.sdc.be.ui.model.PropertyAssignmentUi; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.log.wrappers.Logger; import org.yaml.snakeyaml.parser.ParserException; @@ -140,9 +152,9 @@ public class YamlTemplateParsingHandler { Map<String, NodeTypeInfo> nodeTypesInfo, String nodeName, Component component, String interfaceTemplateYaml) { log.debug("#parseResourceInfoFromYAML - Going to parse yaml {} ", fileName); - final Map<String, Object> mappedToscaTemplate = getMappedToscaTemplate(fileName, resourceYml, nodeTypesInfo, nodeName); - final ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo(); - final Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE, + Map<String, Object> mappedToscaTemplate = getMappedToscaTemplate(fileName, resourceYml, nodeTypesInfo, nodeName); + ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo(); + Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL).left().on(err -> failIfNotTopologyTemplate(fileName)); final Map<String, Object> mappedTopologyTemplateInputs = mappedTopologyTemplate.entrySet().stream() .filter(entry -> entry.getKey().equals(INPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -151,6 +163,7 @@ public class YamlTemplateParsingHandler { parsedToscaYamlInfo.setInputs(getInputs(mappedTopologyTemplateInputs)); parsedToscaYamlInfo.setOutputs(getOutputs(mappedTopologyTemplateOutputs)); parsedToscaYamlInfo.setInstances(getInstances(mappedToscaTemplate, createdNodesToscaResourceNames)); + associateRelationshipTemplatesToInstances(parsedToscaYamlInfo.getInstances(), mappedTopologyTemplate); parsedToscaYamlInfo.setGroups(getGroups(mappedToscaTemplate, component.getModel())); parsedToscaYamlInfo.setPolicies(getPolicies(mappedToscaTemplate, component.getModel())); Map<String, Object> substitutionMappings = getSubstitutionMappings(mappedToscaTemplate); @@ -354,6 +367,102 @@ public class YamlTemplateParsingHandler { return null; } + private void associateRelationshipTemplatesToInstances(final Map<String, UploadComponentInstanceInfo> instances, + final Map<String, Object> toscaJson) { + if (MapUtils.isEmpty(instances)) { + return; + } + for (UploadComponentInstanceInfo instance : instances.values()) { + final Map<String, List<OperationUi>> operations = new HashMap<>(); + final Map<String, List<UploadReqInfo>> requirements = instance.getRequirements(); + if (MapUtils.isNotEmpty(requirements)) { + requirements.values() + .forEach(requirementInfoList -> requirementInfoList.stream() + .filter(requirement -> StringUtils.isNotEmpty(requirement.getRelationshipTemplate())) + .forEach(requirement -> operations.put(requirement.getRelationshipTemplate(), + getOperationsFromRelationshipTemplate(toscaJson, requirement.getRelationshipTemplate())))); + } + instance.setOperations(operations); + } + } + + private Map<String, Object> getRelationshipTemplates(final Map<String, Object> toscaJson, final String relationshipTemplate) { + final Either<Map<String, Object>, ResultStatusEnum> eitherRelationshipTemplates = findFirstToscaMapElement(toscaJson, RELATIONSHIP_TEMPLATES); + if (eitherRelationshipTemplates.isRight()) { + throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_NOT_FOUND); + } + final Map<String, Object> relationshipTemplateMap = eitherRelationshipTemplates.left().value(); + final Map<String, Map<String, Object>> relationship = (Map<String, Map<String, Object>>) relationshipTemplateMap.get(relationshipTemplate); + if (relationship == null) { + throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND); + } + return relationship.get(INTERFACES.getElementName()); + } + + private List<ToscaInterfaceDefinition> buildToscaInterfacesFromRelationship(final Map<String, Object> interfaces) { + return interfaces.entrySet().stream() + .map(entry -> { + final var toscaInterfaceDefinition = new ToscaInterfaceDefinition(); + toscaInterfaceDefinition.setType(entry.getKey()); + final Map<String, Object> toscaInterfaceMap = (Map<String, Object>) entry.getValue(); + toscaInterfaceDefinition.setOperations((Map<String, Object>) toscaInterfaceMap.get(OPERATIONS.getElementName())); + return toscaInterfaceDefinition; + }) + .collect(toList()); + } + + private Optional<Object> getImplementation(final Map<String, Object> operationToscaMap) { + if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(IMPLEMENTATION.getElementName())) { + return Optional.empty(); + } + final Map<String, Object> implementationToscaMap = (Map<String, Object>) operationToscaMap.get(IMPLEMENTATION.getElementName()); + return Optional.ofNullable( + implementationToscaMap.computeIfPresent("toscaPresentation", (key, value) -> ((Map<String, Object>) value).get(NAME.getName())) + ); + } + + private List<PropertyAssignmentUi> getOperationsInputs(final Map<String, Object> operationToscaMap) { + if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(INPUTS.getElementName())) { + return Collections.emptyList(); + } + final Map<String, Object> inputsMap = (Map<String, Object>) operationToscaMap.get(INPUTS.getElementName()); + return inputsMap.entrySet().stream().map(this::buildInputAssignment).collect(toList()); + } + + private PropertyAssignmentUi buildInputAssignment(final Entry<String, Object> inputAssignmentMap) { + var propertyAssignmentUi = new PropertyAssignmentUi(); + propertyAssignmentUi.setName(inputAssignmentMap.getKey()); + propertyAssignmentUi.setValue(inputAssignmentMap.getValue().toString()); + propertyAssignmentUi.setType(STRING.getType()); + return propertyAssignmentUi; + } + + private List<OperationUi> getOperationsFromRelationshipTemplate(final Map<String, Object> toscaJson, final String relationshipTemplate) { + final List<OperationUi> operationUiList = new ArrayList<>(); + final List<ToscaInterfaceDefinition> interfaces = + buildToscaInterfacesFromRelationship(getRelationshipTemplates(toscaJson, relationshipTemplate)); + interfaces.stream() + .filter(interfaceDefinition -> MapUtils.isNotEmpty(interfaceDefinition.getOperations())) + .forEach(interfaceDefinition -> + interfaceDefinition.getOperations() + .forEach((operationType, operationValue) -> + operationUiList.add(buildOperation(interfaceDefinition.getType(), operationType, (Map<String, Object>) operationValue)) + )); + return operationUiList; + } + + private OperationUi buildOperation(final String interfaceType, final String operationType, final Map<String, Object> operationToscaMap) { + var operationUi = new OperationUi(); + operationUi.setInterfaceType(interfaceType); + operationUi.setOperationType(operationType); + getImplementation(operationToscaMap).ifPresent(operationUi::setImplementation); + final List<PropertyAssignmentUi> operationsInputs = getOperationsInputs(operationToscaMap); + if (CollectionUtils.isNotEmpty(operationsInputs)) { + operationUi.setInputs(operationsInputs); + } + return operationUi; + } + @SuppressWarnings("unchecked") private Map<String, GroupDefinition> getGroups(Map<String, Object> toscaJson, String model) { Map<String, Object> mappedTopologyTemplate = (Map<String, Object>) findToscaElement(toscaJson, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL) @@ -715,7 +824,7 @@ public class YamlTemplateParsingHandler { private void setRequirements(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(REQUIREMENTS.getElementName())) { - Map<String, List<UploadReqInfo>> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap); + Map<String, List<UploadReqInfo>> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap, nodeTemplateInfo.getName()); if (!regResponse.isEmpty()) { nodeTemplateInfo.setRequirements(regResponse); } @@ -746,14 +855,14 @@ public class YamlTemplateParsingHandler { } @SuppressWarnings("unchecked") - private Map<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) { + private Map<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap, String nodeName) { Map<String, List<UploadReqInfo>> moduleRequirements = new HashMap<>(); Either<List<Object>, ResultStatusEnum> requirementsListRes = findFirstToscaListElement(nodeTemplateJsonMap, REQUIREMENTS); if (requirementsListRes.isLeft()) { for (Object jsonReqObj : requirementsListRes.left().value()) { String reqName = ((Map<String, Object>) jsonReqObj).keySet().iterator().next(); Object reqJson = ((Map<String, Object>) jsonReqObj).get(reqName); - addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName); + addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName, nodeName); } } else { Either<Map<String, Object>, ResultStatusEnum> requirementsMapRes = findFirstToscaMapElement(nodeTemplateJsonMap, REQUIREMENTS); @@ -761,15 +870,15 @@ public class YamlTemplateParsingHandler { for (Map.Entry<String, Object> entry : requirementsMapRes.left().value().entrySet()) { String reqName = entry.getKey(); Object reqJson = entry.getValue(); - addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName); + addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName, nodeName); } } } return moduleRequirements; } - private void addModuleNodeTemplateReq(Map<String, List<UploadReqInfo>> moduleRequirements, Object requirementJson, String requirementName) { - UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson); + private void addModuleNodeTemplateReq(Map<String, List<UploadReqInfo>> moduleRequirements, Object requirementJson, String requirementName, String nodeName) { + UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson, nodeName); requirement.setName(requirementName); if (moduleRequirements.containsKey(requirementName)) { moduleRequirements.get(requirementName).add(requirement); @@ -911,7 +1020,7 @@ public class YamlTemplateParsingHandler { } @SuppressWarnings("unchecked") - private UploadReqInfo buildModuleNodeTemplateReg(Object regObject) { + private UploadReqInfo buildModuleNodeTemplateReg(Object regObject, String nodeName) { UploadReqInfo regTemplateInfo = new UploadReqInfo(); if (regObject instanceof String) { String nodeTemplateJsonString = (String) regObject; @@ -924,6 +1033,12 @@ public class YamlTemplateParsingHandler { if (nodeTemplateJsonMap.containsKey(CAPABILITY.getElementName())) { regTemplateInfo.setCapabilityName((String) nodeTemplateJsonMap.get(CAPABILITY.getElementName())); } + if (nodeTemplateJsonMap.containsKey(RELATIONSHIP.getElementName())) { + final String template = (String) nodeTemplateJsonMap.get(RELATIONSHIP.getElementName()); + if (StringUtils.isNotEmpty(nodeName) && template.contains(nodeName)) { + regTemplateInfo.setRelationshipTemplate(template); + } + } } return regTemplateInfo; } 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 225a6c4408..0850535108 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 @@ -40,6 +40,7 @@ import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; @@ -132,6 +133,7 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.tosca.CsarUtils; +import org.openecomp.sdc.be.ui.model.OperationUi; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; @@ -1862,6 +1864,9 @@ public class ServiceImportBusinessLogic { reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId()); CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship(); capReqRel.setRelation(reqAndRelationshipPair); + if (StringUtils.isNotEmpty(uploadRegInfo.getRelationshipTemplate())) { + capReqRel.setOperations(getOperations(nodesInfoValue.getOperations(), uploadRegInfo.getRelationshipTemplate())); + } reqAndRelationshipPairList.add(capReqRel); regCapRelDef.setRelationships(reqAndRelationshipPairList); relations.add(regCapRelDef); @@ -1871,6 +1876,16 @@ public class ServiceImportBusinessLogic { return componentsUtils.getResponseFormat(ActionStatus.OK, yamlName); } + private List<OperationUi> getOperations(final Map<String, List<OperationUi>> operations, final String relationshipTemplate) { + final List<OperationUi> operationUiList = new ArrayList<>(); + operations.forEach((operationKey, operationValues) -> { + if (operationKey.equals(relationshipTemplate)) { + operationUiList.addAll(operationValues); + } + }); + return operationUiList; + } + protected Service getResourceAfterCreateRelations(Service service) { ComponentParametersView parametersView = serviceImportParseLogic.getComponentFilterAfterCreateRelations(); Either<Service, StorageOperationStatus> eitherGetResource = toscaOperationFacade.getToscaElement(service.getUniqueId(), parametersView); |