Merge branch 'recursive-orch'
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ebb / loader / ServiceEBBLoader.java
index 55a92b0..9d76707 100644 (file)
@@ -1,9 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (c) 2020 Nokia
+ * ================================================================================
+ * Modifications Copyright (c) 2021 Orange
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.javatuples.Pair;
+import org.onap.aai.domain.yang.ComposedResource;
+import org.onap.aai.domain.yang.ComposedResources;
+import org.onap.aai.domain.yang.GenericVnf;
 import org.onap.aai.domain.yang.Relationship;
+import org.onap.aai.domain.yang.RelationshipData;
+import org.onap.aai.domain.yang.RelationshipList;
 import org.onap.aai.domain.yang.ServiceInstance;
 import org.onap.aai.domain.yang.VpnBinding;
 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
@@ -12,10 +39,11 @@ import org.onap.aaiclient.client.aai.entities.Relationships;
 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.Resource;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.VrfBondingServiceException;
-import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionExtractResourcesAAI;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowType;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
+import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoNetwork;
+import org.onap.so.bpmn.servicedecomposition.modelinfo.ModelInfoPnf;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
 import org.onap.so.client.exception.ExceptionBuilder;
@@ -36,12 +64,17 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ACTIVATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DEACTIVATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UNASSIGN_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_INSTANCE;
 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.NETWORKCOLLECTION;
 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.USER_PARAM_SERVICE;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGNINSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
 
 
 @Component
@@ -78,7 +111,7 @@ public class ServiceEBBLoader {
         boolean containsService = false;
         List<Resource> resourceList = new ArrayList<>();
         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-        if (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
+        if (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)) {
             // SERVICE-MACRO-ASSIGN will always get user params with a
             // service.
 
@@ -106,20 +139,20 @@ public class ServiceEBBLoader {
                 resourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, userParams,
                         serviceInstanceId, requestAction);
             }
-            if (!foundRelated(resourceList)) {
+            if (!isComposedService(resourceList) && !foundRelated(resourceList)) {
                 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
             }
-        } else if (("activateInstance".equalsIgnoreCase(requestAction)
-                || "unassignInstance".equalsIgnoreCase(requestAction)
-                || "deleteInstance".equalsIgnoreCase(requestAction)
+        } else if ((ACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)
+                || UNASSIGN_INSTANCE.equalsIgnoreCase(requestAction) || DELETE_INSTANCE.equalsIgnoreCase(requestAction)
+                || UPGRADE_INSTANCE.equalsIgnoreCase(requestAction)
                 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
             // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
             // SERVICE-MACRO-DELETE
             // Will never get user params with service, macro will have
             // to query the SI in AAI to find related instances.
             traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
-        } else if ("deactivateInstance".equalsIgnoreCase(requestAction)) {
-            resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
+        } else if (DEACTIVATE_INSTANCE.equalsIgnoreCase(requestAction)) {
+            resourceList.add(new Resource(WorkflowType.SERVICE, "", false, null));
         }
         return resourceList;
     }
@@ -140,16 +173,18 @@ public class ServiceEBBLoader {
         if (service == null) {
             buildAndThrowException(execution, "Could not find the service model in catalog db.");
         } else {
-            resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
+            Resource serviceResource = new Resource(WorkflowType.SERVICE, service.getModelUUID(), false, null);
+            resourceList.add(serviceResource);
             RelatedInstance relatedVpnBinding =
                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
             RelatedInstance relatedLocalNetwork =
                     bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
 
             if (relatedVpnBinding != null && relatedLocalNetwork != null) {
-                traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
+                traverseVrfConfiguration(aaiResourceIds, resourceList, serviceResource, service, relatedVpnBinding,
+                        relatedLocalNetwork);
             } else {
-                traverseNetworkCollection(execution, resourceList, service);
+                traverseNetworkCollection(execution, resourceList, serviceResource, service);
             }
         }
     }
@@ -161,20 +196,37 @@ public class ServiceEBBLoader {
                 || containsWorkflowType(resourceList, WorkflowType.NETWORKCOLLECTION));
     }
 
