X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fcsar%2FYamlTemplateParsingHandler.java;h=5556548b50c6aba7396fbeb43fcadd1468f2677e;hb=39dd951527bf62568cf5815a6b1e4901c2b89c3f;hp=9636885190af5e9340783115c72b72994d6a7f43;hpb=a8d3e1b8c759c21227690a425552a245da883e97;p=sdc.git 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 9636885190..5556548b50 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 @@ -19,136 +19,205 @@ * Modifications copyright (c) 2019 Nokia * ================================================================================ */ + package org.openecomp.sdc.be.components.csar; +import static java.util.stream.Collectors.toList; +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE; +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.findFirstToscaListElement; +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.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; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITY; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE; +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; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TARGETS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES; + +import com.att.aft.dme2.internal.gson.reflect.TypeToken; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.Gson; import fj.data.Either; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EnumMap; +import java.util.HashMap; +import java.util.LinkedHashMap; +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.UUID; +import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic; import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.NodeFilterUploadCreator; import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.utils.PropertiesUtils; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubPropertyToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupTypeDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; import org.openecomp.sdc.be.model.PolicyDefinition; import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.UploadArtifactInfo; +import org.openecomp.sdc.be.model.UploadAttributeInfo; import org.openecomp.sdc.be.model.UploadCapInfo; import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; +import org.openecomp.sdc.be.model.UploadInterfaceInfo; 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.tosca.utils.OperationArtifactUtil; +import org.openecomp.sdc.be.ui.model.OperationUi; +import org.openecomp.sdc.be.ui.model.PropertyAssignmentUi; +import org.openecomp.sdc.be.utils.PropertyFilterConstraintDataDefinitionHelper; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Component; import org.yaml.snakeyaml.parser.ParserException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.toList; -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.findFirstToscaListElement; -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.utils.TypeUtils.ToscaTagNamesEnum.ARTIFACTS; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITIES; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CAPABILITY; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE; -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.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.POLICIES; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIREMENTS; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TARGETS; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES; - /** * A handler class designed to parse the YAML file of the service template for a JAVA object */ -@Component +@org.springframework.stereotype.Component public class YamlTemplateParsingHandler { - private static final Pattern propertyValuePattern = Pattern.compile("[ ]*\\{[ ]*(str_replace=|token=|get_property=|concat=|get_attribute=)+"); private static final int SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX = 0; private static final int SUB_MAPPING_CAPABILITY_NAME_IDX = 1; private static final Logger log = Logger.getLogger(YamlTemplateParsingHandler.class); - - - private Gson gson = new Gson(); - private JanusGraphDao janusGraphDao; - private GroupTypeBusinessLogic groupTypeBusinessLogic; - private AnnotationBusinessLogic annotationBusinessLogic; - private PolicyTypeBusinessLogic policyTypeBusinessLogic; - - public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao, GroupTypeBusinessLogic groupTypeBusinessLogic, - AnnotationBusinessLogic annotationBusinessLogic, PolicyTypeBusinessLogic policyTypeBusinessLogic) { + private final Gson gson = new Gson(); + private final JanusGraphDao janusGraphDao; + private final GroupTypeBusinessLogic groupTypeBusinessLogic; + private final AnnotationBusinessLogic annotationBusinessLogic; + private final PolicyTypeBusinessLogic policyTypeBusinessLogic; + private final ServiceBusinessLogic serviceBusinessLogic; + private final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler; + + public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao, + GroupTypeBusinessLogic groupTypeBusinessLogic, + AnnotationBusinessLogic annotationBusinessLogic, + PolicyTypeBusinessLogic policyTypeBusinessLogic, + ServiceBusinessLogic serviceBusinessLogic, + final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler + ) { this.janusGraphDao = janusGraphDao; this.groupTypeBusinessLogic = groupTypeBusinessLogic; this.annotationBusinessLogic = annotationBusinessLogic; this.policyTypeBusinessLogic = policyTypeBusinessLogic; + this.serviceBusinessLogic = serviceBusinessLogic; + this.toscaFunctionYamlParsingHandler = toscaFunctionYamlParsingHandler; } public ParsedToscaYamlInfo parseResourceInfoFromYAML(String fileName, String resourceYml, Map createdNodesToscaResourceNames, - Map nodeTypesInfo, String nodeName, org.openecomp.sdc.be.model.Component component) { + Map nodeTypesInfo, String nodeName, + Component component, String interfaceTemplateYaml) { log.debug("#parseResourceInfoFromYAML - Going to parse yaml {} ", fileName); Map mappedToscaTemplate = getMappedToscaTemplate(fileName, resourceYml, nodeTypesInfo, nodeName); ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo(); - findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL) - .left() - .on(err -> failIfNotTopologyTemplate(fileName)); - - parsedToscaYamlInfo.setInputs(getInputs(mappedToscaTemplate)); - parsedToscaYamlInfo.setInstances(getInstances(fileName, mappedToscaTemplate, createdNodesToscaResourceNames)); - parsedToscaYamlInfo.setGroups(getGroups(fileName, mappedToscaTemplate)); - if(component instanceof Resource){ - parsedToscaYamlInfo.setPolicies(getPolicies(fileName, mappedToscaTemplate)); + Map mappedTopologyTemplate = (Map) findToscaElement(mappedToscaTemplate, TOPOLOGY_TEMPLATE, + ToscaElementTypeEnum.ALL).left().on(err -> failIfNotTopologyTemplate(fileName)); + final Map mappedTopologyTemplateInputs = mappedTopologyTemplate.entrySet().stream() + .filter(entry -> entry.getKey().equals(INPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + final Map mappedTopologyTemplateOutputs = mappedTopologyTemplate.entrySet().stream() + .filter(entry -> entry.getKey().equals(OUTPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + 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 substitutionMappings = getSubstitutionMappings(mappedToscaTemplate); + if (substitutionMappings != null) { + if (component.isService()) { + if (interfaceTemplateYaml.isEmpty()) { + List properties = serviceBusinessLogic.fetchDerivedFromGenericType(component, null).getProperties(); + parsedToscaYamlInfo.setProperties(properties.stream().collect(Collectors.toMap(PropertyDefinition::getName, prop -> prop))); + } else { + parsedToscaYamlInfo.setProperties(getProperties(loadYamlAsStrictMap(interfaceTemplateYaml))); + } + parsedToscaYamlInfo.setSubstitutionFilterProperties(getSubstitutionFilterProperties(mappedToscaTemplate)); + } + if (substitutionMappings.get("properties") != null) { + parsedToscaYamlInfo.setSubstitutionMappingProperties((Map>) substitutionMappings.get("properties")); + } + parsedToscaYamlInfo.setSubstitutionMappingNodeType((String) substitutionMappings.get(NODE_TYPE.getElementName())); } log.debug("#parseResourceInfoFromYAML - The yaml {} has been parsed ", fileName); return parsedToscaYamlInfo; } - private Map getMappedToscaTemplate(String fileName, String resourceYml, Map nodeTypesInfo, String nodeName) { + private Map getMappedToscaTemplate(String fileName, String resourceYml, Map nodeTypesInfo, + String nodeName) { Map mappedToscaTemplate; if (isNodeExist(nodeTypesInfo, nodeName)) { mappedToscaTemplate = nodeTypesInfo.get(nodeName).getMappedToscaTemplate(); @@ -174,37 +243,99 @@ public class YamlTemplateParsingHandler { } private Map getInputs(Map toscaJson) { - Map inputs = ImportUtils.getInputs(toscaJson, annotationBusinessLogic.getAnnotationTypeOperations()) - .left() - .on(err -> new HashMap<>()); + Map inputs = ImportUtils.getInputs(toscaJson, annotationBusinessLogic.getAnnotationTypeOperations()).left() + .on(err -> new HashMap<>()); annotationBusinessLogic.validateAndMergeAnnotationsAndAssignToInput(inputs); return inputs; } - private Map getPolicies(String fileName, Map toscaJson) { + private Map getOutputs(Map toscaJson) { + return ImportUtils.getOutputs(toscaJson).left().on(err -> new HashMap<>()); + } + + private Map getProperties(Map toscaJson) { + return ImportUtils.getProperties(toscaJson).left().on(err -> new HashMap<>()); + } + + private ListDataDefinition getSubstitutionFilterProperties(final Map toscaJson) { + final ListDataDefinition propertyList = new ListDataDefinition<>(); + final Map substitutionFilters = findFirstToscaMapElement(toscaJson, SUBSTITUTION_FILTERS).left().on(err -> new HashMap<>()); + if (MapUtils.isEmpty(substitutionFilters)) { + return propertyList; + } + final List> substitutionFilterProperties = (List>) substitutionFilters.get("properties"); + if (CollectionUtils.isEmpty(substitutionFilterProperties)) { + return propertyList; + } + for (final Map filterProps : substitutionFilterProperties) { + for (final Map.Entry propertyFilterEntry : filterProps.entrySet()) { + final String propertyName = propertyFilterEntry.getKey(); + final Object value = propertyFilterEntry.getValue(); + if (value instanceof List) { + final List> propertyFilterEntryValue = (List>) value; + for (final Map filterValueMap : propertyFilterEntryValue) { + final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterPropertyDataDefinition.setName(propertyName); + substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap)); + propertyList.add(substitutionFilterPropertyDataDefinition); + } + } else if (value instanceof Map) { + final Map filterValueMap = (Map) value; + final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterPropertyDataDefinition.setName(propertyName); + substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap)); + propertyList.add(substitutionFilterPropertyDataDefinition); + } + } + } + return propertyList; + } + + private List createSubstitutionFilterConstraints(final String name, final Map value) { + final List constraints = new ArrayList<>(); + for (final Map.Entry valueEntry : value.entrySet()) { + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint.setPropertyName(name); + propertyFilterConstraint.setOperator(ConstraintType.findByType(valueEntry.getKey()).orElse(null)); + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY); + final Optional toscaFunction = PropertyFilterConstraintDataDefinitionHelper + .createToscaFunctionFromLegacyConstraintValue(valueEntry.getValue()); + if (toscaFunction.isPresent()) { + final ToscaFunction toscaFunction1 = toscaFunction.get(); + propertyFilterConstraint.setValue(toscaFunction1); + propertyFilterConstraint.setValueType( + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(toscaFunction1.getType()).orElse(null) + ); + } else { + propertyFilterConstraint.setValue(valueEntry.getValue()); + propertyFilterConstraint.setValueType(FilterValueType.STATIC); + } + constraints.add(propertyFilterConstraint); + } - Map foundPolicies = findFirstToscaMapElement(toscaJson, POLICIES) - .left() - .on(err -> logPoliciesNotFound(fileName)); + return constraints; + } + private Map getPolicies(Map toscaJson, String model) { + Map mappedTopologyTemplate = (Map) findToscaElement(toscaJson, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL) + .left().on(err -> new HashMap<>()); + Map foundPolicies = (Map) mappedTopologyTemplate.get(POLICIES.getElementName()); if (MapUtils.isNotEmpty(foundPolicies)) { - return foundPolicies - .entrySet() - .stream() - .map(this::createPolicy) - .collect(Collectors.toMap(PolicyDefinition::getName, p -> p)); + return foundPolicies.entrySet().stream().map(policyToCreate -> createPolicy(policyToCreate, model)) + .collect(Collectors.toMap(PolicyDefinition::getName, p -> p)); } return Collections.emptyMap(); } - private PolicyDefinition createPolicy(Map.Entry policyNameValue) { + private PolicyDefinition createPolicy(Map.Entry policyNameValue, String model) { PolicyDefinition emptyPolicyDef = new PolicyDefinition(); String policyName = policyNameValue.getKey(); emptyPolicyDef.setName(policyName); try { - if (policyNameValue.getValue() != null && policyNameValue.getValue() instanceof Map) { + // There's no need to null test in conjunction with an instanceof test. null is not an instanceof anything, so a null check is redundant. + if (policyNameValue.getValue() instanceof Map) { Map policyTemplateJsonMap = (Map) policyNameValue.getValue(); - validateAndFillPolicy(emptyPolicyDef, policyTemplateJsonMap); + validateAndFillPolicy(emptyPolicyDef, policyTemplateJsonMap, model); } else { rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); } @@ -215,27 +346,22 @@ public class YamlTemplateParsingHandler { return emptyPolicyDef; } - private Map logPoliciesNotFound(String fileName) { - log.debug("#logPoliciesNotFound - Policies were not found in the yaml template {}.", fileName); - return Collections.emptyMap(); - } - - private void validateAndFillPolicy(PolicyDefinition emptyPolicyDefinition, Map policyTemplateJsonMap) { + private void validateAndFillPolicy(PolicyDefinition emptyPolicyDefinition, Map policyTemplateJsonMap, String model) { String policyTypeName = (String) policyTemplateJsonMap.get(TYPE.getElementName()); - if(StringUtils.isEmpty(policyTypeName)){ + if (StringUtils.isEmpty(policyTypeName)) { log.debug("#validateAndFillPolicy - The 'type' member is not found under policy {}", emptyPolicyDefinition.getName()); rollbackWithException(ActionStatus.POLICY_MISSING_POLICY_TYPE, emptyPolicyDefinition.getName()); } emptyPolicyDefinition.setType(policyTypeName); // set policy targets emptyPolicyDefinition.setTargets(validateFillPolicyTargets(policyTemplateJsonMap)); - PolicyTypeDefinition policyTypeDefinition = validateGetPolicyTypeDefinition(policyTypeName); + PolicyTypeDefinition policyTypeDefinition = validateGetPolicyTypeDefinition(policyTypeName, model); // set policy properties emptyPolicyDefinition.setProperties(validateFillPolicyProperties(policyTypeDefinition, policyTemplateJsonMap)); } - private PolicyTypeDefinition validateGetPolicyTypeDefinition(String policyType) { - PolicyTypeDefinition policyTypeDefinition = policyTypeBusinessLogic.getLatestPolicyTypeByType(policyType); + private PolicyTypeDefinition validateGetPolicyTypeDefinition(String policyType, String modelName) { + PolicyTypeDefinition policyTypeDefinition = policyTypeBusinessLogic.getLatestPolicyTypeByType(policyType, modelName); if (policyTypeDefinition == null) { log.debug("#validateAndFillPolicy - The policy type {} not found", policyType); rollbackWithException(ActionStatus.POLICY_TYPE_IS_INVALID, policyType); @@ -243,138 +369,232 @@ public class YamlTemplateParsingHandler { return policyTypeDefinition; } - private List validateFillPolicyProperties(PolicyTypeDefinition policyTypeDefinition, - Map policyTemplateJsonMap) { - if (MapUtils.isEmpty(policyTemplateJsonMap) || Objects.isNull(policyTypeDefinition)) { + private List validateFillPolicyProperties(final PolicyTypeDefinition policyTypeDefinition, + final Map policyTemplateJsonMap) { + if (policyTypeDefinition == null || CollectionUtils.isEmpty(policyTypeDefinition.getProperties()) + || MapUtils.isEmpty(policyTemplateJsonMap)) { return Collections.emptyList(); } - List propertyDataDefinitionList = new ArrayList<>(); - Map propertiesMap = - (Map) policyTemplateJsonMap.get(PROPERTIES.getElementName()); - if (MapUtils.isEmpty(propertiesMap)) { + final Map propertiesJsonMap = (Map) policyTemplateJsonMap.get(PROPERTIES.getElementName()); + if (MapUtils.isEmpty(propertiesJsonMap)) { return Collections.emptyList(); } - if (CollectionUtils.isNotEmpty(policyTypeDefinition.getProperties())) { - propertyDataDefinitionList = policyTypeDefinition - .getProperties() - .stream() - .map(propertyDefinition -> setPropertyValue(propertiesMap, - propertyDefinition)) - .collect(Collectors.toList()); - } - return propertyDataDefinitionList; - } - - private PropertyDataDefinition setPropertyValue(Map propertiesMap, PropertyDataDefinition srcPropertyDataDefinition) { - PropertyDataDefinition newPropertyDef = new PropertyDataDefinition(srcPropertyDataDefinition); - String propertyName = newPropertyDef.getName(); - if (Objects.nonNull(propertiesMap.get(propertyName))) { - Object propValue = propertiesMap.get(propertyName); - newPropertyDef.setValue(PropertiesUtils.trimQuotes(gson.toJson(propValue))); - } - return newPropertyDef; + return propertiesJsonMap.entrySet().stream() + .map(propertyJson -> { + final PropertyDefinition originalProperty = + policyTypeDefinition.getProperties().stream() + .filter(propertyDefinition -> propertyDefinition.getName().equals(propertyJson.getKey())) + .findFirst() + .orElse(null); + if (originalProperty == null) { + return null; + } + final UploadPropInfo uploadPropInfo = buildProperty(propertyJson.getKey(), propertyJson.getValue()); + final PropertyDefinition propertyDefinition = new PropertyDefinition(originalProperty); + propertyDefinition.setToscaFunction(uploadPropInfo.getToscaFunction()); + propertyDefinition.setSubPropertyToscaFunctions(uploadPropInfo.getSubPropertyToscaFunctions()); + propertyDefinition.setGetInputValues(uploadPropInfo.getGet_input()); + propertyDefinition.setDescription(uploadPropInfo.getDescription()); + String propertyValue = gson.toJson(uploadPropInfo.getValue()); + if (!propertyDefinition.isToscaFunction()) { + propertyValue = PropertiesUtils.trimQuotes(propertyValue); + } + propertyDefinition.setValue(propertyValue); + return propertyDefinition; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } private Map> validateFillPolicyTargets(Map policyTemplateJson) { Map> targets = new EnumMap<>(PolicyTargetType.class); - if (policyTemplateJson.containsKey(TARGETS.getElementName()) - && policyTemplateJson.get(TARGETS.getElementName()) instanceof List ) { + if (policyTemplateJson.containsKey(TARGETS.getElementName()) && policyTemplateJson.get(TARGETS.getElementName()) instanceof List) { List targetsElement = (List) policyTemplateJson.get(TARGETS.getElementName()); targets.put(PolicyTargetType.COMPONENT_INSTANCES, targetsElement); } return targets; } - private Map getInstances(String yamlName, Map toscaJson, Map createdNodesToscaResourceNames) { - - Map nodeTemlates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES) - .left() - .on(err -> failIfNoNodeTemplates(yamlName)); - - return getInstances(toscaJson, createdNodesToscaResourceNames, nodeTemlates); + private Map getInstances( + Map toscaJson, + Map createdNodesToscaResourceNames + ) { + Map nodeTemplates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES) + .left().on(err -> new HashMap<>()); + if (nodeTemplates.isEmpty()) { + return Collections.emptyMap(); + } + return getInstances( + toscaJson, + createdNodesToscaResourceNames, + nodeTemplates + ); } - private Map getInstances(Map toscaJson, Map createdNodesToscaResourceNames, Map nodeTemlates) { - Map moduleComponentInstances; + private Map getInstances( + Map toscaJson, + Map createdNodesToscaResourceNames, + Map nodeTemplates + ) { Map substitutionMappings = getSubstitutionMappings(toscaJson); - moduleComponentInstances = nodeTemlates.entrySet() - .stream() - .map(node -> buildModuleComponentInstanceInfo(node, substitutionMappings, createdNodesToscaResourceNames)) - .collect(Collectors.toMap(UploadComponentInstanceInfo::getName, i -> i)); - return moduleComponentInstances; + return nodeTemplates.entrySet().stream() + .map(node -> buildModuleComponentInstanceInfo( + node, + substitutionMappings, + createdNodesToscaResourceNames + )) + .collect(Collectors.toMap(UploadComponentInstanceInfo::getName, i -> i)); } private Map getSubstitutionMappings(Map toscaJson) { - Map substitutionMappings = null; Either, ResultStatusEnum> eitherSubstitutionMappings = findFirstToscaMapElement(toscaJson, SUBSTITUTION_MAPPINGS); if (eitherSubstitutionMappings.isLeft()) { - substitutionMappings = eitherSubstitutionMappings.left().value(); + return eitherSubstitutionMappings.left().value(); } - return substitutionMappings; + return null; } - @SuppressWarnings("unchecked") - private Map getGroups(String fileName, Map toscaJson) { + private void associateRelationshipTemplatesToInstances(final Map instances, + final Map toscaJson) { + if (MapUtils.isEmpty(instances)) { + return; + } + for (UploadComponentInstanceInfo instance : instances.values()) { + final Map> operations = new HashMap<>(); + final Map> 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 getRelationshipTemplates(final Map toscaJson, final String relationshipTemplate) { + final Either, ResultStatusEnum> eitherRelationshipTemplates = findFirstToscaMapElement(toscaJson, RELATIONSHIP_TEMPLATES); + if (eitherRelationshipTemplates.isRight()) { + throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_NOT_FOUND); + } + final Map relationshipTemplateMap = eitherRelationshipTemplates.left().value(); + final Map> relationship = (Map>) relationshipTemplateMap.get(relationshipTemplate); + if (relationship == null) { + throw new ByActionStatusComponentException(ActionStatus.RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND); + } + return relationship.get(INTERFACES.getElementName()); + } - Map foundGroups = findFirstToscaMapElement(toscaJson, GROUPS) - .left() - .on(err -> logGroupsNotFound(fileName)); + private List buildToscaInterfacesFromRelationship(final Map interfaces) { + return interfaces.entrySet().stream() + .map(entry -> { + final var toscaInterfaceDefinition = new ToscaInterfaceDefinition(); + toscaInterfaceDefinition.setType(entry.getKey()); + final Map toscaInterfaceMap = (Map) entry.getValue(); + toscaInterfaceDefinition.setOperations((Map) toscaInterfaceMap.get(OPERATIONS.getElementName())); + return toscaInterfaceDefinition; + }) + .collect(toList()); + } + private Optional getImplementation(final Map operationToscaMap) { + if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(IMPLEMENTATION.getElementName())) { + return Optional.empty(); + } + return Optional.ofNullable(operationToscaMap.get(IMPLEMENTATION.getElementName())); + } + + private List getOperationsInputs(final Map operationToscaMap) { + if (MapUtils.isEmpty(operationToscaMap) || !operationToscaMap.containsKey(INPUTS.getElementName())) { + return Collections.emptyList(); + } + final Map inputsMap = (Map) operationToscaMap.get(INPUTS.getElementName()); + return inputsMap.entrySet().stream().map(this::buildInputAssignment).collect(toList()); + } + + private PropertyAssignmentUi buildInputAssignment(final Entry inputAssignmentMap) { + var propertyAssignmentUi = new PropertyAssignmentUi(); + propertyAssignmentUi.setName(inputAssignmentMap.getKey()); + propertyAssignmentUi.setValue(inputAssignmentMap.getValue().toString()); + propertyAssignmentUi.setType(STRING.getType()); + return propertyAssignmentUi; + } + + private List getOperationsFromRelationshipTemplate(final Map toscaJson, final String relationshipTemplate) { + final List operationUiList = new ArrayList<>(); + final List 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) operationValue)) + )); + return operationUiList; + } + + private OperationUi buildOperation(final String interfaceType, final String operationType, final Map operationToscaMap) { + var operationUi = new OperationUi(); + operationUi.setInterfaceType(interfaceType); + operationUi.setOperationType(operationType); + getImplementation(operationToscaMap).ifPresent(operationUi::setImplementation); + final List operationsInputs = getOperationsInputs(operationToscaMap); + if (CollectionUtils.isNotEmpty(operationsInputs)) { + operationUi.setInputs(operationsInputs); + } + return operationUi; + } + + @SuppressWarnings("unchecked") + private Map getGroups(Map toscaJson, String model) { + Map mappedTopologyTemplate = (Map) findToscaElement(toscaJson, TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL) + .left().on(err -> new HashMap<>()); + Map foundGroups = (Map) mappedTopologyTemplate.get(GROUPS.getElementName()); if (MapUtils.isNotEmpty(foundGroups)) { - Map groups = foundGroups - .entrySet() - .stream() - .map(this::createGroup) - .collect(Collectors.toMap(GroupDefinition::getName, g -> g)); + Map groups = foundGroups.entrySet().stream().map(groupToCreate -> createGroup(groupToCreate, model)) + .collect(Collectors.toMap(GroupDefinition::getName, g -> g)); Map substitutionMappings = getSubstitutionMappings(toscaJson); if (capabilitiesSubstitutionMappingsExist(substitutionMappings)) { - groups.entrySet().forEach(entry -> updateCapabilitiesNames(entry.getValue(), getNamesToUpdate(entry.getKey(), - (Map>) substitutionMappings.get(CAPABILITIES.getElementName())))); + groups.forEach((key, value) -> updateCapabilitiesNames(value, + getNamesToUpdate(key, (Map>) substitutionMappings.get(CAPABILITIES.getElementName())))); } return groups; } return new HashMap<>(); } - private Map logGroupsNotFound(String fileName) { - log.debug("#logGroupsNotFound - Groups were not found in the yaml template {}.", fileName); - return new HashMap<>(); - } - private void updateCapabilitiesNames(GroupDefinition group, Map capabilityNames) { if (MapUtils.isNotEmpty(group.getCapabilities())) { - group.getCapabilities().values() - .stream() - .flatMap(Collection::stream) - .filter(cap -> capabilityNames.containsKey(cap.getName())) - .forEach(cap -> cap.setName(capabilityNames.get(cap.getName()))); + group.getCapabilities().values().stream().flatMap(Collection::stream).filter(cap -> capabilityNames.containsKey(cap.getName())) + .forEach(cap -> cap.setName(capabilityNames.get(cap.getName()))); } } private Map getNamesToUpdate(String name, Map> pair) { - return pair.entrySet().stream() - .filter(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX).equalsIgnoreCase(name)) - .collect(Collectors.toMap(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_NAME_IDX), Map.Entry::getKey, (n1 ,n2) -> n1)); + return pair.entrySet().stream().filter(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX).equalsIgnoreCase(name)) + .collect(Collectors.toMap(e -> e.getValue().get(SUB_MAPPING_CAPABILITY_NAME_IDX), Map.Entry::getKey, (n1, n2) -> n1)); } private boolean capabilitiesSubstitutionMappingsExist(Map substitutionMappings) { return substitutionMappings != null && substitutionMappings.containsKey(CAPABILITIES.getElementName()); } - private GroupDefinition createGroup(Map.Entry groupNameValue) { + private GroupDefinition createGroup(Map.Entry groupNameValue, String model) { GroupDefinition group = new GroupDefinition(); group.setName(groupNameValue.getKey()); try { - if (groupNameValue.getValue() != null && groupNameValue.getValue() instanceof Map) { + if (groupNameValue.getValue() instanceof Map) { Map groupTemplateJsonMap = (Map) groupNameValue.getValue(); - validateAndFillGroup(group, groupTemplateJsonMap); + validateAndFillGroup(group, groupTemplateJsonMap, model); validateUpdateGroupProperties(group, groupTemplateJsonMap); validateUpdateGroupCapabilities(group, groupTemplateJsonMap); } else { rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); } } catch (ClassCastException e) { - log.debug("#createGroup - Failed to create the group {}. The exception occure", groupNameValue.getKey(), e); + log.debug("#createGroup - Failed to create the group {}. The exception occurres", groupNameValue.getKey(), e); rollbackWithException(ActionStatus.INVALID_YAML); } return group; @@ -406,43 +626,35 @@ public class YamlTemplateParsingHandler { } private void setMembersFromList(GroupDefinition groupInfo, List membersAsList) { - groupInfo.setMembers(membersAsList - .stream() - .collect(Collectors.toMap(Object::toString, member -> ""))); + groupInfo.setMembers(membersAsList.stream().collect(Collectors.toMap(Object::toString, member -> ""))); } @SuppressWarnings("unchecked") private void validateUpdateGroupProperties(GroupDefinition groupInfo, Map groupTemplateJsonMap) { if (groupTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { Object propertiesElement = groupTemplateJsonMap.get(PROPERTIES.getElementName()); - if (propertiesElement instanceof Map){ + if (propertiesElement instanceof Map) { mergeGroupProperties(groupInfo, (Map) propertiesElement); } } } - private void mergeGroupProperties(GroupDefinition groupInfo, Map parsedProperties) { - if(CollectionUtils.isNotEmpty(groupInfo.getProperties())){ - validateGroupProperties(parsedProperties, groupInfo); - groupInfo.getProperties().forEach(p -> mergeGroupProperty(p, parsedProperties)); - } - } - - private void mergeGroupProperty(PropertyDataDefinition property, Map parsedProperties) { - if(parsedProperties.containsKey(property.getName())){ - Object propValue = parsedProperties.get(property.getName()); - if (valueNotContainsPattern(propertyValuePattern, propValue)) { - setPropertyValueAndGetInputsValues(property, propValue); - } + private void mergeGroupProperties(final GroupDefinition groupDefinition, final Map parsedProperties) { + if (CollectionUtils.isEmpty(groupDefinition.getProperties())) { + return; } + validateGroupProperties(parsedProperties, groupDefinition); + groupDefinition.getProperties().stream() + .filter(property -> parsedProperties.containsKey(property.getName())) + .forEach(property -> mergeGroupProperty(property, parsedProperties.get(property.getName()))); } - private void setPropertyValueAndGetInputsValues(PropertyDataDefinition property, Object propValue) { - if(propValue != null){ - UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propValue); - property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue())); - property.setGetInputValues(uploadPropInfo.getGet_input()); - } + private void mergeGroupProperty(final PropertyDataDefinition property, final Object propertyYaml) { + final UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propertyYaml); + property.setToscaFunction(uploadPropInfo.getToscaFunction()); + property.setSubPropertyToscaFunctions(uploadPropInfo.getSubPropertyToscaFunctions()); + property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue())); + property.setGetInputValues(uploadPropInfo.getGet_input()); } private String convertPropertyValue(ToscaPropertyType type, Object value) { @@ -459,19 +671,18 @@ public class YamlTemplateParsingHandler { private void setDescription(GroupDefinition groupInfo, Map groupTemplateJsonMap) { if (groupTemplateJsonMap.containsKey(DESCRIPTION.getElementName())) { - groupInfo.setDescription( - (String) groupTemplateJsonMap.get(DESCRIPTION.getElementName())); + groupInfo.setDescription((String) groupTemplateJsonMap.get(DESCRIPTION.getElementName())); } } - private void validateAndFillGroup(GroupDefinition groupInfo, Map groupTemplateJsonMap) { + private void validateAndFillGroup(GroupDefinition groupInfo, Map groupTemplateJsonMap, String model) { String type = (String) groupTemplateJsonMap.get(TYPE.getElementName()); - if(StringUtils.isEmpty(type)){ + if (StringUtils.isEmpty(type)) { log.debug("#validateAndFillGroup - The 'type' member is not found under group {}", groupInfo.getName()); rollbackWithException(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupInfo.getName()); } groupInfo.setType(type); - GroupTypeDefinition groupType = groupTypeBusinessLogic.getLatestGroupTypeByType(type); + GroupTypeDefinition groupType = groupTypeBusinessLogic.getLatestGroupTypeByType(type, model); if (groupType == null) { log.debug("#validateAndFillGroup - The group type {} not found", groupInfo.getName()); rollbackWithException(ActionStatus.GROUP_TYPE_IS_INVALID, type); @@ -484,17 +695,14 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private void validateUpdateGroupCapabilities(GroupDefinition groupInfo, Map groupTemplateJsonMap) { - if (groupTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) { Object capabilities = groupTemplateJsonMap.get(CAPABILITIES.getElementName()); if (capabilities instanceof List) { - validateUpdateCapabilities(groupInfo, ((List) capabilities).stream() - .map(o -> buildGroupCapability(groupInfo, o)) - .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities))); + validateUpdateCapabilities(groupInfo, ((List) capabilities).stream().map(o -> buildGroupCapability(groupInfo, o)) + .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities))); } else if (capabilities instanceof Map) { - validateUpdateCapabilities(groupInfo, ((Map) capabilities).entrySet() - .stream() - .map(e -> buildGroupCapability(groupInfo, e)) + validateUpdateCapabilities(groupInfo, + ((Map) capabilities).entrySet().stream().map(e -> buildGroupCapability(groupInfo, e)) .collect(Collectors.toMap(CapabilityDefinition::getType, this::addCapability, this::addCapabilities))); } else { log.debug("#setCapabilities - Failed to import the capabilities of the group {}. ", groupInfo.getName()); @@ -513,7 +721,8 @@ public class YamlTemplateParsingHandler { if (MapUtils.isEmpty(group.getCapabilities())) { failOnMissingCapabilityTypes(group, Lists.newArrayList(parsedCapabilities.keySet())); } - List missingCapTypes = parsedCapabilities.keySet().stream().filter(ct -> !group.getCapabilities().containsKey(ct)).collect(toList()); + List missingCapTypes = parsedCapabilities.keySet().stream().filter(ct -> !group.getCapabilities().containsKey(ct)) + .collect(toList()); if (CollectionUtils.isNotEmpty(missingCapTypes)) { failOnMissingCapabilityTypes(group, missingCapTypes); } @@ -521,7 +730,8 @@ public class YamlTemplateParsingHandler { } } - private void validateCapabilities(GroupDefinition group, List capabilities, Map parsedCapabilities) { + private void validateCapabilities(GroupDefinition group, List capabilities, + Map parsedCapabilities) { List allowedCapNames = capabilities.stream().map(CapabilityDefinition::getName).distinct().collect(toList()); List missingCapNames = parsedCapabilities.keySet().stream().filter(c -> !allowedCapNames.contains(c)).collect(toList()); if (CollectionUtils.isNotEmpty(missingCapNames)) { @@ -535,33 +745,32 @@ public class YamlTemplateParsingHandler { } private void validateCapabilityProperties(CapabilityDefinition capability, CapabilityDefinition parsedCapability) { - if(parsedCapability != null && parsedCapability.getProperties() != null){ - List parsedPropertiesNames = parsedCapability.getProperties() - .stream() - .map(ComponentInstanceProperty::getName).collect(toList()); - validateProperties(capability.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, ActionStatus.PROPERTY_NOT_FOUND, capability.getName(), capability.getType()); + if (parsedCapability != null && parsedCapability.getProperties() != null) { + List parsedPropertiesNames = parsedCapability.getProperties().stream().map(ComponentInstanceProperty::getName).collect(toList()); + validateProperties(capability.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, + ActionStatus.PROPERTY_NOT_FOUND, capability.getName(), capability.getType()); } } - private void validateGroupProperties(Map parsedProperties, GroupDefinition groupInfo) { - List parsedPropertiesNames = parsedProperties.entrySet() - .stream() - .map(Map.Entry::getKey).collect(toList()); - validateProperties(groupInfo.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, ActionStatus.GROUP_PROPERTY_NOT_FOUND, groupInfo.getName(), groupInfo.getType()); + private void validateGroupProperties(Map parsedProperties, GroupDefinition groupInfo) { + List parsedPropertiesNames = new ArrayList<>(parsedProperties.keySet()); + validateProperties(groupInfo.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, + ActionStatus.GROUP_PROPERTY_NOT_FOUND, groupInfo.getName(), groupInfo.getType()); } - private void validateProperties(List validProperties, List parsedProperties, ActionStatus actionStatus, String name, String type) { + private void validateProperties(List validProperties, List parsedProperties, ActionStatus actionStatus, String name, + String type) { if (CollectionUtils.isNotEmpty(parsedProperties)) { - verifyMissingProperties(actionStatus, name, type, parsedProperties - .stream() - .filter(n -> !validProperties.contains(n)) - .collect(toList())); + verifyMissingProperties(actionStatus, name, type, parsedProperties.stream().filter(n -> !validProperties.contains(n)).collect(toList())); } } private void verifyMissingProperties(ActionStatus actionStatus, String name, String type, List missingProperties) { if (CollectionUtils.isNotEmpty(missingProperties)) { - log.debug("#validateProperties - Failed to validate properties. The properties {} are missing on {} of the type {}. ", missingProperties.toString(), name, type); + if (log.isDebugEnabled()) { + log.debug("#validateProperties - Failed to validate properties. The properties {} are missing on {} of the type {}. ", + missingProperties.toString(), name, type); + } rollbackWithException(actionStatus, missingProperties.toString(), missingProperties.toString(), name, type); } } @@ -611,9 +820,10 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private UploadComponentInstanceInfo buildModuleComponentInstanceInfo( - Map.Entry nodeTemplateJsonEntry, Map substitutionMappings, - Map createdNodesToscaResourceNames) { - + Map.Entry nodeTemplateJsonEntry, + Map substitutionMappings, + Map createdNodesToscaResourceNames + ) { UploadComponentInstanceInfo nodeTemplateInfo = new UploadComponentInstanceInfo(); nodeTemplateInfo.setName(nodeTemplateJsonEntry.getKey()); try { @@ -627,9 +837,12 @@ public class YamlTemplateParsingHandler { setCapabilities(nodeTemplateInfo, nodeTemplateJsonMap); setArtifacts(nodeTemplateInfo, nodeTemplateJsonMap); updateProperties(nodeTemplateInfo, nodeTemplateJsonMap); + updateAttributes(nodeTemplateInfo, nodeTemplateJsonMap); + updateInterfaces(nodeTemplateInfo, nodeTemplateJsonMap); setDirectives(nodeTemplateInfo, nodeTemplateJsonMap); setNodeFilter(nodeTemplateInfo, nodeTemplateJsonMap); setSubstitutions(substitutionMappings, nodeTemplateInfo); + setOccurrencesAndInstanceCount(nodeTemplateInfo, nodeTemplateJsonMap); } else { rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); } @@ -645,26 +858,49 @@ public class YamlTemplateParsingHandler { private void setSubstitutions(Map substitutionMappings, UploadComponentInstanceInfo nodeTemplateInfo) { if (substitutionMappings != null) { if (substitutionMappings.containsKey(CAPABILITIES.getElementName())) { - nodeTemplateInfo.setCapabilitiesNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(), (Map>) substitutionMappings - .get(CAPABILITIES.getElementName()))); + nodeTemplateInfo.setCapabilitiesNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(), + (Map>) substitutionMappings.get(CAPABILITIES.getElementName()))); } if (substitutionMappings.containsKey(REQUIREMENTS.getElementName())) { - nodeTemplateInfo.setRequirementsNamesToUpdate(getNamesToUpdate( - nodeTemplateInfo.getName(), (Map>) substitutionMappings - .get(REQUIREMENTS.getElementName()))); + nodeTemplateInfo.setRequirementsNamesToUpdate(getNamesToUpdate(nodeTemplateInfo.getName(), + (Map>) substitutionMappings.get(REQUIREMENTS.getElementName()))); } } } private void updateProperties(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map> properties = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map> properties = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!properties.isEmpty()) { nodeTemplateInfo.setProperties(properties); } } } + private void updateAttributes(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + if (nodeTemplateJsonMap.containsKey(ATTRIBUTES.getElementName())) { + Map attributes = buildAttributeModuleFromYaml(nodeTemplateJsonMap); + if (!attributes.isEmpty()) { + nodeTemplateInfo.setAttributes(attributes); + } + } + } + + private void updateInterfaces( + UploadComponentInstanceInfo nodeTemplateInfo, + Map nodeTemplateJsonMap + ) { + if (nodeTemplateJsonMap.containsKey(INTERFACES.getElementName())) { + Map interfaces = buildInterfacesModuleFromYaml( + nodeTemplateJsonMap + ); + if (!interfaces.isEmpty()) { + nodeTemplateInfo.setInterfaces(interfaces); + } + } + } + private void setCapabilities(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) { Map> eitherCapRes = createCapModuleFromYaml(nodeTemplateJsonMap); @@ -685,15 +921,15 @@ public class YamlTemplateParsingHandler { private void setRequirements(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(REQUIREMENTS.getElementName())) { - Map> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap); + Map> regResponse = createReqModuleFromYaml(nodeTemplateJsonMap, nodeTemplateInfo.getName()); if (!regResponse.isEmpty()) { nodeTemplateInfo.setRequirements(regResponse); } } } - private void setToscaResourceType(Map createdNodesToscaResourceNames, - UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + private void setToscaResourceType(Map createdNodesToscaResourceNames, UploadComponentInstanceInfo nodeTemplateInfo, + Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(TYPE.getElementName())) { String toscaResourceType = (String) nodeTemplateJsonMap.get(TYPE.getElementName()); if (createdNodesToscaResourceNames.containsKey(toscaResourceType)) { @@ -703,51 +939,62 @@ public class YamlTemplateParsingHandler { } } - private void setDirectives(UploadComponentInstanceInfo nodeTemplateInfo, - Map nodeTemplateJsonMap) { - List directives = - (List) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.DIRECTIVES.getElementName()); + private void setDirectives(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + List directives = (List) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.DIRECTIVES.getElementName()); nodeTemplateInfo.setDirectives(directives); } - private void setNodeFilter(UploadComponentInstanceInfo nodeTemplateInfo, - Map nodeTemplateJsonMap) { + private void setNodeFilter(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName())) { - nodeTemplateInfo.setUploadNodeFilterInfo( - new NodeFilterUploadCreator().createNodeFilterData(nodeTemplateJsonMap.get( - TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName()))); + nodeTemplateInfo.setUploadNodeFilterInfo(new NodeFilterUploadCreator() + .createNodeFilterData(nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName()))); } } @SuppressWarnings("unchecked") - private Map> createReqModuleFromYaml(Map nodeTemplateJsonMap) { - Map> moduleRequirements = new HashMap<>(); - Either, ResultStatusEnum> requirementsListRes = - findFirstToscaListElement(nodeTemplateJsonMap, REQUIREMENTS); + private void setOccurrencesAndInstanceCount(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) { + List occurrences = (List) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName()); + nodeTemplateInfo.setMinOccurrences(occurrences.get(0).toString()); + nodeTemplateInfo.setMaxOccurrences(occurrences.get(1).toString()); + } + if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.INSTANCE_COUNT.getElementName())) { + Object instanceCount = nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.INSTANCE_COUNT.getElementName()); + if (instanceCount instanceof Map) { + String instanceCountAsString = "{get_input:" + (String)((Map)instanceCount).get("get_input") + "}"; + nodeTemplateInfo.setInstanceCount(instanceCountAsString); + } else { + nodeTemplateInfo.setInstanceCount(instanceCount.toString()); + } + } + } + @SuppressWarnings("unchecked") + private Map> createReqModuleFromYaml(Map nodeTemplateJsonMap, String nodeName) { + Map> moduleRequirements = new HashMap<>(); + Either, ResultStatusEnum> requirementsListRes = findFirstToscaListElement(nodeTemplateJsonMap, REQUIREMENTS); if (requirementsListRes.isLeft()) { for (Object jsonReqObj : requirementsListRes.left().value()) { String reqName = ((Map) jsonReqObj).keySet().iterator().next(); Object reqJson = ((Map) jsonReqObj).get(reqName); - addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName); + addModuleNodeTemplateReq(moduleRequirements, reqJson, reqName, nodeName); } } else { - Either, ResultStatusEnum> requirementsMapRes = - findFirstToscaMapElement(nodeTemplateJsonMap, REQUIREMENTS); + Either, ResultStatusEnum> requirementsMapRes = findFirstToscaMapElement(nodeTemplateJsonMap, REQUIREMENTS); if (requirementsMapRes.isLeft()) { for (Map.Entry 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> moduleRequirements, Object requirementJson, String requirementName) { - - UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson); + private void addModuleNodeTemplateReq(Map> moduleRequirements, Object requirementJson, String requirementName, + String nodeName) { + UploadReqInfo requirement = buildModuleNodeTemplateReg(requirementJson, nodeName); requirement.setName(requirementName); if (moduleRequirements.containsKey(requirementName)) { moduleRequirements.get(requirementName).add(requirement); @@ -761,19 +1008,17 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private Map> createArtifactsModuleFromYaml(Map nodeTemplateJsonMap) { Map> moduleArtifacts = new HashMap<>(); - Either, ResultStatusEnum> ArtifactsListRes = - findFirstToscaListElement(nodeTemplateJsonMap, ARTIFACTS); - if (ArtifactsListRes.isLeft()) { - for (Object jsonArtifactObj : ArtifactsListRes.left().value()) { + Either, ResultStatusEnum> artifactsListRes = findFirstToscaListElement(nodeTemplateJsonMap, ARTIFACTS); + if (artifactsListRes.isLeft()) { + for (Object jsonArtifactObj : artifactsListRes.left().value()) { String key = ((Map) jsonArtifactObj).keySet().iterator().next(); Object artifactJson = ((Map) jsonArtifactObj).get(key); addModuleNodeTemplateArtifacts(moduleArtifacts, artifactJson, key); } } else { - Either>, ResultStatusEnum> ArtifactsMapRes = - findFirstToscaMapElement(nodeTemplateJsonMap, ARTIFACTS); - if (ArtifactsMapRes.isLeft()) { - for (Map.Entry> entry : ArtifactsMapRes.left().value().entrySet()) { + Either>, ResultStatusEnum> artifactsMapRes = findFirstToscaMapElement(nodeTemplateJsonMap, ARTIFACTS); + if (artifactsMapRes.isLeft()) { + for (Map.Entry> entry : artifactsMapRes.left().value().entrySet()) { String artifactName = entry.getKey(); Object artifactJson = entry.getValue(); addModuleNodeTemplateArtifacts(moduleArtifacts, artifactJson, artifactName); @@ -783,8 +1028,8 @@ public class YamlTemplateParsingHandler { return moduleArtifacts; } - private void addModuleNodeTemplateArtifacts(Map> moduleArtifacts, Object artifactJson, String artifactName) { - + private void addModuleNodeTemplateArtifacts(Map> moduleArtifacts, Object artifactJson, + String artifactName) { UploadArtifactInfo artifact = buildModuleNodeTemplateArtifact(artifactJson); artifact.setName(artifactName); if (moduleArtifacts.containsKey(ARTIFACTS.getElementName())) { @@ -812,36 +1057,31 @@ public class YamlTemplateParsingHandler { if (nodeTemplateJsonMap.containsKey(FILE.getElementName())) { artifactTemplateInfo.setFile((String) nodeTemplateJsonMap.get(FILE.getElementName())); } + if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { + Map> props = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); + if (!props.isEmpty()) { + List properties = props.values().stream().flatMap(Collection::stream).collect(toList()); + artifactTemplateInfo.setProperties(properties); + } + } } - @SuppressWarnings("unchecked") private Map> createCapModuleFromYaml(Map nodeTemplateJsonMap) { Map> moduleCap = new HashMap<>(); - Either, ResultStatusEnum> capabilitiesListRes = - findFirstToscaListElement(nodeTemplateJsonMap, CAPABILITIES); - if (capabilitiesListRes.isLeft()) { - for (Object jsonCapObj : capabilitiesListRes.left().value()) { - String key = ((Map) jsonCapObj).keySet().iterator().next(); - Object capJson = ((Map) jsonCapObj).get(key); - addModuleNodeTemplateCap(moduleCap, capJson, key); - } - } else { - Either, ResultStatusEnum> capabilitiesMapRes = - findFirstToscaMapElement(nodeTemplateJsonMap, CAPABILITIES); - if (capabilitiesMapRes.isLeft()) { - for (Map.Entry entry : capabilitiesMapRes.left().value().entrySet()) { - String capName = entry.getKey(); - Object capJson = entry.getValue(); - addModuleNodeTemplateCap(moduleCap, capJson, capName); - } + Map capabilities = (Map) nodeTemplateJsonMap.get(CAPABILITIES.getElementName()); + if (MapUtils.isNotEmpty(capabilities)) { + for (Map.Entry entry : capabilities.entrySet()) { + String capName = entry.getKey(); + Object capJson = entry.getValue(); + addModuleNodeTemplateCap(moduleCap, capJson, capName); } } return moduleCap; } private void addModuleNodeTemplateCap(Map> moduleCap, Object capJson, String key) { - UploadCapInfo capabilityDef = buildModuleNodeTemplateCap(capJson); capabilityDef.setKey(key); if (moduleCap.containsKey(key)) { @@ -856,7 +1096,6 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private UploadCapInfo buildModuleNodeTemplateCap(Object capObject) { UploadCapInfo capTemplateInfo = new UploadCapInfo(); - if (capObject instanceof String) { String nodeTemplateJsonString = (String) capObject; capTemplateInfo.setNode(nodeTemplateJsonString); @@ -874,15 +1113,14 @@ public class YamlTemplateParsingHandler { capTemplateInfo.setType((String) nodeTemplateJsonMap.get(TYPE.getElementName())); } if (nodeTemplateJsonMap.containsKey(VALID_SOURCE_TYPES.getElementName())) { - Either, ResultStatusEnum> validSourceTypesRes = - findFirstToscaListElement(nodeTemplateJsonMap, VALID_SOURCE_TYPES); + Either, ResultStatusEnum> validSourceTypesRes = findFirstToscaListElement(nodeTemplateJsonMap, VALID_SOURCE_TYPES); if (validSourceTypesRes.isLeft()) { - capTemplateInfo.setValidSourceTypes(validSourceTypesRes.left().value().stream() - .map(Object::toString).collect(toList())); + capTemplateInfo.setValidSourceTypes(validSourceTypesRes.left().value().stream().map(Object::toString).collect(toList())); } } if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map> props = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map> props = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!props.isEmpty()) { List properties = props.values().stream().flatMap(Collection::stream).collect(toList()); capTemplateInfo.setProperties(properties); @@ -891,8 +1129,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; @@ -903,29 +1140,59 @@ public class YamlTemplateParsingHandler { regTemplateInfo.setNode((String) nodeTemplateJsonMap.get(NODE.getElementName())); } if (nodeTemplateJsonMap.containsKey(CAPABILITY.getElementName())) { - regTemplateInfo.setCapabilityName( - (String) nodeTemplateJsonMap.get(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; } - private Map> buildPropModuleFromYaml(Map nodeTemplateJsonMap) { - - Map> moduleProp = new HashMap<>(); - Either, ResultStatusEnum> toscaProperties = - findFirstToscaMapElement(nodeTemplateJsonMap, PROPERTIES); - if (toscaProperties.isLeft()) { - Map jsonProperties = toscaProperties.left().value(); - for (Map.Entry jsonPropObj : jsonProperties.entrySet()) { - if (valueNotContainsPattern(propertyValuePattern, jsonPropObj.getValue())) { - addProperty(moduleProp, jsonPropObj); - } + private Map buildAttributeModuleFromYaml( + Map nodeTemplateJsonMap) { + Map moduleAttribute = new HashMap<>(); + Either, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(nodeTemplateJsonMap, ATTRIBUTES); + if (toscaAttributes.isLeft()) { + Map jsonAttributes = toscaAttributes.left().value(); + for (Map.Entry jsonAttributeObj : jsonAttributes.entrySet()) { + UploadAttributeInfo attributeDef = buildAttribute(jsonAttributeObj.getKey(), jsonAttributeObj.getValue()); + moduleAttribute.put(attributeDef.getName(), attributeDef); } } + return moduleAttribute; + } + + private UploadAttributeInfo buildAttribute(String attributeName, Object attributeValue) { + UploadAttributeInfo attributeDef = new UploadAttributeInfo(); + attributeDef.setValue(attributeValue); + attributeDef.setName(attributeName); + return attributeDef; + } + + private Map> buildPropModuleFromYaml(final Map propertyMap) { + final Map> moduleProp = new HashMap<>(); + propertyMap.entrySet().forEach(propertyMapEntry -> addProperty(moduleProp, propertyMapEntry)); return moduleProp; } + private Map buildInterfacesModuleFromYaml( + Map nodeTemplateJsonMap + ) { + Map moduleInterfaces = new HashMap<>(); + Either, ResultStatusEnum> toscaInterfaces = findFirstToscaMapElement(nodeTemplateJsonMap, INTERFACES); + if (toscaInterfaces.isLeft()) { + Map jsonInterfaces = toscaInterfaces.left().value(); + for (Map.Entry jsonInterfacesObj : jsonInterfaces.entrySet()) { + addInterfaces(moduleInterfaces, jsonInterfacesObj); + } + } + return moduleInterfaces; + } + private void addProperty(Map> moduleProp, Map.Entry jsonPropObj) { UploadPropInfo propertyDef = buildProperty(jsonPropObj.getKey(), jsonPropObj.getValue()); if (moduleProp.containsKey(propertyDef.getName())) { @@ -937,58 +1204,262 @@ public class YamlTemplateParsingHandler { } } - @SuppressWarnings("unchecked") - private UploadPropInfo buildProperty(String propName, Object propValue) { + private void addInterfaces(Map moduleInterface, Map.Entry jsonPropObj) { + UploadInterfaceInfo interfaceInfo = buildInterface(jsonPropObj.getKey(), jsonPropObj.getValue()); + moduleInterface.put(jsonPropObj.getKey(), interfaceInfo); + } - UploadPropInfo propertyDef = new UploadPropInfo(); - propertyDef.setValue(propValue); + @SuppressWarnings("unchecked") + private UploadPropInfo buildProperty(String propName, Object propValueObj) { + final var propertyDef = new UploadPropInfo(); + propertyDef.setValue(propValueObj); propertyDef.setName(propName); - if (propValue instanceof Map) { - if (((Map) propValue).containsKey(TYPE.getElementName())) { - propertyDef.setType(((Map) propValue) - .get(TYPE.getElementName()).toString()); + if (propValueObj instanceof Map) { + final Map propValueMap = (Map) propValueObj; + if (propValueMap.containsKey(TYPE.getElementName())) { + propertyDef.setType(propValueMap.get(TYPE.getElementName()).toString()); + } + if (containsGetInput(propValueObj)) { + fillInputRecursively(propName, propValueMap, propertyDef); } - if (containsGetInput(propValue)) { - fillInputRecursively(propName, (Map) propValue, propertyDef); + if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(propValueObj)) { + toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(propValueMap).ifPresent(propertyDef::setToscaFunction); + } else { + final Collection subPropertyToscaFunctions = + buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>()); + if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) { + Collection existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions(); + if (existingSubPropertyToscaFunctions == null) { + propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions); + } else { + propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions); + } + } } + if (propValueMap.containsKey(DESCRIPTION.getElementName())) { + propertyDef.setDescription((propValueMap).get(DESCRIPTION.getElementName()).toString()); + } + if (propValueMap.containsKey(DEFAULT_VALUE.getElementName())) { + propertyDef.setValue(propValueMap.get(DEFAULT_VALUE.getElementName())); + } + if (propValueMap.containsKey(IS_PASSWORD.getElementName())) { + propertyDef.setPassword(Boolean.getBoolean(propValueMap.get(IS_PASSWORD.getElementName()).toString())); + } else { + propertyDef.setValue(propValueObj); + } + } else if (propValueObj instanceof List) { + fillInputsListRecursively(propertyDef, (List) propValueObj); + propertyDef.setValue(propValueObj); + } + return propertyDef; + } - if (((Map) propValue).containsKey(DESCRIPTION.getElementName())) { - propertyDef.setDescription(((Map) propValue) - .get(DESCRIPTION.getElementName()).toString()); + private Collection buildSubPropertyToscaFunctions(final Map propValueMap, final List path) { + Collection subPropertyToscaFunctions = new ArrayList<>(); + propValueMap.entrySet().stream().filter(entry -> entry.getValue() instanceof Map).forEach(entry -> { + List subPropertyPath = new ArrayList<>(path); + subPropertyPath.add(entry.getKey()); + if (ToscaFunctionType.findType(((Map) entry.getValue()).keySet().iterator().next()).isPresent()) { + Optional toscaFunction = + toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map) entry.getValue()); + if (toscaFunction.isPresent()) { + SubPropertyToscaFunction subPropertyToscaFunction = new SubPropertyToscaFunction(); + subPropertyToscaFunction.setToscaFunction(toscaFunction.get()); + subPropertyToscaFunction.setSubPropertyPath(subPropertyPath); + subPropertyToscaFunctions.add(subPropertyToscaFunction); + } + } else { + subPropertyToscaFunctions.addAll(buildSubPropertyToscaFunctions((Map) entry.getValue(), subPropertyPath)); + } + }); + return subPropertyToscaFunctions; + } + + private UploadInterfaceInfo buildInterface(String interfaceName, Object interfaceValue) { + UploadInterfaceInfo interfaceDef = new UploadInterfaceInfo(); + interfaceDef.setValue(interfaceValue); + interfaceDef.setName(interfaceName); + interfaceDef.setKey(interfaceName); + Map operations = new HashMap<>(); + if (interfaceValue instanceof Map) { + Map operationsMap = (Map) interfaceValue; + for (Map.Entry operationEntry : operationsMap.entrySet()) { + OperationDataDefinition operationDef = new OperationDataDefinition(); + operationDef.setName(operationEntry.getKey()); + Map operationValue = (Map) operationEntry.getValue(); + if (operationValue.containsKey(DESCRIPTION.getElementName())) { + operationDef.setDescription(operationValue.get(DESCRIPTION.getElementName()).toString()); + } + operationDef.setImplementation(handleOperationImplementation(operationValue).orElse(new ArtifactDataDefinition())); + if (operationValue.containsKey(INPUTS.getElementName())) { + final Map interfaceInputs = (Map) operationValue.get(INPUTS.getElementName()); + operationDef.setInputs(handleInterfaceOperationInputs(interfaceInputs)); + } + operations.put(operationEntry.getKey(), operationDef); } - if (((Map) propValue) - .containsKey(DEFAULT_VALUE.getElementName())) { - propertyDef.setValue(((Map) propValue) - .get(DEFAULT_VALUE.getElementName())); + interfaceDef.setOperations(operations); + if (operationsMap.containsKey(TYPE.getElementName())) { + interfaceDef.setType(((Map) interfaceValue).get(TYPE.getElementName()).toString()); } - if (((Map) propValue).containsKey(IS_PASSWORD.getElementName())) { - propertyDef.setPassword(Boolean.getBoolean(((Map) propValue) - .get(IS_PASSWORD.getElementName()).toString())); + } + return interfaceDef; + } + + private ListDataDefinition handleInterfaceOperationInputs(final Map interfaceInputs) { + final ListDataDefinition inputs = new ListDataDefinition<>(); + for (final Entry interfaceInput : interfaceInputs.entrySet()) { + final OperationInputDefinition operationInput = new OperationInputDefinition(); + operationInput.setUniqueId(UUID.randomUUID().toString()); + operationInput.setInputId(operationInput.getUniqueId()); + operationInput.setName(interfaceInput.getKey()); + + handleInputToscaDefinition(interfaceInput.getKey(), interfaceInput.getValue(), operationInput); + inputs.add(operationInput); + } + return inputs; + } + + private void handleInputToscaDefinition( + final String inputName, + final Object value, + final OperationInputDefinition operationInput + ) { + if (value instanceof Map) { + final Map valueMap = (Map) value; + log.debug("Creating interface operation input '{}'", inputName); + Type type = new TypeToken>() { + }.getType(); + String stringValue = gson.toJson(value, type); + if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(value)) { + toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map) value) + .ifPresent(operationInput::setToscaFunction); } else { - propertyDef.setValue(propValue); + final Collection subPropertyToscaFunctions = buildSubPropertyToscaFunctions(valueMap, new ArrayList<>()); + if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) { + Collection existingSubPropertyToscaFunctions = operationInput.getSubPropertyToscaFunctions(); + if (existingSubPropertyToscaFunctions == null) { + operationInput.setSubPropertyToscaFunctions(subPropertyToscaFunctions); + } else { + operationInput.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions); + } + } } - } else if (propValue instanceof List) { - List propValueList = (List) propValue; + operationInput.setValue(stringValue); + } + if (value instanceof String) { + final String stringValue = (String) value; + operationInput.setDefaultValue(stringValue); + operationInput.setToscaDefaultValue(stringValue); + operationInput.setValue(stringValue); + } + operationInput.setType("string"); + if (operationInput.getValue() == null) { + operationInput.setValue(String.valueOf(value)); + } + } - fillInputsListRecursively(propertyDef, propValueList); - propertyDef.setValue(propValue); + private Optional handleOperationImplementation( + final Map operationDefinitionMap + ) { + if (!operationDefinitionMap.containsKey(IMPLEMENTATION.getElementName())) { + return Optional.empty(); } + final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition(); + if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof Map && + ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).containsKey("primary")) { - return propertyDef; + final Object primary = ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).get("primary"); + if (primary instanceof Map) { + Map implDetails = (Map) primary; + + if (implDetails.get("file") != null) { + final String file = implDetails.get("file").toString(); + artifactDataDefinition.setArtifactName(generateArtifactName(file)); + } + if (implDetails.get("type") != null) { + artifactDataDefinition.setArtifactType(implDetails.get("type").toString()); + } + if (implDetails.get("artifact_version") != null) { + artifactDataDefinition.setArtifactVersion(implDetails.get("artifact_version").toString()); + } + + if (implDetails.get("properties") instanceof Map) { + Map properties = (Map) implDetails.get("properties"); + properties.forEach((k, v) -> { + ToscaPropertyType type = getTypeFromObject(v); + if (type != null) { + PropertyDataDefinition propertyDef = new PropertyDataDefinition(); + propertyDef.setName(k); + propertyDef.setValue(v.toString()); + artifactDataDefinition.addProperty(propertyDef); + } + }); + } + } else { + artifactDataDefinition.setArtifactName(generateArtifactName(primary.toString())); + } + } + + if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof Map && + ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).containsKey("timeout")) { + final Object timeOut = ((Map) operationDefinitionMap.get(IMPLEMENTATION.getElementName())).get("timeout"); + artifactDataDefinition.setTimeout((Integer)timeOut); + } + + if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof String) { + final String implementation = (String) operationDefinitionMap.get(IMPLEMENTATION.getElementName()); + artifactDataDefinition.setArtifactName(generateArtifactName(implementation)); + } + return Optional.of(artifactDataDefinition); + } + + private String generateArtifactName(final String name) { + if (OperationArtifactUtil.artifactNameIsALiteralValue(name)) { + return name; + } else { + return QUOTE + name + QUOTE; + } + } + + private ToscaPropertyType getTypeFromObject(final Object value) { + if (value instanceof String) { + return ToscaPropertyType.STRING; + } + if (value instanceof Integer) { + return ToscaPropertyType.INTEGER; + } + if (value instanceof Boolean) { + return ToscaPropertyType.BOOLEAN; + } + if (value instanceof Float || value instanceof Double) { + return ToscaPropertyType.FLOAT; + } + return null; } @SuppressWarnings("unchecked") private boolean containsGetInput(Object propValue) { - return ((Map) propValue).containsKey(GET_INPUT.getElementName()) - || ImportUtils.containsGetInput(propValue); + return ((Map) propValue).containsKey(GET_INPUT.getElementName()) || ImportUtils.containsGetInput(propValue); } @SuppressWarnings("unchecked") private void fillInputsListRecursively(UploadPropInfo propertyDef, List propValueList) { + int index = 0; for (Object objValue : propValueList) { - if (objValue instanceof Map) { Map objMap = (Map) objValue; + Map propValueMap = new HashMap<>(); + propValueMap.put(String.valueOf(index), objValue); + final Collection subPropertyToscaFunctions = + buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>()); + if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) { + Collection existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions(); + if (existingSubPropertyToscaFunctions == null) { + propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions); + } else { + propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions); + } + } if (objMap.containsKey(GET_INPUT.getElementName())) { fillInputRecursively(propertyDef.getName(), objMap, propertyDef); } else { @@ -999,12 +1470,12 @@ public class YamlTemplateParsingHandler { List propSubValueList = (List) objValue; fillInputsListRecursively(propertyDef, propSubValueList); } + index++; } } @SuppressWarnings("unchecked") - private void findAndFillInputsListRecursively(UploadPropInfo propertyDef, Map objMap, - Set keys) { + private void findAndFillInputsListRecursively(UploadPropInfo propertyDef, Map objMap, Set keys) { for (String key : keys) { Object value = objMap.get(key); if (value instanceof Map) { @@ -1017,7 +1488,6 @@ public class YamlTemplateParsingHandler { } private void fillInputRecursively(String propName, Map propValue, UploadPropInfo propertyDef) { - if (propValue.containsKey(GET_INPUT.getElementName())) { Object getInput = propValue.get(GET_INPUT.getElementName()); GetInputValueDataDefinition getInputInfo = new GetInputValueDataDefinition(); @@ -1026,10 +1496,8 @@ public class YamlTemplateParsingHandler { getInputs = new ArrayList<>(); } if (getInput instanceof String) { - getInputInfo.setInputName((String) getInput); getInputInfo.setPropName(propName); - } else if (getInput instanceof List) { fillInput(propName, getInput, getInputInfo); } @@ -1043,11 +1511,11 @@ public class YamlTemplateParsingHandler { @SuppressWarnings("unchecked") private void findAndFillInputRecursively(Map propValue, UploadPropInfo propertyDef) { - for (String propName : propValue.keySet()) { - Object value = propValue.get(propName); + for (Map.Entry entry : propValue.entrySet()) { + String propName = entry.getKey(); + Object value = entry.getValue(); if (value instanceof Map) { fillInputRecursively(propName, (Map) value, propertyDef); - } else if (value instanceof List) { fillInputsRecursively(propertyDef, propName, (List) value); } @@ -1055,9 +1523,7 @@ public class YamlTemplateParsingHandler { } private void fillInputsRecursively(UploadPropInfo propertyDef, String propName, List inputs) { - inputs.stream() - .filter(o -> o instanceof Map) - .forEach(o -> fillInputRecursively(propName, (Map)o, propertyDef)); + inputs.stream().filter(Map.class::isInstance).forEach(o -> fillInputRecursively(propName, (Map) o, propertyDef)); } @SuppressWarnings("unchecked") @@ -1072,10 +1538,8 @@ public class YamlTemplateParsingHandler { } else if (indexObj instanceof Float) { int index = ((Float) indexObj).intValue(); getInputInfo.setIndexValue(index); - } else if (indexObj instanceof Map && ((Map) indexObj) - .containsKey(GET_INPUT.getElementName())) { - Object index = ((Map) indexObj) - .get(GET_INPUT.getElementName()); + } else if (indexObj instanceof Map && ((Map) indexObj).containsKey(GET_INPUT.getElementName())) { + Object index = ((Map) indexObj).get(GET_INPUT.getElementName()); GetInputValueDataDefinition getInputInfoIndex = new GetInputValueDataDefinition(); getInputInfoIndex.setInputName((String) index); getInputInfoIndex.setPropName(propName); @@ -1085,15 +1549,6 @@ public class YamlTemplateParsingHandler { } } - private boolean valueNotContainsPattern(Pattern pattern, Object propValue) { - return propValue == null || !pattern.matcher(propValue.toString()).find(); - } - - private Map failIfNoNodeTemplates(String fileName) { - janusGraphDao.rollback(); - throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName); - } - private Object failIfNotTopologyTemplate(String fileName) { janusGraphDao.rollback(); throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName); @@ -1105,15 +1560,23 @@ public class YamlTemplateParsingHandler { } private void failOnMissingCapabilityTypes(GroupDefinition groupDefinition, List missingCapTypes) { - log.debug("#failOnMissingCapabilityTypes - Failed to validate the capabilities of the group {}. The capability types {} are missing on the group type {}. ", groupDefinition.getName(), missingCapTypes.toString(), groupDefinition.getType()); - if(CollectionUtils.isNotEmpty(missingCapTypes)) { + if (log.isDebugEnabled()) { + log.debug( + "#failOnMissingCapabilityTypes - Failed to validate the capabilities of the group {}. The capability types {} are missing on the group type {}. ", + groupDefinition.getName(), missingCapTypes.toString(), groupDefinition.getType()); + } + if (CollectionUtils.isNotEmpty(missingCapTypes)) { rollbackWithException(ActionStatus.MISSING_CAPABILITY_TYPE, missingCapTypes.toString()); } } private void failOnMissingCapabilityNames(GroupDefinition groupDefinition, List missingCapNames) { - log.debug("#failOnMissingCapabilityNames - Failed to validate the capabilities of the group {}. The capabilities with the names {} are missing on the group type {}. ", groupDefinition.getName(), missingCapNames.toString(), groupDefinition.getType()); - rollbackWithException(ActionStatus.MISSING_CAPABILITIES, missingCapNames.toString(), CapabilityDataDefinition.OwnerType.GROUP.getValue(), groupDefinition.getName()); + if (log.isDebugEnabled()) { + log.debug( + "#failOnMissingCapabilityNames - Failed to validate the capabilities of the group {}. The capabilities with the names {} are missing on the group type {}. ", + groupDefinition.getName(), missingCapNames.toString(), groupDefinition.getType()); + } + rollbackWithException(ActionStatus.MISSING_CAPABILITIES, missingCapNames.toString(), CapabilityDataDefinition.OwnerType.GROUP.getValue(), + groupDefinition.getName()); } - }