Interface operation feature enhancements
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / utils / InterfacesOperationsToscaUtil.java
index f14164b..fbef11d 100644 (file)
 
 package org.openecomp.sdc.be.tosca.utils;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import org.apache.commons.collections.MapUtils;
 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Product;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.Service;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition;
 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * @author KATYR
- * @since March 20, 2018
- */
 
 public class InterfacesOperationsToscaUtil {
 
@@ -48,12 +45,14 @@ public class InterfacesOperationsToscaUtil {
     private static final String OPERATIONS_KEY = "operations";
 
     private static final String DEFAULT = "default";
-    private static final String _DEFAULT = "_default";
+    private static final String DEFAULT_HAS_UNDERSCORE = "_default";
     private static final String DOT = ".";
-    private static final String DEFAULT_INPUT_TYPE = "string";
     private static final String SELF = "SELF";
     private static final String GET_PROPERTY = "get_property";
-    public static final String DEFAULTP = "defaultp";
+    private static final String DEFAULTP = "defaultp";
+
+    private InterfacesOperationsToscaUtil() {
+    }
 
     /**
      * Creates the interface_types element
@@ -61,34 +60,38 @@ public class InterfacesOperationsToscaUtil {
      * @param component to work on
      * @return the added element
      */
-    public static Map<String, Object> addInterfaceTypeElement(Component component) {
-        Map<String, Object> toscaInterfaceTypes = new HashMap<>();
-        if ((component instanceof Service) || (component instanceof Product)) {
+    public static 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;
         }
 
-        final Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces();
+        Map<String, Object> toscaInterfaceTypes = new HashMap<>();
         for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
-            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 (String operationId : operations.keySet()) {
-                toscaOperations.put(operations.get(operationId).getName(),
-                        null); //currently not initializing any of the operations' fields as it is not needed
-            }
+            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<>();
 
-            toscaInterfaceType.setOperations(toscaOperations);
-            Map<String, Object> interfacesAsMap = getObjectAsMap(toscaInterfaceType);
-            Map<String, Object> operationsMap = (Map<String, Object>) interfacesAsMap.remove(OPERATIONS_KEY);
-            interfacesAsMap.putAll(operationsMap);
+                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_KEY);
+                interfacesAsMap.putAll(operationsMap);
 
-            toscaInterfaceTypes.put(interfaceDefinition.getToscaResourceName(), interfacesAsMap);
+                toscaInterfaceTypes.put(interfaceDefinition.getType(), interfacesAsMap);
+            }
         }
-        return toscaInterfaceTypes;
+        return MapUtils.isNotEmpty(toscaInterfaceTypes) ? toscaInterfaceTypes : null;
     }
 
     /**
@@ -97,21 +100,20 @@ public class InterfacesOperationsToscaUtil {
      * @param component to work on
      * @param nodeType  to which the interfaces element will be added
      */
