diff options
Diffstat (limited to 'catalog-be/src')
11 files changed, 523 insertions, 104 deletions
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 5d4549406c..6a56da2c4d 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 @@ -40,6 +40,7 @@ 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.POLICIES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIREMENTS; @@ -64,6 +65,7 @@ import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -139,6 +141,9 @@ public class YamlTemplateParsingHandler { if (component instanceof Resource) { parsedToscaYamlInfo.setPolicies(getPolicies(fileName, mappedToscaTemplate, component.getModel())); } + if (getSubstitutionMappings(mappedToscaTemplate) != null) { + parsedToscaYamlInfo.setSubstitutionMappingNodeType((String) getSubstitutionMappings(mappedToscaTemplate).get(NODE_TYPE.getElementName())); + } log.debug("#parseResourceInfoFromYAML - The yaml {} has been parsed ", fileName); return parsedToscaYamlInfo; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java index 6007d0602e..7d4ba3bf77 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java @@ -686,14 +686,34 @@ public abstract class ComponentBusinessLogic extends BaseBusinessLogic { }); return componentNonGenericInputs; } + + protected void generatePropertiesFromGenericType(final Component component, final Resource genericType) { + if (CollectionUtils.isEmpty(genericType.getProperties())) { + return; + } + final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new) + .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList()); + if (component.getProperties() == null) { + component.setProperties(new ArrayList<>(genericTypePropertyList)); + } else { + List<PropertyDefinition> servicePropertyList = component.getProperties(); + genericTypePropertyList.stream() + .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName()))) + .forEach(servicePropertyList::add); + } + component.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null)); + } + protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component) { + return fetchAndSetDerivedFromGenericType(component, null); + } - protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(T component) { - Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component); + protected <T extends Component> Resource fetchAndSetDerivedFromGenericType(final T component, final String toscaType) { + final Either<Resource, ResponseFormat> genericTypeEither = this.genericTypeBusinessLogic.fetchDerivedFromGenericType(component, toscaType); if (genericTypeEither.isRight()) { log.debug("Failed to fetch latest generic type for component {} of type", component.getName(), component.assetType()); throw new ByActionStatusComponentException(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType()); } - Resource genericTypeResource = genericTypeEither.left().value(); + final Resource genericTypeResource = genericTypeEither.left().value(); component.setDerivedFromGenericInfo(genericTypeResource); return genericTypeResource; } @@ -855,7 +875,7 @@ public abstract class ComponentBusinessLogic extends BaseBusinessLogic { } public Either<Boolean, ResponseFormat> shouldUpgradeToLatestGeneric(Component clonedComponent) { - if (!clonedComponent.deriveFromGeneric()) { + if (!clonedComponent.deriveFromGeneric() || StringUtils.isNotEmpty(clonedComponent.getModel())) { return Either.left(false); } Boolean shouldUpgrade = false; 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 f5b890e438..2435b5e937 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 @@ -29,9 +29,6 @@ import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStr import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue; import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN; import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE; - -import com.google.common.annotations.VisibleForTesting; -import fj.data.Either; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -185,6 +182,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +import com.google.common.annotations.VisibleForTesting; +import fj.data.Either; @org.springframework.stereotype.Component("resourceBusinessLogic") public class ResourceBusinessLogic extends ComponentBusinessLogic { @@ -561,14 +560,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { preparedResource = updateExistingResourceByImport(newResource, oldResource, csarInfo.getModifier(), inTransaction, shouldLock, isNested).left; log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContent); - handleResourceGenericType(preparedResource); + handleResourceGenericType(preparedResource, yamlFileContent, uploadComponentInstanceInfoMap, uploadComponentInstanceInfoMap.getSubstitutionMappingNodeType()); handleNodeTypes(yamlFileName, preparedResource, yamlFileContent, shouldLock, nodeTypesArtifactsToHandle, createdArtifacts, nodeTypesInfo, - csarInfo, nodeName); + csarInfo, nodeName, newResource.getModel()); preparedResource = createInputsOnResource(preparedResource, uploadComponentInstanceInfoMap.getInputs()); Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>(); - preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instances, csarInfo.getCreatedNodes(), + final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(uploadComponentInstanceInfoMap, newResource.getModel()); + preparedResource = createResourceInstances(yamlFileName, preparedResource, oldResource, instancesToCreate, csarInfo.getCreatedNodes(), existingNodeTypesByResourceNames); - preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource, instances, + preparedResource = createResourceInstancesRelations(csarInfo.getModifier(), yamlFileName, preparedResource, oldResource, instancesToCreate, existingNodeTypesByResourceNames); } catch (ComponentException e) { ResponseFormat responseFormat = @@ -714,15 +714,31 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } return Either.left(resource); } - + private Resource handleResourceGenericType(Resource resource) { Resource genericResource = fetchAndSetDerivedFromGenericType(resource); + if (resource.shouldGenerateInputs()) { generateAndAddInputsFromGenericTypeProperties(resource, genericResource); } return genericResource; } + private Resource handleResourceGenericType(final Resource resource, final String topologyTemplateYaml, final ParsedToscaYamlInfo parsedToscaYamlInfo, final String substitutionMappingNodeType) { + if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) { + final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate((Map<String, Object>) new Yaml().load(topologyTemplateYaml), substitutionMappingNodeType); + final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, (String)substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName())); + + generatePropertiesFromGenericType(resource, genericResource); + generatePropertiesFromNodeType(resource, substitutableAsNodeType); + final String resourceId = resource.getUniqueId(); + resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName()))); + createResourcePropertiesOnGraph(resource); + return genericResource; + } + return handleResourceGenericType(resource); + } + private Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandle( final Map<String, NodeTypeInfo> nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) { final Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle = new HashMap<>(); @@ -1072,20 +1088,33 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { boolean needLock, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, - Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo) { + Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo, final String substitutableAsNodeType) { Either<String, ResultStatusEnum> toscaVersion = findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION); if (toscaVersion.isRight()) { throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE); } Map<String, Object> mapToConvert = new HashMap<>(); mapToConvert.put(TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), toscaVersion.left().value()); - Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate); + final Map<String, Object> nodeTypes = getNodeTypesFromTemplate(mappedToscaTemplate, substitutableAsNodeType); createNodeTypes(yamlName, resource, needLock, nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, mapToConvert, nodeTypes); return csarInfo.getCreatedNodes(); } - private Map<String, Object> getNodeTypesFromTemplate(Map<String, Object> mappedToscaTemplate) { + private Map<String, Object> getNodeTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) { + final Map<String, Object> nodeTypes = getAllNodeTypesInTemplate(mappedToscaTemplate); + if (StringUtils.isNotEmpty(substitutableAsNodeType)){ + nodeTypes.remove(substitutableAsNodeType); + } + return nodeTypes; + } + + @SuppressWarnings("unchecked") + private Map<String, Object> getSubstitutableAsNodeTypeFromTemplate(final Map<String, Object> mappedToscaTemplate, final String substitutableAsNodeType) { + return (Map<String, Object>)getAllNodeTypesInTemplate(mappedToscaTemplate).get(substitutableAsNodeType); + } + + private Map<String, Object> getAllNodeTypesInTemplate(final Map<String, Object> mappedToscaTemplate) { return ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES).left().orValue(HashMap::new); } @@ -1127,7 +1156,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { Map<String, Object> nestedVfcJsonMap = nodesInfo.get(nodeName).getMappedToscaTemplate(); log.debug("************* Going to create node types from yaml {}", yamlName); createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, createdArtifacts, - Collections.emptyMap(), csarInfo); + Collections.emptyMap(), csarInfo, resource.getModel()); log.debug("************* Finished to create node types from yaml {}", yamlName); if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) { log.debug("************* Going to handle complex VFC from yaml {}", yamlName); @@ -1395,36 +1424,60 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { log.trace("************* createResourceFromYaml before full create resource {}", yamlName); loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, "Starting to add inputs from yaml: {}", yamlName); - final Resource genericResource = fetchAndSetDerivedFromGenericType(resource); - resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative); - log.trace("************* createResourceFromYaml after full create resource {}", yamlName); - log.trace("************* Going to add inputs from yaml {}", yamlName); - if (resource.shouldGenerateInputs()) { - generateAndAddInputsFromGenericTypeProperties(resource, genericResource); - } - final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs(); - resource = createInputsOnResource(resource, inputs); - log.trace("************* Finish to add inputs from yaml {}", yamlName); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, - "Finish to add inputs from yaml: {}", yamlName); - if (resource.getResourceType() == ResourceTypeEnum.PNF) { - log.trace("************* Adding generic properties to PNF"); - resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties()); - log.trace("************* Adding software information to PNF"); - softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo); - log.trace("************* Removing non-mano software information file from PNF"); - if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo)) { - log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be", - "Could not remove the software information file."); + if (processSubstitutableAsNodeType(resource, parsedToscaYamlInfo)) { + final Map<String, Object> substitutableAsNodeType = getSubstitutableAsNodeTypeFromTemplate((Map<String, Object>) new Yaml().load(topologyTemplateYaml), parsedToscaYamlInfo.getSubstitutionMappingNodeType()); + resource.setToscaResourceName(parsedToscaYamlInfo.getSubstitutionMappingNodeType()); + final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, (String)substitutableAsNodeType.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName())); + resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative); + generatePropertiesFromGenericType(resource, genericResource); + generatePropertiesFromNodeType(resource, substitutableAsNodeType); + final String resourceId = resource.getUniqueId(); + resource.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyDefinition.getName()))); + + createResourcePropertiesOnGraph(resource); + final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo, resource.getModel()); + + log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); + loggerSupportability + .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, + "Start create nodes, RI and Relations from yaml: {}", yamlName); + resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml, + nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, parsedToscaYamlInfo.getSubstitutionMappingNodeType()); + } else { + final Resource genericResource = fetchAndSetDerivedFromGenericType(resource, null); + resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative); + log.trace("************* createResourceFromYaml after full create resource {}", yamlName); + log.trace("************* Going to add inputs from yaml {}", yamlName); + if (resource.shouldGenerateInputs()) { + generateAndAddInputsFromGenericTypeProperties(resource, genericResource); } - } - final Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap = parsedToscaYamlInfo.getInstances(); - log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); - loggerSupportability - .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, - "Start create nodes, RI and Relations from yaml: {}", yamlName); - resource = createRIAndRelationsFromYaml(yamlName, resource, uploadComponentInstanceInfoMap, topologyTemplateYaml, - nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName); + final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs(); + resource = createInputsOnResource(resource, inputs); + + log.trace("************* Finish to add inputs from yaml {}", yamlName); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, + "Finish to add inputs from yaml: {}", yamlName); + if (resource.getResourceType() == ResourceTypeEnum.PNF) { + log.trace("************* Adding generic properties to PNF"); + resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties()); + log.trace("************* Adding software information to PNF"); + softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo); + log.trace("************* Removing non-mano software information file from PNF"); + if (csarInfo.getSoftwareInformationPath().isPresent() && !softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo)) { + log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), "catalog-be", + "Could not remove the software information file."); + } + } + final Map<String, UploadComponentInstanceInfo> instancesToCreate = getInstancesToCreate(parsedToscaYamlInfo); + + log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); + loggerSupportability + .log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML, resource.getComponentMetadataForSupportLog(), StatusCode.STARTED, + "Start create nodes, RI and Relations from yaml: {}", yamlName); + resource = createRIAndRelationsFromYaml(yamlName, resource, instancesToCreate, topologyTemplateYaml, + nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName, null); + } + log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName); loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "Finished to create nodes, RI and Relation from yaml: {}", yamlName); @@ -1505,6 +1558,22 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } } } + + private boolean processSubstitutableAsNodeType(final Resource resource, final ParsedToscaYamlInfo parsedToscaYamlInfo) { + return !resource.getResourceType().isAtomicType() && StringUtils.isNotEmpty(resource.getModel()) && parsedToscaYamlInfo.getSubstitutionMappingNodeType() != null; + } + + private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo) { + return getInstancesToCreate(parsedToscaYamlInfo, null); + } + + private Map<String, UploadComponentInstanceInfo> getInstancesToCreate(final ParsedToscaYamlInfo parsedToscaYamlInfo, final String model) { + if (StringUtils.isEmpty(model) || StringUtils.isEmpty(parsedToscaYamlInfo.getSubstitutionMappingNodeType())) { + return parsedToscaYamlInfo.getInstances(); + } + return parsedToscaYamlInfo.getInstances().entrySet().stream().filter(entry -> !parsedToscaYamlInfo.getSubstitutionMappingNodeType().equals(entry.getValue().getType())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } private void rollback(boolean inTransaction, Resource resource, List<ArtifactDefinition> createdArtifacts, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts) { @@ -1689,6 +1758,41 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } return resource; } + + private Resource generatePropertiesFromNodeType(final Resource resource, final Map<String, Object> nodeType) { + final Either<Map<String, PropertyDefinition>, ResultStatusEnum> properties = ImportUtils.getProperties(nodeType); + if (properties.isLeft()) { + final List<PropertyDefinition> propertiesList = new ArrayList<>(); + final Map<String, PropertyDefinition> value = properties.left().value(); + if (value != null) { + for (Entry<String, PropertyDefinition> entry : value.entrySet()) { + final String name = entry.getKey(); + final PropertyDefinition propertyDefinition = entry.getValue(); + propertyDefinition.setName(name); + propertiesList.add(propertyDefinition); + resource.getProperties().removeIf(p -> p.getName().equals(name)); + } + } + resource.getProperties().addAll(propertiesList); + } + return resource; + } + + private Resource createResourcePropertiesOnGraph(final Resource resource) { + final List<PropertyDefinition> resourceProperties = resource.getProperties(); + for (PropertyDefinition propertyDefinition: resourceProperties) { + final Either<PropertyDefinition, StorageOperationStatus> addPropertyEither = toscaOperationFacade + .addPropertyToComponent(propertyDefinition.getName(), propertyDefinition, resource); + + if (addPropertyEither.isRight()) { + final String error = String.format("failed to add properties from yaml: {}", addPropertyEither.right().value()); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_PROPERTIES, resource.getComponentMetadataForSupportLog(), StatusCode.ERROR, + error); + throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(addPropertyEither.right().value()), error); + } + } + return resource; + } private List<GroupDefinition> updateGroupsMembersUsingResource(Map<String, GroupDefinition> groups, Resource component) { List<GroupDefinition> result = new ArrayList<>(); @@ -1829,10 +1933,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { String topologyTemplateYaml, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate, - String nodeName) { + String nodeName, final String substitutableAsNodeType) { log.debug("************* Going to create all nodes {}", yamlName); handleNodeTypes(yamlName, resource, topologyTemplateYaml, false, nodeTypesArtifactsToCreate, nodeTypesNewCreatedArtifacts, nodeTypesInfo, - csarInfo, nodeName); + csarInfo, nodeName, substitutableAsNodeType); log.debug("************* Finished to create all nodes {}", yamlName); log.debug("************* Going to create all resource instances {}", yamlName); Map<String, Resource> existingNodeTypesByResourceNames = new HashMap<>(); @@ -1864,7 +1968,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { private void handleNodeTypes(String yamlName, Resource resource, String topologyTemplateYaml, boolean needLock, Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToHandle, List<ArtifactDefinition> nodeTypesNewCreatedArtifacts, Map<String, NodeTypeInfo> nodeTypesInfo, CsarInfo csarInfo, - String nodeName) { + String nodeName, String substitutableAsNodeType) { try { for (Entry<String, NodeTypeInfo> nodeTypeEntry : nodeTypesInfo.entrySet()) { if (nodeTypeEntry.getValue().isNested() && !nodeTypeAlreadyExists(nodeTypeEntry.getKey())) { @@ -1881,7 +1985,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { mappedToscaTemplate = (Map<String, Object>) new Yaml().load(topologyTemplateYaml); } createResourcesFromYamlNodeTypesList(yamlName, resource, mappedToscaTemplate, needLock, nodeTypesArtifactsToHandle, - nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo); + nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, substitutableAsNodeType); } catch (ComponentException e) { ResponseFormat responseFormat = e.getResponseFormat() != null ? e.getResponseFormat() : componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()); @@ -2384,14 +2488,18 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } private void handleSubstitutionMappings(Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) { + Either<Resource, StorageOperationStatus> getResourceRes = null; if (resource.getResourceType() == ResourceTypeEnum.CVFC) { - Either<Resource, StorageOperationStatus> getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap); - if (getResourceRes.isRight()) { - ResponseFormat responseFormat = componentsUtils - .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource); - throw new ByResponseFormatComponentException(responseFormat); - } + getResourceRes = updateCalculatedCapReqWithSubstitutionMappings(resource, uploadResInstancesMap); + } else if (StringUtils.isNotEmpty(resource.getModel()) && resource.getResourceType() == ResourceTypeEnum.VF) { + getResourceRes = updateCalculatedCapReqWithSubstitutionMappingsForVf(resource, uploadResInstancesMap); } + if (getResourceRes != null && getResourceRes.isRight()) { + ResponseFormat responseFormat = componentsUtils + .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResourceRes.right().value()), resource); + throw new ByResponseFormatComponentException(responseFormat); + } + } private void addRelationsToRI(String yamlName, Resource resource, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, @@ -2559,6 +2667,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { Either<Resource, StorageOperationStatus> updateRes = null; Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>(); Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>(); + StorageOperationStatus status = toscaOperationFacade.deleteAllCalculatedCapabilitiesRequirements(resource.getUniqueId()); if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) { log.debug("Failed to delete all calculated capabilities and requirements of resource {} upon update. Status is {}", @@ -2581,6 +2690,31 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } return updateRes; } + + private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappingsForVf(final Resource resource, + final Map<String, UploadComponentInstanceInfo> uploadResInstancesMap) { + Either<Resource, StorageOperationStatus> updateRes = null; + final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilities = new HashMap<>(); + final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements = new HashMap<>(); + + resource.getComponentInstances().forEach(i -> { + setExternalCapabilities(updatedInstCapabilities, i, uploadResInstancesMap.get(i.getName()).getCapabilitiesNamesToUpdate()); + setExternalRequirements(updatedInstRequirements, i, uploadResInstancesMap.get(i.getName()).getRequirementsNamesToUpdate()); + }); + + final StorageOperationStatus status = toscaOperationFacade.updateCalculatedCapabilitiesRequirements(updatedInstCapabilities, updatedInstRequirements, resource); + if (status != StorageOperationStatus.OK) { + log.debug( + "Failed to update capabilities and requirements of resource {}. Status is {}", + resource.getUniqueId(), status); + updateRes = Either.right(status); + } + + if (updateRes == null) { + updateRes = Either.left(resource); + } + return updateRes; + } private void fillUpdatedInstCapabilitiesRequirements(List<ComponentInstance> componentInstances, Map<String, UploadComponentInstanceInfo> uploadResInstancesMap, @@ -2612,6 +2746,54 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { updatedInstRequirements.put(instance, updatedRequirements); } } + + private void setExternalRequirements( + final Map<ComponentInstance, Map<String, List<RequirementDefinition>>> updatedInstRequirements, + final ComponentInstance instance, final Map<String, String> requirementsNamesToUpdate) { + final Map<String, List<RequirementDefinition>> updatedRequirements = new HashMap<>(); + final Set<String> updatedReqNames = new HashSet<>(); + if (isNotEmpty(requirementsNamesToUpdate)) { + for (Map.Entry<String, List<RequirementDefinition>> requirements : instance.getRequirements().entrySet()) { + updatedRequirements.put(requirements.getKey(), + requirements.getValue().stream() + .filter(r -> requirementsNamesToUpdate.containsKey(r.getName()) + && !updatedReqNames.contains(requirementsNamesToUpdate.get(r.getName()))) + .map(r -> { + r.setExternal(true); + r.setExternalName(requirementsNamesToUpdate.get(r.getName())); + updatedReqNames.add(r.getName()); + return r; + }).collect(toList())); + } + } + if (isNotEmpty(updatedRequirements)) { + updatedInstRequirements.put(instance, updatedRequirements); + } + } + + private void setExternalCapabilities( + final Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties, + final ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) { + final Map<String, List<CapabilityDefinition>> updatedCapabilities = new HashMap<>(); + final Set<String> updatedCapNames = new HashSet<>(); + if (isNotEmpty(capabilitiesNamesToUpdate)) { + for (Map.Entry<String, List<CapabilityDefinition>> requirements : instance.getCapabilities().entrySet()) { + updatedCapabilities.put(requirements.getKey(), + requirements.getValue().stream() + .filter(c -> capabilitiesNamesToUpdate.containsKey(c.getName()) + && !updatedCapNames.contains(capabilitiesNamesToUpdate.get(c.getName()))) + .map(c -> { + c.setExternal(true); + c.setExternalName(capabilitiesNamesToUpdate.get(c.getName())); + updatedCapNames.add(c.getName()); + return c; + }).collect(toList())); + } + } + if (isNotEmpty(updatedCapabilities)) { + updatedInstCapabilties.put(instance, updatedCapabilities); + } + } private void fillUpdatedInstCapabilities(Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> updatedInstCapabilties, ComponentInstance instance, Map<String, String> capabilitiesNamesToUpdate) { @@ -3383,6 +3565,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { newResource.setUUID(oldResource.getUUID()); newResource.setNormalizedName(oldResource.getNormalizedName()); newResource.setSystemName(oldResource.getSystemName()); + newResource.setModel(oldResource.getModel()); if (oldResource.getCsarUUID() != null) { newResource.setCsarUUID(oldResource.getCsarUUID()); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index ccaadbad76..21d27f3fa0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -737,23 +737,6 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { }); } - private void generatePropertiesFromGenericType(final Service service, final Resource genericType) { - if (CollectionUtils.isEmpty(genericType.getProperties())) { - return; - } - final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new) - .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList()); - if (service.getProperties() == null) { - service.setProperties(new ArrayList<>(genericTypePropertyList)); - } else { - List<PropertyDefinition> servicePropertyList = service.getProperties(); - genericTypePropertyList.stream() - .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName()))) - .forEach(servicePropertyList::add); - } - service.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null)); - } - @SuppressWarnings("unchecked") private void createServiceApiArtifactsData(Service service, User user) { // create mandatory artifacts diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java index 313d345da1..6cf4327a99 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java @@ -78,6 +78,18 @@ public class GenericTypeBusinessLogic { Resource genericTypeResource = genericType.left().value(); return Either.left(genericTypeResource); } + + public Either<Resource, ResponseFormat> fetchDerivedFromGenericType(final Component component, final String toscaType) { + if (StringUtils.isNotEmpty(toscaType)) { + final Either<Resource, StorageOperationStatus> genericType = toscaOperationFacade.getLatestByToscaResourceNameAndModel(toscaType, component.getModel()); + if (genericType.isRight()) { + log.debug("Failed to fetch certified node type by tosca resource name {}", toscaType); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType(), toscaType)); + } + return Either.left(genericType.left().value()); + } + return fetchDerivedFromGenericType(component); + } /** * @param genericType the generic node type diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java index 88f3666305..8cc5868341 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java @@ -301,9 +301,7 @@ public class CapabilityRequirementConverter { Map<String, String[]> toscaRequirements = new HashMap<>(); Either<Map<String, String[]>, ToscaError> result = null; for (Map.Entry<String, List<RequirementDefinition>> entry : requirements.entrySet()) { - Optional<RequirementDefinition> failedToAddRequirement = entry.getValue().stream().filter(RequirementDefinition::isExternal).filter( - r -> !addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(r.getName(), r.getParentName(), ""), - r.getPreviousName(), r.getOwnerId(), r.getPath())).findAny(); + Optional<RequirementDefinition> failedToAddRequirement = addExternalToToscaRequirements(componentsCache, toscaRequirements, component, entry.getValue()); if (failedToAddRequirement.isPresent()) { logger.debug("Failed to convert requirement {} for substitution mappings section of a tosca template of the component {}. ", failedToAddRequirement.get().getName(), component.getName()); @@ -316,6 +314,18 @@ public class CapabilityRequirementConverter { } return result; } + + private Optional<RequirementDefinition> addExternalToToscaRequirements(final Map<String, Component> componentsCache, + final Map<String, String[]> toscaRequirements, final Component component, final List<RequirementDefinition> requirements) { + return requirements.stream().filter(RequirementDefinition::isExternal).filter( + r -> ! + (StringUtils.isEmpty(r.getExternalName()) ? + addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(r.getName(), r.getParentName(), ""), + r.getPreviousName(), r.getOwnerId(), r.getPath()): + addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(r.getExternalName(), r.getName(), ""), + r.getPreviousName(), r.getOwnerId(), r.getPath(), false)) + ).findAny(); + } private Either<Map<String, String[]>, ToscaError> buildAddSubstitutionMappingsCapabilities(Map<String, Component> componentsCache, Component component, @@ -323,11 +333,7 @@ public class CapabilityRequirementConverter { Map<String, String[]> toscaCapabilities = new HashMap<>(); Either<Map<String, String[]>, ToscaError> result = null; for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) { - Optional<CapabilityDefinition> failedToAddRequirement = entry.getValue().stream() - .filter(CapabilityDataDefinition::isExternal) - .filter( c -> !addEntry(componentsCache, toscaCapabilities, component, new SubstitutionEntry(c.getName(), c.getParentName(), "") - , c.getPreviousName(), c.getOwnerId(), c.getPath())) - .findAny(); + Optional<CapabilityDefinition> failedToAddRequirement = addExternalToToscaCapabilities(componentsCache, toscaCapabilities, component, entry.getValue()); if (failedToAddRequirement.isPresent()) { logger.debug("Failed to convert capability {} for substitution mappings section of a tosca template of the component {}. ", failedToAddRequirement.get().getName(), component.getName()); @@ -340,18 +346,38 @@ public class CapabilityRequirementConverter { } return result; } + + private Optional<CapabilityDefinition> addExternalToToscaCapabilities(final Map<String, Component> componentsCache, + final Map<String, String[]> toscaCapabilities, final Component component, final List<CapabilityDefinition> requirements) { + return requirements.stream() + .filter(CapabilityDataDefinition::isExternal) + .filter( c -> ! + (StringUtils.isEmpty(c.getExternalName()) ? + addEntry(componentsCache, toscaCapabilities, component, new SubstitutionEntry(c.getName(), c.getParentName(), ""), + c.getPreviousName(), c.getOwnerId(), c.getPath()): + addEntry(componentsCache, toscaCapabilities, component, new SubstitutionEntry(c.getName(), c.getParentName(), ""), + c.getPreviousName(), c.getOwnerId(), c.getPath(), false)) + ).findAny(); + } private boolean addEntry(Map<String, Component> componentsCache, Map<String, String[]> capReqMap, Component component, SubstitutionEntry entry, String previousName, String ownerId, List<String> path) { - if (shouldBuildSubstitutionName(component, path) && !buildSubstitutedNamePerInstance(componentsCache, component, entry.getFullName(), - previousName, path, ownerId, entry)) { + return addEntry(componentsCache, capReqMap, component, entry, previousName, ownerId, path, shouldBuildSubstitutionName(component, path)); + } + + private boolean addEntry(final Map<String, Component> componentsCache, Map<String, String[]> capReqMap, final Component component, + final SubstitutionEntry entry, final String previousName, final String ownerId, final List<String> path, final boolean shouldBuildSubstitutionName) { + if (shouldBuildSubstitutionName && !buildSubstitutedNamePerInstance(componentsCache, + component, entry.getFullName(), previousName, path, ownerId, entry)) { return false; } - logger.debug("The requirement/capability {} belongs to the component {} ", entry.getFullName(), component.getUniqueId()); + logger.debug("The requirement/capability {} belongs to the component {} ", entry.getFullName(), + component.getUniqueId()); if (StringUtils.isNotEmpty(entry.getSourceName())) { addEntry(capReqMap, component, path, entry); } - logger.debug("Finish convert the requirement/capability {} for the component {}. ", entry.getFullName(), component.getName()); + logger.debug("Finish convert the requirement/capability {} for the component {}. ", entry.getFullName(), + component.getName()); return true; } @@ -445,10 +471,16 @@ public class CapabilityRequirementConverter { private ImmutablePair<String, ToscaRequirement> convertRequirement(Map<String, Component> componentsCache, Component component, boolean isNodeType, RequirementDefinition r) { - String name = r.getName(); - if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) { - name = buildReqNamePerOwnerByPath(componentsCache, component, r); + String name; + if (StringUtils.isEmpty(r.getExternalName())){ + name = r.getName(); + if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) { + name = buildReqNamePerOwnerByPath(componentsCache, component, r); + } + } else { + name = r.getExternalName(); } + logger.debug("the requirement {} belongs to resource {} ", name, component.getUniqueId()); ToscaRequirement toscaRequirement = createToscaRequirement(r); return new ImmutablePair<>(name, toscaRequirement); @@ -546,9 +578,14 @@ public class CapabilityRequirementConverter { private void convertCapability(Map<String, Component> componentsCache, Component component, Map<String, ToscaCapability> toscaCapabilities, boolean isNodeType, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes, String capabilityName) { - String name = isNoneBlank(capabilityName) ? capabilityName : c.getName(); - if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) { - name = buildCapNamePerOwnerByPath(componentsCache, c, component); + String name; + if (StringUtils.isEmpty(c.getExternalName())) { + name = isNoneBlank(capabilityName) ? capabilityName : c.getName(); + if (!isNodeType && ToscaUtils.isNotComplexVfc(component)) { + name = buildCapNamePerOwnerByPath(componentsCache, c, component); + } + } else { + name = c.getExternalName(); } logger.debug("The capability {} belongs to resource {} ", name, component.getUniqueId()); createToscaCapability(toscaCapabilities, c, dataTypes, name); 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 fe2f3ba983..f0900f7589 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 @@ -27,20 +27,28 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import fj.data.Either; +import java.io.File; import java.io.IOException; import java.lang.reflect.Method; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -58,10 +66,12 @@ 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.YamlTemplateParsingHandler; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic; +import org.openecomp.sdc.be.components.impl.utils.YamlTemplateParsingHandlerTest; import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic; @@ -91,6 +101,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.GroupDefinition; @@ -98,8 +109,12 @@ import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; +import org.openecomp.sdc.be.model.UploadReqInfo; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; @@ -134,6 +149,8 @@ import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.web.context.WebApplicationContext; @@ -164,7 +181,8 @@ public class ResourceBusinessLogicTest { private final CatalogOperation catalogOperation = Mockito.mock(CatalogOperation.class); private final ICapabilityTypeOperation capabilityTypeOperation = Mockito.mock(ICapabilityTypeOperation.class); private final PropertyOperation propertyOperation = Mockito.mock(PropertyOperation.class); - private final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); + private final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); + private final ApplicationDataTypeCache dataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); private final WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); private final UserValidations userValidations = Mockito.mock(UserValidations.class); private final WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); @@ -195,6 +213,7 @@ public class ResourceBusinessLogicTest { private final ToscaExportHandler toscaExportHandler = Mockito.mock(ToscaExportHandler.class); private final PolicyBusinessLogic policyBusinessLogic = Mockito.mock(PolicyBusinessLogic.class); + private YamlTemplateParsingHandler yamlTemplateParsingHandler = Mockito.mock(YamlTemplateParsingHandler.class); @InjectMocks ResponseFormatManager responseManager = null; private final GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class); @@ -288,7 +307,8 @@ public class ResourceBusinessLogicTest { when(toscaOperationFacade.createToscaComponent(any(Resource.class))).thenReturn(eitherCreate); when(catalogOperation.updateCatalog(Mockito.any(), Mockito.any())).thenReturn(ActionStatus.OK); Map<String, DataTypeDefinition> emptyDataTypes = new HashMap<>(); - when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes)); + when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes)); + when(dataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes)); when(mockJanusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK); // BL object @@ -309,7 +329,8 @@ public class ResourceBusinessLogicTest { bl.setGraphLockOperation(graphLockOperation); bl.setPropertyOperation(propertyOperation); bl.setJanusGraphDao(mockJanusGraphDao); - bl.setApplicationDataTypeCache(applicationDataTypeCache); + bl.setApplicationDataTypeCache(applicationDataTypeCache); + bl.setDataTypeCache(dataTypeCache); bl.setGenericTypeBusinessLogic(genericTypeBusinessLogic); bl.setCatalogOperations(catalogOperation); toscaOperationFacade.setNodeTypeOperation(nodeTypeOperation); @@ -359,7 +380,7 @@ public class ResourceBusinessLogicTest { nodeTypesArtifactsToHandle, nodeTypesNewCreatedArtifacts, nodeTypesInfo, - new CsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", ImportUtilsTest.loadFileNameToJsonString("normative-types-new-webServer.yml"),true)); + new CsarInfo(user, "abcd1234", new HashMap<>(), RESOURCE_NAME, "template name", ImportUtilsTest.loadFileNameToJsonString("normative-types-new-webServer.yml"),true), ""); } @Test @@ -419,6 +440,37 @@ public class ResourceBusinessLogicTest { } return resource; } + + private Resource createResourceObjectWithModel(boolean afterCreate) { + Resource resource = new Resource(); + resource.setName(RESOURCE_NAME); + resource.setToscaResourceName(RESOURCE_TOSCA_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("My short description"); + List<String> tgs = new ArrayList<>(); + tgs.add("test"); + tgs.add(resource.getName()); + resource.setTags(tgs); + List<String> template = new ArrayList<>(); + template.add("tosca.nodes.Root"); + resource.setDerivedFrom(template); + resource.setVendorName("Motorola"); + resource.setVendorRelease("1.0.0"); + resource.setContactId("ya5467"); + resource.setIcon("defaulticon"); + resource.setModel("Test Model"); + + if (afterCreate) { + resource.setName(resource.getName()); + resource.setVersion("0.1"); + resource.setUniqueId(resource.getName() + .toLowerCase() + ":" + resource.getVersion()); + resource.setCreatorUserId(user.getUserId()); + resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + return resource; + } private Resource createResourceObjectCsar(boolean afterCreate) { Resource resource = new Resource(); @@ -1402,6 +1454,132 @@ public class ResourceBusinessLogicTest { public void createResourceFromCsarTest() { bl.createResourceFromCsar(resourceResponse, user, new HashMap<>(), ""); } + + @Test() + public void testCreateResourceFromCsarWithModel() throws URISyntaxException, ZipException { + + final File csarFile = new File( + ResourceBusinessLogicTest.class.getClassLoader().getResource("csars/nonOnapCsar.csar").toURI()); + final Map<String, byte[]> csar = ZipUtils.readZip(csarFile, false); + + String resourceYml = new String(csar.get("Definitions/my_vnf.yaml")); + + YamlTemplateParsingHandler yamlTemplateParser = new YamlTemplateParsingHandler(mockJanusGraphDao, null, Mockito.mock(AnnotationBusinessLogic.class), null); + final ParsedToscaYamlInfo parsedToscaYamlInfo = yamlTemplateParser.parseResourceInfoFromYAML("Definitions/my_vnf.yml", resourceYml, Collections.EMPTY_MAP, Collections.EMPTY_MAP, "myVnf", resourceResponse); + + when(toscaOperationFacade.getLatestByToscaResourceName(anyString())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + Resource vduCp = new Resource(); + vduCp.setToscaResourceName("tosca.nodes.nfv.VduCp"); + vduCp.setState(LifecycleStateEnum.CERTIFIED); + vduCp.setUniqueId("tosca.nodes.nfv.VduCp"); + vduCp.setProperties(new ArrayList<>()); + Map<String, List<RequirementDefinition>> requirements = new HashMap<>(); + RequirementDefinition req = new RequirementDefinition(); + req.setName("virtual_link"); + List<RequirementDefinition> listReqs = new ArrayList<>(); + listReqs.add(req); + requirements.put("tosca.nodes.nfv.VduCp", listReqs); + vduCp.setRequirements(requirements); + PropertyDefinition bitrateProp = new PropertyDefinition(); + bitrateProp.setName("bitrate_requirement"); + bitrateProp.setType("integer"); + vduCp.getProperties().add(bitrateProp); + PropertyDefinition virtNiProp = new PropertyDefinition(); + virtNiProp.setName("virtual_network_interface_requirements"); + virtNiProp.setType("list"); + vduCp.getProperties().add(virtNiProp); + PropertyDefinition descriptionProp = new PropertyDefinition(); + descriptionProp.setName("description"); + descriptionProp.setType("string"); + vduCp.getProperties().add(descriptionProp); + PropertyDefinition roleProp = new PropertyDefinition(); + roleProp.setName("role"); + roleProp.setType("string"); + vduCp.getProperties().add(roleProp); + when(toscaOperationFacade.getByToscaResourceNameMatchingVendorRelease("tosca.nodes.nfv.VduCp", "1.0.0")).thenReturn(Either.left(vduCp)); + + + when(yamlTemplateParsingHandler.parseResourceInfoFromYAML(any(), any(), any(), any(), any(), any())).thenReturn(parsedToscaYamlInfo); + + UploadComponentInstanceInfo uploadComponentInstanceInfo = new UploadComponentInstanceInfo(); + uploadComponentInstanceInfo.setType("myType"); + resourceResponse.setUniqueId("myVnf"); + resourceResponse.setName("myVnf"); + resourceResponse.setSystemName("myVnf"); + resourceResponse.setModel("testModel"); + resourceResponse.setResourceType(ResourceTypeEnum.VF); + resourceResponse.setProperties(new ArrayList<>()); + + Resource derivedFrom = new Resource(); + List<PropertyDefinition> properties = new ArrayList<>(); + PropertyDefinition baseTypeProp = new PropertyDefinition(); + baseTypeProp.setName("propInBase"); + baseTypeProp.setType("string"); + properties.add(baseTypeProp); + derivedFrom.setProperties(properties ); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(any(), eq("tosca.nodes.nfv.VNF"))).thenReturn(Either.left(derivedFrom)); + + when(toscaOperationFacade + .validateComponentNameAndModelExists("myVnf", "testModel", ResourceTypeEnum.VF, ComponentTypeEnum.RESOURCE)).thenReturn(Either.left(false)); + + when(toscaOperationFacade.addPropertyToComponent(any(), any(), any())).thenReturn(Either.left(new PropertyDefinition())); + when(toscaOperationFacade.associateComponentInstancePropertiesToComponent(any(), any())).thenReturn(Either.left(Collections.emptyMap())); + when(toscaOperationFacade.associateArtifactsToInstances(any(), any())).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.associateDeploymentArtifactsToInstances(any(), any(), any())).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.associateInstAttributeToComponentToInstances(any(), any())).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.associateResourceInstances(any(Component.class), anyString(), anyList())).thenReturn(Either.left(Collections.EMPTY_LIST)); + + doAnswer(invocation -> { + Map<ComponentInstance, Map<String, List<RequirementDefinition>>> instReqs = invocation.getArgument(1); + for (final Entry<ComponentInstance, Map<String, List<RequirementDefinition>>> m: instReqs.entrySet()) { + m.getKey().setRequirements(m.getValue()); + } + return StorageOperationStatus.OK; + }). + when(toscaOperationFacade).associateOrAddCalculatedCapReq(any(), any(), any()); + + + when(toscaOperationFacade.updateCalculatedCapabilitiesRequirements(any(), any(), any())).thenReturn(StorageOperationStatus.OK); + when(groupBusinessLogic.validateUpdateVfGroupNames(any(), any())).thenReturn(Either.left(Collections.EMPTY_MAP)); + + ComponentInstance ci = new ComponentInstance(); + List<ComponentInstance> cis = new ArrayList<>(); + cis.add(ci); + doAnswer(invocation -> { + List<ComponentInstance> componentInstances = new ArrayList<ComponentInstance>(((Map<ComponentInstance, Resource>)invocation.getArgument(1)).keySet()); + ((Resource)invocation.getArgument(0)).setComponentInstances(componentInstances); + return null; + }).when(toscaOperationFacade).associateComponentInstancesToComponent(any(), any(), eq(false), eq(false)); + + doAnswer(invocation -> { + return Either.left(invocation.getArgument(0)); + }).when(csarArtifactsAndGroupsBusinessLogic).deleteVFModules(any(Resource.class), any(CsarInfo.class), eq(true), eq(false)); + + doAnswer(invocation -> { + return Either.left(resourceResponse); + }).when(toscaOperationFacade).getToscaFullElement("myVnf"); + + + Resource result = bl.createResourceFromCsar(resourceResponse, user, csar, "1234"); + + assertEquals("myDomain.myVnf", result.getToscaResourceName()); + List<String> propIds = result.getProperties().stream().map(prop -> prop.getUniqueId()).collect(Collectors.toList()); + assertTrue(propIds.contains("myVnf.propInBase")); + assertTrue(propIds.contains("myVnf.descriptor_id")); + assertTrue(propIds.contains("myVnf.descriptor_version")); + assertTrue(propIds.contains("myVnf.flavour_description")); + assertTrue(propIds.contains("myVnf.flavour_id")); + assertTrue(propIds.contains("myVnf.product_name")); + assertTrue(propIds.contains("myVnf.provider")); + assertTrue(propIds.contains("myVnf.software_version")); + assertTrue(propIds.contains("myVnf.vnfm_info")); + + final List<String> reqsName = new ArrayList<>(); + + final List<ComponentInstance> cisWithExtReq = result.getComponentInstances().stream().filter(instance -> instance.getRequirements().get("tosca.nodes.nfv.VduCp").get(0).isExternal()).collect(Collectors.toList()); + cisWithExtReq.forEach(instance -> reqsName.add(instance.getRequirements().get("tosca.nodes.nfv.VduCp").get(0).getExternalName())); + assertEquals(3, cisWithExtReq.size()); + } @Test public void testResourceCategoryAfterCertify_UPDATE() { @@ -2097,7 +2275,7 @@ public class ResourceBusinessLogicTest { resource.setDerivedFrom(null); resource.setResourceType(ResourceTypeEnum.VF); when(toscaOperationFacade.createToscaComponent(resource)).thenReturn(Either.left(resource)); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource)).thenReturn(Either.left(genericVF)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource, null)).thenReturn(Either.left(genericVF)); when(genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericVF)).thenCallRealMethod(); when(genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericVF.getProperties(), resource.getUniqueId())).thenCallRealMethod(); @@ -2125,7 +2303,7 @@ public class ResourceBusinessLogicTest { resource.setDerivedFrom(null); resource.setResourceType(ResourceTypeEnum.CR); when(toscaOperationFacade.createToscaComponent(resource)).thenReturn(Either.left(resource)); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource)).thenReturn(Either.left(genericCR)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource, null)).thenReturn(Either.left(genericCR)); when(genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericCR)).thenCallRealMethod(); when(genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericCR.getProperties(), resource.getUniqueId())).thenCallRealMethod(); @@ -2146,7 +2324,7 @@ public class ResourceBusinessLogicTest { resource.setDerivedFrom(null); resource.setResourceType(ResourceTypeEnum.PNF); when(toscaOperationFacade.createToscaComponent(resource)).thenReturn(Either.left(resource)); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource)).thenReturn(Either.left(genericPNF)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(resource, null)).thenReturn(Either.left(genericPNF)); when(genericTypeBusinessLogic.generateInputsFromGenericTypeProperties(genericPNF)).thenCallRealMethod(); when(genericTypeBusinessLogic.convertGenericTypePropertiesToInputsDefintion(genericPNF.getProperties(), resource.getUniqueId())).thenCallRealMethod(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogicTest.java index 42d24bbcd1..a64e3c1c85 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogicTest.java @@ -95,7 +95,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup @Test public void testHappyScenario() { Service service = createServiceObject(false); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericService)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericService)); Either<Service, ResponseFormat> createResponse = bl.createService(service, user); if (createResponse.isRight()) { @@ -107,7 +107,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup @Test public void testServiceCreationPluginCall() { final Service service = createServiceObject(false); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericService)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericService)); final List<ServiceCreationPlugin> serviceCreationPlugins = new ArrayList<>(); serviceCreationPlugins.add(new ServiceCreationPlugin() { @Override @@ -143,7 +143,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup final Resource genericTypeResource = mockGenericTypeResource(); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericTypeResource)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericTypeResource)); final Service expectedService = createServiceObject(true); expectedService.setProperties(mockPropertyList()); when(toscaOperationFacade.createToscaComponent(service)).thenReturn(Either.left(expectedService)); @@ -168,7 +168,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup final Resource genericTypeResource = mockGenericTypeResource(); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericTypeResource)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericTypeResource)); final Service expectedService = createServiceObject(true); expectedService.setProperties(mockPropertyList()); expectedService.getProperties().add(serviceProperty); @@ -188,7 +188,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup public void testHappyScenarioCRNullProjectCode() { Service service = createServiceObject(false); service.setProjectCode(null); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericService)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericService)); Either<Service, ResponseFormat> createResponse = bl.createService(service, user); if (createResponse.isRight()) { @@ -202,7 +202,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup createServiceValidator(); Service service = createServiceObject(false); service.setProjectCode(""); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericService)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericService)); Either<Service, ResponseFormat> createResponse = bl.createService(service, user); if (createResponse.isRight()) { @@ -744,7 +744,7 @@ public class ServiceBusinessLogicTest extends ServiceBussinessLogicBaseTestSetup public void testDerivedFromGeneric() { Service service = createServiceObject(true); when(toscaOperationFacade.createToscaComponent(service)).thenReturn(Either.left(service)); - when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service)).thenReturn(Either.left(genericService)); + when(genericTypeBusinessLogic.fetchDerivedFromGenericType(service, null)).thenReturn(Either.left(genericService)); Either<Service, ResponseFormat> createResponse = bl.createService(service, user); assertTrue(createResponse.isLeft()); service = createResponse.left().value(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java index 69367e962c..059dde3254 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/YamlTemplateParsingHandlerTest.java @@ -264,6 +264,7 @@ public class YamlTemplateParsingHandlerTest { .get(CAPABILITY_TYPE) .get(0).getProperties().get(0).getValue()).isEqualTo("success"); assertThat(parsedYaml.getGroups().get(MAIN_GROUP_NAME).getCapabilities()).isNotNull(); + assertThat(parsedYaml.getSubstitutionMappingNodeType()).isEqualTo("org.openecomp.resource.abstract.nodes.VF"); } private void stubGetGroupType() { diff --git a/catalog-be/src/test/resources/csars/nonOnapCsar.csar b/catalog-be/src/test/resources/csars/nonOnapCsar.csar Binary files differnew file mode 100644 index 0000000000..fcf6b7f2ae --- /dev/null +++ b/catalog-be/src/test/resources/csars/nonOnapCsar.csar diff --git a/catalog-be/src/test/resources/csars/with_groups.csar b/catalog-be/src/test/resources/csars/with_groups.csar Binary files differindex 3a9e9ab8e0..9259a81de0 100644 --- a/catalog-be/src/test/resources/csars/with_groups.csar +++ b/catalog-be/src/test/resources/csars/with_groups.csar |