Fix 'Import use case fails when interfaces in template do not exist in system'-bug...
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ResourceImportManager.java
index 076dd50..99dea8f 100644 (file)
@@ -27,6 +27,7 @@ import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementO
 import fj.data.Either;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.EnumMap;
 import java.util.HashMap;
@@ -65,6 +66,7 @@ import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
@@ -83,10 +85,11 @@ import org.openecomp.sdc.be.model.DefaultUploadResourceInfo;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.NodeTypesMetadataList;
-import org.openecomp.sdc.be.model.NullNodeTypeMetadata;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.RequirementDefinition;
 import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.UploadComponentInstanceInfo;
+import org.openecomp.sdc.be.model.UploadInterfaceInfo;
 import org.openecomp.sdc.be.model.UploadResourceInfo;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
@@ -115,7 +118,7 @@ import org.yaml.snakeyaml.Yaml;
 @org.springframework.stereotype.Component("resourceImportManager")
 public class ResourceImportManager {
 
-    static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("['\\w\\s\\-\\:]+");
+    static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("['\\w\\s\\-\\.\\:]+");
     private static final Logger log = Logger.getLogger(ResourceImportManager.class);
     private final InterfaceDefinitionHandler interfaceDefinitionHandler;
     private final ComponentsUtils componentsUtils;
@@ -153,13 +156,14 @@ public class ResourceImportManager {
     }
 
     public ImmutablePair<Resource, ActionStatus> importNormativeResource(final String resourceYml, final UploadResourceInfo resourceMetaData,
+                                                                         final Map<String, UploadComponentInstanceInfo> instancesFromCsar,
                                                                          final User creator, final boolean createNewVersion, final boolean needLock,
                                                                          final boolean isInTransaction) {
         LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction();
         lifecycleChangeInfo.setUserRemarks("certification on import");
         Function<Resource, Boolean> validator = resource -> resourceBusinessLogic.validatePropertiesDefaultValues(resource);
         return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, createNewVersion,
-            needLock, null, null, false, null, null, false);
+            needLock, null, null, false, null, null, false, instancesFromCsar);
     }
 
     public void importAllNormativeResource(final String resourcesYaml, final NodeTypesMetadataList nodeTypesMetadataList, final User user,
@@ -175,11 +179,11 @@ public class ResourceImportManager {
             return;
         }
         final Map<String, Object> nodeTypesMap = (Map<String, Object>) nodeTypesYamlMap.get(ToscaTagNamesEnum.NODE_TYPES.getElementName());
-        importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList, user, "", createNewVersion,needLock);
+        importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList, null, user, "", createNewVersion,needLock);
     }
 
     public void importAllNormativeResource(final  Map<String, Object> nodeTypesMap, final NodeTypesMetadataList nodeTypesMetadataList,
-                                           final User user, String model, final boolean createNewVersion, final boolean needLock) {
+                                           Map<String, UploadComponentInstanceInfo> instancesFromCsar, final User user, String model, final boolean createNewVersion, final boolean needLock) {
         try {
             nodeTypesMetadataList.getNodeMetadataList().forEach(nodeTypeMetadata -> {
                 final String nodeTypeToscaName = nodeTypeMetadata.getToscaName();
@@ -198,7 +202,7 @@ public class ResourceImportManager {
                         uploadResourceInfo.setModel(model);
                         uploadResourceInfo.setContactId(user.getUserId());
                     }
-                    importNormativeResource(nodeTypeYaml, uploadResourceInfo, user, createNewVersion, needLock, true);
+                    importNormativeResource(nodeTypeYaml, uploadResourceInfo, instancesFromCsar, user, createNewVersion, needLock, true);
                 }
             });
             janusGraphDao.commit();
@@ -214,7 +218,7 @@ public class ResourceImportManager {
         lifecycleChangeInfo.setUserRemarks("certification on import");
         Function<Resource, Boolean> validator = resource -> resourceBusinessLogic.validatePropertiesDefaultValues(resource);
         return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false, createNewVersion, needLock,
-            null, null, false, null, null, false);
+            null, null, false, null, null, false, null);
     }
 
     public ImmutablePair<Resource, ActionStatus> importCertifiedResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator,