-    public static void addInterfaceDefinitionElement(Component component, ToscaNodeType nodeType) {
-        Map<String, Object> toscaInterfaceDefinitions = new HashMap<>();
-
-        if ((component instanceof Service) || (component instanceof Product)) {
+    public static void addInterfaceDefinitionElement(Component component, ToscaNodeType nodeType,
+                                                     boolean isAssociatedResourceComponent) {
+        if (component instanceof Product) {
             return;
         }
-
-        final Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces();
-        if (Objects.isNull(interfaces)) {
+        final Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
+        if (MapUtils.isEmpty(interfaces)) {
             return;
         }
+        Map<String, Object> toscaInterfaceDefinitions = new HashMap<>();
         for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
             ToscaInterfaceDefinition toscaInterfaceDefinition = new ToscaInterfaceDefinition();
-            final String toscaResourceName = interfaceDefinition.getToscaResourceName();
-            toscaInterfaceDefinition.setType(toscaResourceName);
+            final String interfaceType = interfaceDefinition.getType();
+            toscaInterfaceDefinition.setType(interfaceType);
             final Map<String, OperationDataDefinition> operations = interfaceDefinition.getOperations();
             Map<String, Object> toscaOperations = new HashMap<>();
 
@@ -120,9 +122,8 @@ public class InterfacesOperationsToscaUtil {
                 ToscaLifecycleOperationDefinition toscaOperation = new ToscaLifecycleOperationDefinition();
                 if (isArtifactPresent(operationEntry)) {
                     operationArtifactPath = OperationArtifactUtil
-                                                    .createOperationArtifactPath(component.getNormalizedName(),
-                                                            interfaceDefinition.getToscaResourceName(),
-                                                            operationEntry.getValue());
+                            .createOperationArtifactPath(component, operationEntry.getValue(),
+                                    isAssociatedResourceComponent);
                     toscaOperation.setImplementation(operationArtifactPath);
                 }
                 toscaOperation.setDescription(operationEntry.getValue().getDescription());
@@ -136,34 +137,34 @@ public class InterfacesOperationsToscaUtil {
             Map<String, Object> operationsMap = (Map<String, Object>) interfaceDefAsMap.remove(OPERATIONS_KEY);
             handleDefaults(operationsMap);
             interfaceDefAsMap.putAll(operationsMap);
-            toscaInterfaceDefinitions.put(getLastPartOfName(toscaResourceName), interfaceDefAsMap);
+            toscaInterfaceDefinitions.put(getLastPartOfName(interfaceType), interfaceDefAsMap);
+        }
+        if (MapUtils.isNotEmpty(toscaInterfaceDefinitions)) {
+            nodeType.setInterfaces(toscaInterfaceDefinitions);
         }
-        nodeType.setInterfaces(toscaInterfaceDefinitions);
     }
 
     /***
-     * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in ToscaExportHandler
-     * any string key named "defaultp" will have its named changed to "default"
+     * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in
+     * ToscaExportHandler so, any string Map key named "defaultp" will have its named changed to "default"
      * @param operationsMap the map to update
      */
     private static void handleDefaults(Map<String, Object> operationsMap) {
-        for (String key : operationsMap.keySet()) {
-            Object value = operationsMap.get(key);
+        for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
+            final Object value = operationEntry.getValue();
             if (value instanceof Map) {
                 handleDefaults((Map<String, Object>) value);
             }
+            final String key = operationEntry.getKey();
             if (key.equals(DEFAULTP)) {
                 Object removed = operationsMap.remove(key);
                 operationsMap.put(DEFAULT, removed);
             }
         }
-
-
     }
 
     private static String getLastPartOfName(String toscaResourceName) {
         return toscaResourceName.substring(toscaResourceName.lastIndexOf(DOT) + 1);
-
     }
 
     private static boolean isArtifactPresent(Map.Entry<String, OperationDataDefinition> operationEntry) {
@@ -175,8 +176,9 @@ public class InterfacesOperationsToscaUtil {
     }
 
     private static void fillToscaOperationInputs(OperationDataDefinition operation,
-            ToscaLifecycleOperationDefinition toscaOperation) {
-        if (Objects.isNull(operation.getInputs())) {
+                                                 ToscaLifecycleOperationDefinition toscaOperation) {
+        if (Objects.isNull(operation.getInputs()) || operation.getInputs().isEmpty()) {
+            toscaOperation.setInputs(null);
             return;
         }
         Map<String, ToscaProperty> toscaInputs = new HashMap<>();
@@ -184,9 +186,14 @@ public class InterfacesOperationsToscaUtil {
         for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) {
             ToscaProperty toscaInput = new ToscaProperty();
             toscaInput.setDescription(input.getDescription());
-            toscaInput.setType(DEFAULT_INPUT_TYPE);
+            String mappedPropertyName = null;
+            if (Objects.nonNull(input.getInputId())) {
+                mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1);
+            }
+            toscaInput.setDefaultp(createDefaultValue(mappedPropertyName));
 
-            toscaInput.setDefaultp(createDefaultValue(getLastPartOfName(input.getInputId())));
+            toscaInput.setType(input.getType());
+            toscaInput.setRequired(input.isRequired());
             toscaInputs.put(input.getName(), toscaInput);
         }
 
@@ -197,23 +204,29 @@ public class InterfacesOperationsToscaUtil {
         Map<String, List<String>> getPropertyMap = new HashMap<>();
         List<String> values = new ArrayList<>();
         values.add(SELF);
-        values.add(propertyName);
+        if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) {
+            values.addAll(Arrays.asList(propertyName.split("\\.")));
+        }
+
         getPropertyMap.put(GET_PROPERTY, values);
 
         return getPropertyMap;
     }
 
-
     private static Map<String, Object> getObjectAsMap(Object obj) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        if (obj instanceof ToscaInterfaceDefinition) {
+            //Prevent empty field serialization in interface definition
+            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        }
         Map<String, Object> objectAsMap =
-                obj instanceof Map ? (Map<String, Object>) obj : new ObjectMapper().convertValue(obj, Map.class);
+                obj instanceof Map ? (Map<String, Object>) obj : objectMapper.convertValue(obj, Map.class);
 
         if (objectAsMap.containsKey(DEFAULT)) {
             Object defaultValue = objectAsMap.get(DEFAULT);
             objectAsMap.remove(DEFAULT);
-            objectAsMap.put(_DEFAULT, defaultValue);
+            objectAsMap.put(DEFAULT_HAS_UNDERSCORE, defaultValue);
         }
         return objectAsMap;
     }
-
 }