+    public boolean isComposedService(List<Resource> resourceList) {
+        return resourceList.stream().anyMatch(s -> s.getResourceType() == WorkflowType.SERVICE && s.hasParent());
+    }
+
     public void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
             List<Pair<WorkflowType, String>> aaiResourceIds) {
         try {
             ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
                     bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
-            resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
-            traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
-            traverseServiceInstanceMSOPnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
+            var serviceResource =
+                    new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false, null);
+            serviceResource.setModelInvariantId(serviceInstanceAAI.getModelInvariantId());
+            serviceResource.setModelVersionId(serviceInstanceAAI.getModelVersionId());
+            resourceList.add(serviceResource);
+            traverseServiceInstanceChildService(resourceList, serviceResource, serviceInstanceAAI);
+            traverseServiceInstanceMSOVnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
+            traverseServiceInstanceMSOPnfs(resourceList, serviceResource, aaiResourceIds, serviceInstanceMSO);
             if (serviceInstanceMSO.getNetworks() != null) {
                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
                         .getNetworks()) {
                     aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
-                    resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
+                    Resource networkResource =
+                            new Resource(WorkflowType.NETWORK, network.getNetworkId(), false, serviceResource);
+                    ModelInfoNetwork modelInfoNetwork = network.getModelInfoNetwork();
+                    if (modelInfoNetwork != null) {
+                        networkResource.setModelCustomizationId(modelInfoNetwork.getModelCustomizationUUID());
+                        networkResource.setModelVersionId(modelInfoNetwork.getModelUUID());
+                        networkResource.setModelCustomizationId(modelInfoNetwork.getModelCustomizationUUID());
+                    }
+                    resourceList.add(networkResource);
                 }
             }
             if (serviceInstanceMSO.getCollection() != null) {
@@ -182,7 +234,7 @@ public class ServiceEBBLoader {
                 aaiResourceIds
                         .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
                 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
-                        serviceInstanceMSO.getCollection().getId(), false));
+                        serviceInstanceMSO.getCollection().getId(), false, serviceResource));
             }
             if (serviceInstanceMSO.getConfigurations() != null) {
                 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
@@ -193,8 +245,8 @@ public class ServiceEBBLoader {
                             if (relationship.getRelatedTo().contains("vnfc")
                                     || relationship.getRelatedTo().contains("vpn-binding")) {
                                 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
-                                resourceList.add(
-                                        new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
+                                resourceList.add(new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(),
+                                        false, serviceResource));
                                 break;
                             }
                         }
@@ -208,7 +260,7 @@ public class ServiceEBBLoader {
         }
     }
 
-    private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
+    private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList, Resource serviceResource,
             List<Pair<WorkflowType, String>> aaiResourceIds,
             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
         if (serviceInstanceMSO.getVnfs() == null) {
@@ -216,18 +268,24 @@ public class ServiceEBBLoader {
         }
         for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
             aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
-            resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
-            traverseVnfModules(resourceList, aaiResourceIds, vnf);
+            GenericVnf genericVnf = bbInputSetupUtils.getAAIGenericVnf(vnf.getVnfId());
+            Resource vnfResource = new Resource(WorkflowType.VNF, vnf.getVnfId(), false, serviceResource);
+            vnfResource.setVnfCustomizationId(genericVnf.getModelCustomizationId());
+            vnfResource.setModelCustomizationId(genericVnf.getModelCustomizationId());
+            vnfResource.setModelVersionId(genericVnf.getModelVersionId());
+            resourceList.add(vnfResource);
+            traverseVnfModules(resourceList, vnfResource, aaiResourceIds, vnf);
             if (vnf.getVolumeGroups() != null) {
                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
                     aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
-                    resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
+                    resourceList.add(
+                            new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false, vnfResource));
                 }
             }
         }
     }
 
