Import service with milestones
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / csar / YamlTemplateParsingHandler.java
index 3171277..a5927a5 100644 (file)
@@ -45,6 +45,7 @@ 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.MILESTONES;
 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;
@@ -88,16 +89,22 @@ 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.InterfaceDefinitionHandler;
 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.janusgraph.JanusGraphDao;
+import org.openecomp.sdc.be.datatypes.elements.ActivityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.FilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MilestoneDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
@@ -106,8 +113,9 @@ import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefin
 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.enums.ConstraintType;
 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
+import org.openecomp.sdc.be.datatypes.enums.ActivityTypeEnum;
+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;
@@ -153,19 +161,25 @@ public class YamlTemplateParsingHandler {
     private final GroupTypeBusinessLogic groupTypeBusinessLogic;
     private final AnnotationBusinessLogic annotationBusinessLogic;
     private final PolicyTypeBusinessLogic policyTypeBusinessLogic;
+    private final ServiceBusinessLogic serviceBusinessLogic;
     private final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler;
+    private final InterfaceDefinitionHandler interfaceDefinitionHandler;
 
     public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao,
                                       GroupTypeBusinessLogic groupTypeBusinessLogic,
                                       AnnotationBusinessLogic annotationBusinessLogic,
                                       PolicyTypeBusinessLogic policyTypeBusinessLogic,
-                                      final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler
+                                      ServiceBusinessLogic serviceBusinessLogic,
+                                      final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler,
+                                      final InterfaceDefinitionHandler interfaceDefinitionHandler
     ) {
         this.janusGraphDao = janusGraphDao;
         this.groupTypeBusinessLogic = groupTypeBusinessLogic;
         this.annotationBusinessLogic = annotationBusinessLogic;
         this.policyTypeBusinessLogic = policyTypeBusinessLogic;
+        this.serviceBusinessLogic = serviceBusinessLogic;
         this.toscaFunctionYamlParsingHandler = toscaFunctionYamlParsingHandler;
+        this.interfaceDefinitionHandler = interfaceDefinitionHandler;
     }
 
     public ParsedToscaYamlInfo parseResourceInfoFromYAML(String fileName, String resourceYml, Map<String, String> createdNodesToscaResourceNames,
@@ -191,10 +205,19 @@ public class YamlTemplateParsingHandler {
         parsedToscaYamlInfo.setPolicies(getPolicies(mappedToscaTemplate, component.getModel()));
         Map<String, Object> substitutionMappings = getSubstitutionMappings(mappedToscaTemplate);
         if (substitutionMappings != null) {
-            if (component.isService() && !interfaceTemplateYaml.isEmpty()) {
-                parsedToscaYamlInfo.setProperties(getProperties(loadYamlAsStrictMap(interfaceTemplateYaml)));
+            if (component.isService()) {
+                if (interfaceTemplateYaml.isEmpty()) {
+                    component.setDerivedFromGenericType((String) substitutionMappings.get(NODE_TYPE.getElementName()));
+                    List<PropertyDefinition> 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<String, List<String>>) substitutionMappings.get("properties"));
+            }
             parsedToscaYamlInfo.setSubstitutionMappingNodeType((String) substitutionMappings.get(NODE_TYPE.getElementName()));
         }
         log.debug("#parseResourceInfoFromYAML - The yaml {} has been parsed ", fileName);
@@ -242,21 +265,30 @@ public class YamlTemplateParsingHandler {
         return ImportUtils.getProperties(toscaJson).left().on(err -> new HashMap<>());
     }
 
-    private ListDataDefinition<SubstitutionFilterPropertyDataDefinition> getSubstitutionFilterProperties(Map<String, Object> toscaJson) {
-        ListDataDefinition<SubstitutionFilterPropertyDataDefinition> propertyList = new ListDataDefinition<>();
-        Map<String, Object> substitutionFilters = findFirstToscaMapElement(toscaJson, SUBSTITUTION_FILTERS).left().on(err -> new HashMap<>());
+    private ListDataDefinition<SubstitutionFilterPropertyDataDefinition> getSubstitutionFilterProperties(final Map<String, Object> toscaJson) {
+        final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> propertyList = new ListDataDefinition<>();
+        final Map<String, Object> substitutionFilters = findFirstToscaMapElement(toscaJson, SUBSTITUTION_FILTERS).left().on(err -> new HashMap<>());
         if (MapUtils.isEmpty(substitutionFilters)) {
             return propertyList;
         }
-        ArrayList<Map<String, List<Map<String, Object>>>> substitutionFilterProperties =
-            (ArrayList<Map<String, List<Map<String, Object>>>>) substitutionFilters.get("properties");
+        final List<Map<String, Object>> substitutionFilterProperties = (List<Map<String, Object>>) substitutionFilters.get("properties");
         if (CollectionUtils.isEmpty(substitutionFilterProperties)) {
             return propertyList;
         }
-        for (Map<String, List<Map<String, Object>>> filterProps : substitutionFilterProperties) {
-            for (Map.Entry<String, List<Map<String, Object>>> propertyFilterEntry : filterProps.entrySet()) {
+        for (final Map<String, Object> filterProps : substitutionFilterProperties) {
+            for (final Map.Entry<String, Object> propertyFilterEntry : filterProps.entrySet()) {
                 final String propertyName = propertyFilterEntry.getKey();
-                for (Map<String, Object> filterValueMap : propertyFilterEntry.getValue()) {
+                final Object value = propertyFilterEntry.getValue();
+                if (value instanceof List) {
+                    final List<Map<String, Object>> propertyFilterEntryValue = (List<Map<String, Object>>) value;
+                    for (final Map<String, Object> 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<String, Object> filterValueMap = (Map<String, Object>) value;
                     final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition();
                     substitutionFilterPropertyDataDefinition.setName(propertyName);
                     substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap));
@@ -367,11 +399,15 @@ public class YamlTemplateParsingHandler {
                 }
                 final UploadPropInfo uploadPropInfo = buildProperty(propertyJson.getKey(), propertyJson.getValue());
                 final PropertyDefinition propertyDefinition = new PropertyDefinition(originalProperty);
-                propertyDefinition.setValue(gson.toJson(uploadPropInfo.getValue()));
                 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)
@@ -814,6 +850,7 @@ public class YamlTemplateParsingHandler {
                 setDirectives(nodeTemplateInfo, nodeTemplateJsonMap);
                 setNodeFilter(nodeTemplateInfo, nodeTemplateJsonMap);
                 setSubstitutions(substitutionMappings, nodeTemplateInfo);
+                setOccurrencesAndInstanceCount(nodeTemplateInfo, nodeTemplateJsonMap);
             } else {
                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
             }
@@ -922,6 +959,24 @@ public class YamlTemplateParsingHandler {
         }
     }
 
+    @SuppressWarnings("unchecked")
+    private void setOccurrencesAndInstanceCount(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
+        if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) {
+            List<Object> occurrences = (List<Object>) 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<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap, String nodeName) {
         Map<String, List<UploadReqInfo>> moduleRequirements = new HashMap<>();
@@ -1178,7 +1233,8 @@ public class YamlTemplateParsingHandler {
             if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(propValueObj)) {
                 toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(propValueMap).ifPresent(propertyDef::setToscaFunction);
             } else {
-                final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
+                final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions =
+                    buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
                 if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
                     Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions();
                     if (existingSubPropertyToscaFunctions == null) {
@@ -1205,7 +1261,7 @@ public class YamlTemplateParsingHandler {
         }
         return propertyDef;
     }
-    
+
     private Collection<SubPropertyToscaFunction> buildSubPropertyToscaFunctions(final Map<String, Object> propValueMap, final List<String> path) {
         Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = new ArrayList<>();
         propValueMap.entrySet().stream().filter(entry -> entry.getValue() instanceof Map).forEach(entry -> {
@@ -1213,7 +1269,7 @@ public class YamlTemplateParsingHandler {
             subPropertyPath.add(entry.getKey());
             if (ToscaFunctionType.findType(((Map<String, Object>) entry.getValue()).keySet().iterator().next()).isPresent()) {
                 Optional<ToscaFunction> toscaFunction =
-                        toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map) entry.getValue());
+                    toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map) entry.getValue());
                 if (toscaFunction.isPresent()) {
                     SubPropertyToscaFunction subPropertyToscaFunction = new SubPropertyToscaFunction();
                     subPropertyToscaFunction.setToscaFunction(toscaFunction.get());
@@ -1247,6 +1303,10 @@ public class YamlTemplateParsingHandler {
                     final Map<String, Object> interfaceInputs = (Map<String, Object>) operationValue.get(INPUTS.getElementName());
                     operationDef.setInputs(handleInterfaceOperationInputs(interfaceInputs));
                 }
+                if (operationValue.containsKey(MILESTONES.getElementName())) {
+                    final Map<String, Object> interfaceMilestones = (Map<String, Object>) operationValue.get(MILESTONES.getElementName());
+                    operationDef.setMilestones(interfaceDefinitionHandler.handleInterfaceOperationMilestones(interfaceMilestones));
+                }
                 operations.put(operationEntry.getKey(), operationDef);
             }
             interfaceDef.setOperations(operations);
@@ -1264,6 +1324,7 @@ public class YamlTemplateParsingHandler {
             operationInput.setUniqueId(UUID.randomUUID().toString());
             operationInput.setInputId(operationInput.getUniqueId());
             operationInput.setName(interfaceInput.getKey());
+
             handleInputToscaDefinition(interfaceInput.getKey(), interfaceInput.getValue(), operationInput);
             inputs.add(operationInput);
         }
@@ -1276,10 +1337,25 @@ public class YamlTemplateParsingHandler {
         final OperationInputDefinition operationInput
     ) {
         if (value instanceof Map) {
+            final Map<String, Object> valueMap = (Map<String, Object>) value;
             log.debug("Creating interface operation input '{}'", inputName);
             Type type = new TypeToken<LinkedHashMap<String, Object>>() {
             }.getType();
             String stringValue = gson.toJson(value, type);
+            if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(value)) {
+                toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) value)
+                    .ifPresent(operationInput::setToscaFunction);
+            } else {
+                final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(valueMap, new ArrayList<>());
+                if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
+                    Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = operationInput.getSubPropertyToscaFunctions();
+                    if (existingSubPropertyToscaFunctions == null) {
+                        operationInput.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
+                    } else {
+                        operationInput.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
+                    }
+                }
+            }
             operationInput.setValue(stringValue);
         }
         if (value instanceof String) {
@@ -1288,6 +1364,10 @@ public class YamlTemplateParsingHandler {
             operationInput.setToscaDefaultValue(stringValue);
             operationInput.setValue(stringValue);
         }
+        operationInput.setType("string");
+        if (operationInput.getValue() == null) {
+            operationInput.setValue(String.valueOf(value));
+        }
     }
 
     private Optional<ArtifactDataDefinition> handleOperationImplementation(
@@ -1331,6 +1411,13 @@ public class YamlTemplateParsingHandler {
                 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));
@@ -1369,9 +1456,22 @@ public class YamlTemplateParsingHandler {
 
     @SuppressWarnings("unchecked")
     private void fillInputsListRecursively(UploadPropInfo propertyDef, List<Object> propValueList) {
+        int index = 0;
         for (Object objValue : propValueList) {
             if (objValue instanceof Map) {
                 Map<String, Object> objMap = (Map<String, Object>) objValue;
+                Map<String, Object> propValueMap = new HashMap<>();
+                propValueMap.put(String.valueOf(index), objValue);
+                final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions =
+                    buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
+                if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
+                    Collection<SubPropertyToscaFunction> 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 {
@@ -1382,6 +1482,7 @@ public class YamlTemplateParsingHandler {
                 List<Object> propSubValueList = (List<Object>) objValue;
                 fillInputsListRecursively(propertyDef, propSubValueList);
             }
+            index++;
         }
     }