@@ -224,7 +228,7 @@ public class ResourceImportManager {
                                                                          Map<ArtifactOperationEnum, List<ArtifactDefinition>> nodeTypeArtifactsToHandle,
                                                                          List<ArtifactDefinition> nodeTypesNewCreatedArtifacts,
                                                                          boolean forceCertificationAllowed, CsarInfo csarInfo, String nodeName,
-                                                                         boolean isNested) {
+                                                                         boolean isNested, Map<String, UploadComponentInstanceInfo> instancesFromCsar) {
         Resource resource = new Resource();
         ImmutablePair<Resource, ActionStatus> responsePair = new ImmutablePair<>(resource, ActionStatus.CREATED);
         Either<ImmutablePair<Resource, ActionStatus>, ResponseFormat> response = Either.left(responsePair);
@@ -233,7 +237,7 @@ public class ResourceImportManager {
             boolean shouldBeCertified = nodeTypeArtifactsToHandle == null || nodeTypeArtifactsToHandle.isEmpty();
             setConstantMetaData(resource, shouldBeCertified);
             setResourceMetaData(resource, resourceYml, resourceMetaData);
-            populateResourceFromYaml(resourceYml, resource);
+            populateResourceFromYaml(resourceYml, resource, instancesFromCsar);
             validationFunction.apply(resource);
             resource.getComponentMetadataDefinition().getMetadataDataDefinition().setNormative(resourceMetaData.isNormative());
             checkResourceExists(createNewVersion, csarInfo, resource);
@@ -349,7 +353,7 @@ public class ResourceImportManager {
         ImmutablePair<Resource, ActionStatus> responsePair = new ImmutablePair<>(resource, ActionStatus.CREATED);
         try {
             setMetaDataFromJson(resourceMetaData, resource);
-            populateResourceFromYaml(resourceYml, resource);
+            populateResourceFromYaml(resourceYml, resource, null);
             // currently import VF isn't supported. In future will be supported import VF only with CSAR file!!
             if (ResourceTypeEnum.VF == resource.getResourceType()) {
                 log.debug("Now import VF isn't supported. It will be supported in future with CSAR file only");
@@ -364,7 +368,7 @@ public class ResourceImportManager {
         return responsePair;
     }
 
-    private void populateResourceFromYaml(final String resourceYml, Resource resource) {
+    private void populateResourceFromYaml(final String resourceYml, Resource resource, Map<String, UploadComponentInstanceInfo> instancesFromCsar) {
         @SuppressWarnings("unchecked") Object ymlObj = new Yaml().load(resourceYml);
         if (ymlObj instanceof Map) {
             final Either<Resource, StorageOperationStatus> existingResource = getExistingResource(resource);
@@ -391,7 +395,7 @@ public class ResourceImportManager {
             setProperties(toscaJson, resource, existingResource);
             setAttributes(toscaJson, resource);
             setRequirements(toscaJson, resource, parentResource);
-            setInterfaceLifecycle(toscaJson, resource, existingResource);
+            setInterfaceLifecycle(toscaJson, resource, existingResource, instancesFromCsar);
         } else {
             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
         }
@@ -444,31 +448,45 @@ public class ResourceImportManager {
         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
                 .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TYPES);
         if (toscaElement.isLeft() && toscaElement.left().value().size() == 1) {
-            String toscaResourceName = toscaElement.left().value().keySet().iterator().next();
-            return toscaResourceName;
+            return toscaElement.left().value().keySet().iterator().next();
         }
         return null;
     }
 
-    private void setInterfaceLifecycle(Map<String, Object> toscaJson, Resource resource, Either<Resource, StorageOperationStatus> existingResource) {
+    private void setInterfaceLifecycle(Map<String, Object> toscaJson, Resource resource, Either<Resource, StorageOperationStatus> existingResource,
+                                       Map<String, UploadComponentInstanceInfo> instancesFromCsar) {
         final Either<Map<String, Object>, ResultStatusEnum> toscaInterfaces = ImportUtils
             .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.INTERFACES);
+        final Map<String, InterfaceDefinition> moduleInterfaces = new HashMap<>();
+        final Map<String, Object> map;
+        List<UploadInterfaceInfo> interfaceInfoList = null;
+        if (MapUtils.isNotEmpty(instancesFromCsar)) {
+            interfaceInfoList = instancesFromCsar.values().stream().filter(i -> MapUtils.isNotEmpty(i.getInterfaces()))
+                .flatMap(i -> i.getInterfaces().values().stream()).collect(Collectors.toList());
+        }
         if (toscaInterfaces.isLeft()) {
-            final Map<String, InterfaceDefinition> moduleInterfaces = new HashMap<>();
-            final Map<String, Object> map = toscaInterfaces.left().value();
+            map = toscaInterfaces.left().value();
             for (final Entry<String, Object> interfaceNameValue : map.entrySet()) {
-                final Either<InterfaceDefinition, ResultStatusEnum> eitherInterface = createModuleInterface(interfaceNameValue.getValue(),
-                    resource.getModel());
+                final Either<InterfaceDefinition, ResultStatusEnum> eitherInterface =
+                    createModuleInterface(interfaceNameValue.getValue(), resource.getModel());
                 if (eitherInterface.isRight()) {
                     log.info("error when creating interface:{}, for resource:{}", interfaceNameValue.getKey(), resource.getName());
                 } else {
                     final InterfaceDefinition interfaceDefinition = eitherInterface.left().value();
+                    if (CollectionUtils.isNotEmpty(interfaceInfoList)) {
+                        updateInterfaceDefinition(interfaceDefinition, interfaceInfoList);
+                    }
                     moduleInterfaces.put(interfaceDefinition.getType(), interfaceDefinition);
                 }
             }
-            if (existingResource.isLeft()) {
+        } else {
+            map = Collections.emptyMap();
+        }
+        if (existingResource.isLeft()) {
+            final Map<String, InterfaceDefinition> interfaces = existingResource.left().value().getInterfaces();
+            if (MapUtils.isNotEmpty(interfaces)) {
                 final Map<String, InterfaceDefinition> userCreatedInterfaceDefinitions =
-                    existingResource.left().value().getInterfaces().entrySet().stream()
+                    interfaces.entrySet().stream()
                         .filter(i -> i.getValue().isUserCreated())
                         .filter(i -> !map.containsKey(i.getValue().getType()))
                         .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
@@ -476,13 +494,24 @@ public class ResourceImportManager {
                     moduleInterfaces.putAll(userCreatedInterfaceDefinitions);
                 }
             }
+        }
 
-            if (MapUtils.isNotEmpty(moduleInterfaces)) {
-                resource.setInterfaces(moduleInterfaces);
-            }
+        if (MapUtils.isNotEmpty(moduleInterfaces)) {
+            resource.setInterfaces(moduleInterfaces);
         }
     }
 
+    private void updateInterfaceDefinition(InterfaceDefinition interfaceDefinition, List<UploadInterfaceInfo> interfaceInfoList) {
+        Map<String, OperationDataDefinition> operations = new HashMap<>();
+        interfaceInfoList.stream().filter(i -> interfaceDefinition.getType().endsWith(i.getKey())).forEach(i -> {
+            i.getOperations().values().forEach(o -> {
+                o.setImplementation(null);
+            });
+            operations.putAll(i.getOperations());
+        });
+        interfaceDefinition.setOperations(operations);
+    }
+
     private Either<InterfaceDefinition, ResultStatusEnum> createModuleInterface(final Object interfaceJson, final String model) {
         try {
             if (interfaceJson instanceof String) {
@@ -588,16 +617,14 @@ public class ResourceImportManager {
                 for (final Entry<String, PropertyDefinition> entry : propertyDefinitionMap.entrySet()) {
                     addPropertyToList(resource.getName(), propertiesList, entry);
                 }
-                if (existingResource.isLeft()) {
-                    if ( CollectionUtils.isNotEmpty(existingResource.left().value().getProperties())) {
-                        final List<PropertyDefinition> userCreatedResourceProperties =
-                            existingResource.left().value().getProperties().stream()
-                                .filter(PropertyDataDefinition::isUserCreated)
-                                .filter(propertyDefinition -> !propertyDefinitionMap.containsKey(propertyDefinition.getName()))
-                                .collect(Collectors.toList());
-                        if (CollectionUtils.isNotEmpty(userCreatedResourceProperties)) {
-                            propertiesList.addAll(userCreatedResourceProperties);
-                        }
+                if (existingResource.isLeft() && CollectionUtils.isNotEmpty(existingResource.left().value().getProperties())) {
+                    final List<PropertyDefinition> userCreatedResourceProperties =
+                        existingResource.left().value().getProperties().stream()
+                            .filter(PropertyDataDefinition::isUserCreated)
+                            .filter(propertyDefinition -> !propertyDefinitionMap.containsKey(propertyDefinition.getName()))
+                            .collect(Collectors.toList());
+                    if (CollectionUtils.isNotEmpty(userCreatedResourceProperties)) {
+                        propertiesList.addAll(userCreatedResourceProperties);
                     }
                 }