-    private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList,
+    private void traverseServiceInstanceMSOPnfs(List<Resource> resourceList, Resource serviceResource,
             List<Pair<WorkflowType, String>> aaiResourceIds,
             org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
         if (serviceInstanceMSO.getPnfs() == null) {
@@ -235,12 +293,66 @@ public class ServiceEBBLoader {
         }
         for (org.onap.so.bpmn.servicedecomposition.bbobjects.Pnf pnf : serviceInstanceMSO.getPnfs()) {
             aaiResourceIds.add(new Pair<>(WorkflowType.PNF, pnf.getPnfId()));
-            resourceList.add(new Resource(WorkflowType.PNF, pnf.getPnfId(), false));
+            Resource resource = new Resource(WorkflowType.PNF, pnf.getPnfId(), false, serviceResource);
+            ModelInfoPnf modelInfo = pnf.getModelInfoPnf();
+            if (modelInfo != null) {
+                resource.setModelVersionId(modelInfo.getModelUuid());
+                resource.setModelCustomizationId(modelInfo.getModelCustomizationUuid());
+            }
+            resourceList.add(resource);
         }
     }
 
+    public void traverseServiceInstanceChildService(List<Resource> resourceList, Resource serviceResource,
+            ServiceInstance serviceInstanceAAI) {
+
+        ComposedResources composedResources = serviceInstanceAAI.getComposedResources();
+        if (composedResources == null) {
+            return;
+        }
+
+        List<ComposedResource> listOfComposedResource = composedResources.getComposedResource();
+
+        listOfComposedResource.forEach(composedResource -> {
+            // Get ServiceInstance from composedResource relationship List
+            RelationshipList relationshipList = composedResource.getRelationshipList();
+            if (relationshipList == null) {
+                return;
+            }
+            List<Relationship> composedResourceRelationshipList = relationshipList.getRelationship();
+            ServiceInstance childService = new ServiceInstance();
+            composedResourceRelationshipList.forEach(composedRelation -> {
+                if ("service-instance".equalsIgnoreCase(composedRelation.getRelatedTo())) {
+                    List<RelationshipData> rData = composedRelation.getRelationshipData();
+                    rData.forEach(data -> {
+                        if ("service-instance.service-instance-id".equalsIgnoreCase(data.getRelationshipKey())) {
+                            childService.setServiceInstanceId(data.getRelationshipValue());
+                        }
+                    });
+                    composedRelation.getRelatedToProperty().forEach(relatedToProperty -> {
+                        if ("service-instance.service-instance-name"
+                                .equalsIgnoreCase(relatedToProperty.getPropertyKey())) {
+                            childService.setServiceInstanceName(relatedToProperty.getPropertyValue());
+                        }
+                    });
+                }
+            });
+
+            if (childService.getServiceInstanceId() == null) {
+                return;
+            }
+
+            Resource childServiceResource =
+                    new Resource(WorkflowType.SERVICE, childService.getServiceInstanceId(), false, serviceResource);
+
+            childServiceResource.setInstanceName(childService.getServiceInstanceName());
+            resourceList.add(childServiceResource);
+        });
+
+    }
+
     protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
-            List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
+            List<Resource> resourceList, Resource serviceResource, org.onap.so.db.catalog.beans.Service service,
             RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
             throws VrfBondingServiceException, JsonProcessingException {
         org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
@@ -258,12 +370,12 @@ public class ServiceEBBLoader {
             aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
         }
         resourceList.add(new Resource(WorkflowType.CONFIGURATION,
-                service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
+                service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false, serviceResource));
 
     }
 
     protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
-            org.onap.so.db.catalog.beans.Service service) {
+            Resource serviceResource, org.onap.so.db.catalog.beans.Service service) {
         if (isVnfCustomizationsInTheService(service)) {
             buildAndThrowException(execution,
                     "Cannot orchestrate Service-Macro-Create without user params with a vnf. Please update ASDC model for new macro orchestration support or add service_recipe records to route to old macro flows");
@@ -278,14 +390,16 @@ public class ServiceEBBLoader {
         } else {
             CollectionResourceCustomization collectionResourceCustomization =
                     findCatalogNetworkCollection(execution, service);
-            traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
+            traverseNetworkCollectionResourceCustomization(resourceList, serviceResource,
+                    collectionResourceCustomization);
         }
-        traverseNetworkCollectionCustomization(resourceList, service);
+        traverseNetworkCollectionCustomization(resourceList, serviceResource, service);
     }
 
-    private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
+    private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList, Resource serviceResource,
             CollectionResourceCustomization collectionResourceCustomization) {
-        if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
+        if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, serviceResource,
+                collectionResourceCustomization))
             return;
         int minNetworks = 0;
         org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
@@ -310,7 +424,7 @@ public class ServiceEBBLoader {
         for (int i = 0; i < minNetworks; i++) {
             if (collectionNetworkResourceCust != null) {
                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
-                        collectionNetworkResourceCust.getModelCustomizationUUID(), false);
+                        collectionNetworkResourceCust.getModelCustomizationUUID(), false, serviceResource);
                 resource.setVirtualLinkKey(Integer.toString(i));
                 resourceList.add(resource);
             }
@@ -332,13 +446,13 @@ public class ServiceEBBLoader {
     }
 
     private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
-            CollectionResourceCustomization collectionResourceCustomization) {
+            Resource serviceResource, CollectionResourceCustomization collectionResourceCustomization) {
         if (collectionResourceCustomization == null) {
             logger.debug("No Network Collection Customization found");
             return true;
         }
         resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
-                collectionResourceCustomization.getModelCustomizationUUID(), false));
+                collectionResourceCustomization.getModelCustomizationUUID(), false, serviceResource));
         logger.debug("Found a network collection");
         if (collectionResourceCustomization.getCollectionResource() == null) {
             logger.debug("No Network Collection found. collectionResource is null");
@@ -366,7 +480,7 @@ public class ServiceEBBLoader {
         return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
     }
 
-    private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
+    private void traverseNetworkCollectionCustomization(List<Resource> resourceList, Resource serviceResource,
             org.onap.so.db.catalog.beans.Service service) {
         if (isNetworkCollectionInTheResourceList(resourceList)) {
             return;
@@ -377,7 +491,7 @@ public class ServiceEBBLoader {
         }
         for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
             resourceList.add(new Resource(WorkflowType.NETWORK,
-                    service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
+                    service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false, serviceResource));
         }
     }
 
@@ -389,14 +503,19 @@ public class ServiceEBBLoader {
         return !(service.getPnfCustomizations() == null || service.getPnfCustomizations().isEmpty());
     }
 
-    private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
+    private void traverseVnfModules(List<Resource> resourceList, Resource vnfResource,
+            List<Pair<WorkflowType, String>> aaiResourceIds,
             org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
         if (vnf.getVfModules() == null) {
             return;
         }
         for (VfModule vfModule : vnf.getVfModules()) {
             aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
-            Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
+            Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false, vnfResource);
+            org.onap.aai.domain.yang.VfModule aaiVfModule =
+                    bbInputSetupUtils.getAAIVfModule(vnf.getVnfId(), vfModule.getVfModuleId());
+            resource.setModelCustomizationId(aaiVfModule.getModelCustomizationId());
+            resource.setModelInvariantId(aaiVfModule.getModelInvariantId());
             resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
             resourceList.add(resource);
         }