Backend support for operation milestone filters
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / InterfacesOperationsConverter.java
index 3650422..fa52618 100644 (file)
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.openecomp.sdc.be.tosca;
 
 import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT;
@@ -24,40 +25,75 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.google.gson.Gson;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
+import org.openecomp.sdc.be.datatypes.elements.ActivityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.FilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
+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.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ActivityTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
+import org.openecomp.sdc.be.datatypes.enums.MilestoneTypeEnum;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Product;
 import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.tosca.constraints.EqualConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LengthConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.MaxLengthConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.PatternConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint;
 import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
+import org.openecomp.sdc.be.tosca.model.ToscaActivity;
 import org.openecomp.sdc.be.tosca.model.ToscaArtifactDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaInput;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceOperationImplementation;
 import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition;
+import org.openecomp.sdc.be.tosca.model.ToscaMilestone;
 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignment;
 import org.openecomp.sdc.be.tosca.model.ToscaPropertyAssignmentJsonSerializer;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintEqual;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintGreaterOrEqual;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintGreaterThan;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintInRange;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLength;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLessOrEqual;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintLessThan;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintMaxLength;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintMinLength;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintPattern;
+import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintValidValues;
 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
@@ -81,42 +117,6 @@ public class InterfacesOperationsConverter {
         this.propertyConvertor = propertyConvertor;
     }
 
-    /**
-     * Creates the interface_types element.
-     *
-     * @param component to work on
-     * @return the added element
-     */
-    public Map<String, Object> addInterfaceTypeElement(Component component, List<String> allInterfaceTypes) {
-        if (component instanceof Product) {
-            return null;
-        }
-        final Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
-        if (MapUtils.isEmpty(interfaces)) {
-            return null;
-        }
-        Map<String, Object> toscaInterfaceTypes = new HashMap<>();
-        for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
-            boolean isInterfaceTypeExistInGlobalType = allInterfaceTypes.stream()
-                .anyMatch(type -> type.equalsIgnoreCase(interfaceDefinition.getType()));
-            if (!isInterfaceTypeExistInGlobalType) {
-                ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType();
-                toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE);
-                final Map<String, OperationDataDefinition> operations = interfaceDefinition.getOperations();
-                Map<String, Object> toscaOperations = new HashMap<>();
-                for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
-                    toscaOperations.put(operationEntry.getValue().getName(), null);
-                }
-                toscaInterfaceType.setOperations(toscaOperations);
-                Map<String, Object> interfacesAsMap = getObjectAsMap(toscaInterfaceType);
-                Map<String, Object> operationsMap = (Map<String, Object>) interfacesAsMap.remove(OPERATIONS.getElementName());
-                interfacesAsMap.putAll(operationsMap);
-                toscaInterfaceTypes.put(getInterfaceType(component, LOCAL_INTERFACE_TYPE), interfacesAsMap);
-            }
-        }
-        return MapUtils.isNotEmpty(toscaInterfaceTypes) ? toscaInterfaceTypes : null;
-    }
-
     private static Object getDefaultValue(Map<String, Object> inputValueMap) {
         Object defaultValue = null;
         for (Map.Entry<String, Object> operationEntry : inputValueMap.entrySet()) {
@@ -152,12 +152,10 @@ public class InterfacesOperationsConverter {
         return toscaResourceName.substring(toscaResourceName.lastIndexOf(DOT) + 1);
     }
 
-    private boolean isArtifactPresent(final OperationDataDefinition operationDataDefinition) {
-        return operationDataDefinition.getImplementation() != null
-            && StringUtils.isNotEmpty(operationDataDefinition.getImplementation().getArtifactName());
-    }
-
     private static String getInputValue(final OperationInputDefinition input) {
+        if (null != input.getToscaFunction()) {
+            return input.getToscaFunction().getJsonObjectValue().toString();
+        }
         String inputValue = input.getValue() == null ? input.getToscaDefaultValue() : input.getValue();
         if (inputValue != null && inputValue.contains(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
             Gson gson = new Gson();
@@ -203,6 +201,47 @@ public class InterfacesOperationsConverter {
         return objectAsMap;
     }
 
+    /**
+     * Creates the interface_types element.
+     *
+     * @param component to work on
+     * @return the added element
+     */
+    public Map<String, Object> addInterfaceTypeElement(Component component, List<String> allInterfaceTypes) {
+        if (component instanceof Product) {
+            return null;
+        }
+        final Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
+        if (MapUtils.isEmpty(interfaces)) {
+            return null;
+        }
+        Map<String, Object> toscaInterfaceTypes = new HashMap<>();
+        for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
+            boolean isInterfaceTypeExistInGlobalType = allInterfaceTypes.stream()
+                .anyMatch(type -> type.equalsIgnoreCase(interfaceDefinition.getType()));
+            if (!isInterfaceTypeExistInGlobalType) {
+                ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType();
+                toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE);
+                final Map<String, OperationDataDefinition> operations = interfaceDefinition.getOperations();
+                Map<String, Object> toscaOperations = new HashMap<>();
+                for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
+                    toscaOperations.put(operationEntry.getValue().getName(), null);
+                }
+                toscaInterfaceType.setOperations(toscaOperations);
+                Map<String, Object> interfacesAsMap = getObjectAsMap(toscaInterfaceType);
+                Map<String, Object> operationsMap = (Map<String, Object>) interfacesAsMap.remove(OPERATIONS.getElementName());
+                interfacesAsMap.putAll(operationsMap);
+                toscaInterfaceTypes.put(getInterfaceType(component, LOCAL_INTERFACE_TYPE), interfacesAsMap);
+            }
+        }
+        return MapUtils.isNotEmpty(toscaInterfaceTypes) ? toscaInterfaceTypes : null;
+    }
+
+    private boolean isArtifactPresent(final OperationDataDefinition operationDataDefinition) {
+        return operationDataDefinition.getImplementation() != null
+            && StringUtils.isNotEmpty(operationDataDefinition.getImplementation().getArtifactName());
+    }
+
     /**
      * Adds the 'interfaces' element to the node type provided.
      *
@@ -281,6 +320,7 @@ public class InterfacesOperationsConverter {
                     toscaLifecycleOperationDefinition.setDescription(operationEntry.getValue().getDescription());
                 }
                 fillToscaOperationInputs(operationEntry.getValue(), dataTypes, toscaLifecycleOperationDefinition);
+                fillToscaOperationMilestones(operationEntry.getValue(), dataTypes, toscaLifecycleOperationDefinition);
                 toscaOperationMap.put(operationEntry.getValue().getName(), toscaLifecycleOperationDefinition);
             }
         }
@@ -298,9 +338,123 @@ public class InterfacesOperationsConverter {
         interfaceDefinitionAsMap.putAll(operationsMap);
         toscaInterfaceDefinitions.put(getLastPartOfName(interfaceType), interfaceDefinitionAsMap);
     }
-    
+
+    private void fillToscaOperationMilestones(OperationDataDefinition operation, Map<String, DataTypeDefinition> dataTypes,
+                                              ToscaLifecycleOperationDefinition toscaOperation) {
+        if (Objects.isNull(operation.getMilestones()) || operation.getMilestones().isEmpty()) {
+            toscaOperation.setMilestones(null);
+            return;
+        }
+        Map<String, ToscaMilestone> toscaMilestones = new HashMap<>();
+        for (Entry<String, MilestoneDataDefinition> milestone : operation.getMilestones().entrySet()) {
+            ListDataDefinition<ActivityDataDefinition> activities = milestone.getValue().getActivities();
+            if (MilestoneTypeEnum.getEnum(milestone.getKey()).isEmpty() || activities == null || activities.isEmpty()) {
+                continue;
+            }
+            List<Map<String, ToscaActivity>> toscaActivities = new ArrayList<>();
+            for (ActivityDataDefinition activity : activities.getListToscaDataDefinition()) {
+                if (ActivityTypeEnum.getEnum(activity.getType()).isEmpty()) {
+                    continue;
+                }
+                Map<String, ToscaActivity> toscaActivityMap = new HashMap<>();
+                ToscaActivity toscaActivity = new ToscaActivity();
+                toscaActivity.setWorkflow(activity.getWorkflow());
+                Map<String, Object> inputs = getToscaActivityInputs(activity.getInputs(), dataTypes);
+                if (!inputs.isEmpty()) {
+                    toscaActivity.setInputs(inputs);
+                }
+                toscaActivityMap.put(activity.getType(), toscaActivity);
+                toscaActivities.add(toscaActivityMap);
+            }
+            ToscaMilestone toscaMilestone = new ToscaMilestone();
+            toscaMilestone.setActivities(toscaActivities);
+            toscaMilestone.setFilters(getToscaFilters(milestone.getValue().getFilters()));
+            toscaMilestones.put(milestone.getKey(), toscaMilestone);
+        }
+        toscaOperation.setMilestones(toscaMilestones);
+    }
+
+    private List<Map<String, ToscaPropertyConstraint>> getToscaFilters(ListDataDefinition<FilterDataDefinition> filters) {
+        if (filters != null && !filters.isEmpty()) {
+            List<Map<String, ToscaPropertyConstraint>> toscaFilters = new ArrayList<>();
+            for (FilterDataDefinition filter : filters.getListToscaDataDefinition()) {
+                Optional<ConstraintType> typeOptional = ConstraintType.findByType(filter.getConstraint());
+                if (typeOptional.isEmpty()) {
+                    continue;
+                }
+                ConstraintType type = typeOptional.get();
+                Object value = filter.isToscaFunction() ? filter.getToscaFunction().getJsonObjectValue() : filter.getFilterValue();
+                if (ConstraintType.EQUAL.equals(type)) {
+                    EqualConstraint equalConstraint = new EqualConstraint(value);
+                    ToscaPropertyConstraint prop = new ToscaPropertyConstraintEqual(equalConstraint.getEqual());
+                    toscaFilters.add(Map.of(filter.getName(), prop));
+                }
+                if (ConstraintType.GREATER_THAN.equals(type)) {
+                    GreaterThanConstraint greaterThanConstraint = new GreaterThanConstraint(value);
+                    ToscaPropertyConstraintGreaterThan prop = new ToscaPropertyConstraintGreaterThan(greaterThanConstraint.getGreaterThan());
+                    toscaFilters.add(Map.of(filter.getName(), prop));
+                }
+                if (ConstraintType.GREATER_OR_EQUAL.equals(type)) {
+                    GreaterOrEqualConstraint greaterOrEqualConstraint = new GreaterOrEqualConstraint<>(value);
+                    ToscaPropertyConstraintGreaterOrEqual prop =
+                        new ToscaPropertyConstraintGreaterOrEqual(greaterOrEqualConstraint.getGreaterOrEqual());
+                    toscaFilters.add(Map.of(filter.getName(), prop));
+                }
+                if (ConstraintType.LESS_THAN.equals(type)) {
+                    LessThanConstraint lessThanConstraint = new LessThanConstraint(value);
+                    ToscaPropertyConstraintLessThan prop = new ToscaPropertyConstraintLessThan(lessThanConstraint.getLessThan());
+                    toscaFilters.add(Map.of(filter.getName(), prop));
+                }
+                if (ConstraintType.LESS_OR_EQUAL.equals(type)) {
+                    LessOrEqualConstraint lessOrEqualConstraint = new LessOrEqualConstraint<>(value);
+                    ToscaPropertyConstraintLessOrEqual prop = new ToscaPropertyConstraintLessOrEqual(lessOrEqualConstraint.getLessOrEqual());
+                    toscaFilters.add(Map.of(filter.getName(), prop));
+                }
+                if (ConstraintType.IN_RANGE.equals(type)) {
+                    InRangeConstraint inRangeConstraint = new InRangeConstraint((List<Object>) value);
+                    toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintInRange(inRangeConstraint.getInRange())));
+                }
+                if (ConstraintType.VALID_VALUES.equals(type)) {
+                    ValidValuesConstraint validValues = new ValidValuesConstraint((List<Object>) value);
+                    List prop = validValues.getValidValues();
+                    toscaFilters.add(Map.of(filter.getName(), (new ToscaPropertyConstraintValidValues(prop))));
+                }
+                if (ConstraintType.LENGTH.equals(type)) {
+                    LengthConstraint lengthConstraint = new LengthConstraint((Integer) value);
+                    toscaFilters.add(Map.of(filter.getName(), (new ToscaPropertyConstraintLength(lengthConstraint.getLength()))));
+                }
+                if (ConstraintType.MIN_LENGTH.equals(type)) {
+                    MinLengthConstraint minLengthConstraint = new MinLengthConstraint((Integer) value);
+                    toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintMinLength(minLengthConstraint.getMinLength())));
+                }
+                if (ConstraintType.MAX_LENGTH.equals(type)) {
+                    MaxLengthConstraint maxLengthConstraint = new MaxLengthConstraint((Integer) value);
+                    toscaFilters.add(Map.of(filter.getName(), new ToscaPropertyConstraintMaxLength(maxLengthConstraint.getMaxLength())));
+                }
+            }
+            return toscaFilters;
+        }
+        return null;
+    }
+
+    private Map<String, Object> getToscaActivityInputs(ListDataDefinition<OperationInputDefinition> inputs,
+                                                       Map<String, DataTypeDefinition> dataTypes) {
+        if (Objects.isNull(inputs) || inputs.isEmpty()) {
+            return null;
+        }
+        Map<String, Object> toscaInputs = new HashMap<>();
+        for (OperationInputDefinition input : inputs.getListToscaDataDefinition()) {
+            Object value = propertyConvertor.convertToToscaObject(input, getInputValue(input), dataTypes, false);
+            if (ObjectUtils.isNotEmpty(value)) {
+                toscaInputs.put(input.getName(), value);
+            }
+        }
+        return toscaInputs;
+    }
+
     private boolean operationHasAnImplementation(OperationDataDefinition operation) {
-        return operation.getImplementation() != null && StringUtils.isNotEmpty(operation.getImplementation().getArtifactName()) && !operation.getImplementation().getArtifactName().equals("''");
+        return operation.getImplementation() != null && StringUtils.isNotEmpty(operation.getImplementation().getArtifactName()) &&
+            !operation.getImplementation().getArtifactName().equals("''");
     }
 
     private void handleInterfaceOperationImplementation(final Component component, final ComponentInstance componentInstance,
@@ -316,6 +470,10 @@ public class InterfacesOperationsConverter {
         if (isArtifactPresent(operationDataDefinition)) {
             final String operationArtifactPath =
                 OperationArtifactUtil.createOperationArtifactPath(component, componentInstance, operationDataDefinition, isAssociatedComponent);
+            final ToscaInterfaceOperationImplementation toscaInterfaceOperationImplementation = new ToscaInterfaceOperationImplementation();
+            if (implementation.getTimeout() != null && implementation.getTimeout() > 0) {
+                toscaInterfaceOperationImplementation.setTimeout(implementation.getTimeout());
+            }
             if (implementation.getArtifactType() != null) {
                 final ToscaArtifactDefinition toscaArtifactDefinition = new ToscaArtifactDefinition();
                 toscaArtifactDefinition.setFile(operationArtifactPath);
@@ -326,12 +484,18 @@ public class InterfacesOperationsConverter {
                 if (MapUtils.isNotEmpty(propertiesMap)) {
                     toscaArtifactDefinition.setProperties(propertiesMap);
                 }
-                final ToscaInterfaceOperationImplementation toscaInterfaceOperationImplementation = new ToscaInterfaceOperationImplementation();
                 toscaInterfaceOperationImplementation.setPrimary(toscaArtifactDefinition);
                 toscaOperation.setImplementation(toscaInterfaceOperationImplementation);
             } else {
-                toscaOperation.setImplementation(
-                    StringUtils.isBlank(operationArtifactPath) || "null".equals(operationArtifactPath) ? null : operationArtifactPath);
+                if (toscaInterfaceOperationImplementation.getTimeout() != null) {
+                    final ToscaArtifactDefinition toscaArtifactDefinition = new ToscaArtifactDefinition();
+                    toscaArtifactDefinition.setFile(StringUtils.isBlank(operationArtifactPath) || "null".equals(operationArtifactPath) ? null : operationArtifactPath);
+                    toscaInterfaceOperationImplementation.setPrimary(toscaArtifactDefinition);
+                    toscaOperation.setImplementation(toscaInterfaceOperationImplementation);
+                } else {
+                    toscaOperation.setImplementation(
+                        StringUtils.isBlank(operationArtifactPath) || "null".equals(operationArtifactPath) ? null : operationArtifactPath);
+                }
             }
         }
     }