VNF Recreate
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowAction.java
index 2424627..4eb4ffe 100644 (file)
@@ -50,6 +50,10 @@ import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.Resource;
+import org.onap.so.client.aai.AAICommonObjectMapperProvider;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
+import org.onap.so.client.aai.entities.Relationships;
 import org.onap.so.client.exception.ExceptionBuilder;
 import org.onap.so.client.orchestration.AAIConfigurationResources;
 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
@@ -62,6 +66,7 @@ import org.onap.so.db.catalog.beans.VnfVfmoduleCvnfcConfigurationCustomization;
 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
 import org.onap.so.db.catalog.client.CatalogDbClient;
+import org.onap.so.logger.MsoLogger;
 import org.onap.so.serviceinstancebeans.ModelInfo;
 import org.onap.so.serviceinstancebeans.ModelType;
 import org.onap.so.serviceinstancebeans.Networks;
@@ -72,6 +77,7 @@ import org.onap.so.serviceinstancebeans.VfModules;
 import org.onap.so.serviceinstancebeans.Vnfs;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -81,6 +87,7 @@ public class WorkflowAction {
 
        private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
        private static final String SERVICE_INSTANCES = "serviceInstances";
+       private static final String VF_MODULES = "vfModules";
        private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI = "WorkflowAction was unable to verify if the instance name already exist in AAI.";
        private static final String G_ORCHESTRATION_FLOW = "gOrchestrationFlow";
        private static final String G_ACTION = "requestAction";
@@ -117,6 +124,12 @@ public class WorkflowAction {
        private CatalogDbClient catalogDbClient;
        @Autowired
        private AAIConfigurationResources aaiConfigurationResources;
+       @Autowired
+       private WorkflowActionExtractResourcesAAI workflowActionUtils;
+
+       @Autowired
+        private Environment environment;
+       private String defaultCloudOwner = "org.onap.so.cloud-owner";
 
        public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
                this.bbInputSetupUtils = bbInputSetupUtils;
@@ -148,6 +161,12 @@ public class WorkflowAction {
                        execution.setVariable(G_ISTOPLEVELFLOW, true);
                        ServiceInstancesRequest sIRequest = mapper.readValue(bpmnRequest, ServiceInstancesRequest.class);
                        RequestDetails requestDetails = sIRequest.getRequestDetails();
+                       String cloudOwner = "";
+                       try{
+                               cloudOwner = requestDetails.getCloudConfiguration().getCloudOwner();
+                       } catch (Exception ex) {
+                               cloudOwner = environment.getProperty(defaultCloudOwner);
+                       }
                        Resource resource = extractResourceIdAndTypeFromUri(uri);
                        WorkflowType resourceType = resource.getResourceType();
                        execution.setVariable("resourceName", resourceType.toString());
@@ -162,21 +181,9 @@ public class WorkflowAction {
                        execution.setVariable("resourceId", resourceId);
                        execution.setVariable("resourceType", resourceType);
 
-                       if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
-                               List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
-                                               .getUserParams();
-                               for (Map<String, Object> params : userParams) {
-                                       if (params.containsKey(HOMINGSOLUTION)) {
-                                               execution.setVariable("homing", true);
-                                               execution.setVariable("callHoming", true);
-                                               execution.setVariable("homingSolution", params.get(HOMINGSOLUTION));
-                                       }
-                               }
-                       }
-
                        if (aLaCarte) {
                                if (orchFlows == null || orchFlows.isEmpty()) {
-                                       orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
+                                       orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte, cloudOwner);
                                }
                                orchFlows = filterOrchFlows(orchFlows, resourceType, execution);
                                String key = "";
@@ -249,6 +256,8 @@ public class WorkflowAction {
                                } else if (resourceType == WorkflowType.SERVICE
                                                && requestAction.equalsIgnoreCase("deactivateInstance")) {
                                        resourceCounter.add(new Resource(WorkflowType.SERVICE,"",false));
+                               } else if (resourceType == WorkflowType.VNF && (requestAction.equalsIgnoreCase("replaceInstance") || (requestAction.equalsIgnoreCase("recreateInstance")))) {
+                                       traverseAAIVnf(execution, resourceCounter, workflowResourceIds.getServiceInstanceId(), workflowResourceIds.getVnfId(), aaiResourceIds);
                                } else {
                                        buildAndThrowException(execution, "Current Macro Request is not supported");
                                }
@@ -260,7 +269,7 @@ public class WorkflowAction {
                                logger.info("Found {}", foundObjects);
 
                                if (orchFlows == null || orchFlows.isEmpty()) {
-                                       orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
+                                       orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte, cloudOwner);
                                }
                                flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceCounter, requestId, apiVersion, resourceId,
                                                resourceType, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails);
@@ -268,9 +277,10 @@ public class WorkflowAction {
                                        logger.info("Sorting for Vlan Tagging");
                                        flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
                                }
+                               // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
                                if (resourceType == WorkflowType.SERVICE
-                                               && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
-                                               && !resourceCounter.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType())).collect(Collectors.toList()).isEmpty()) {
+                                       && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
+                                       && !resourceCounter.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType())).collect(Collectors.toList()).isEmpty()) {
                                        execution.setVariable("homing", true);
                                        execution.setVariable("calledHoming", false);
                                }
@@ -281,6 +291,20 @@ public class WorkflowAction {
                                }
                        }
 
+                       // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified, enable it.
+                       if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
+                               List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
+                               for (Map<String, Object> params : userParams) {
+                                       if (params.containsKey(HOMINGSOLUTION)) {
+                                               if (params.get(HOMINGSOLUTION).equals("none")) {
+                                                       execution.setVariable("homing", false);
+                                               } else {
+                                                       execution.setVariable("homing", true);
+                                               }
+                                       }
+                               }
+                       }
+
                        if (flowsToExecute.isEmpty()) {
                                throw new IllegalStateException("Macro did not come up with a valid execution path.");
                        }
@@ -535,6 +559,67 @@ public class WorkflowAction {
                }
        }
 
+       private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceCounter, String serviceId, String vnfId,
+                       List<Pair<WorkflowType, String>> aaiResourceIds) {
+               try{
+                       ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
+                       org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO = bbInputSetup
+                                       .getExistingServiceInstance(serviceInstanceAAI);
+                       resourceCounter.add(new Resource(WorkflowType.SERVICE,serviceInstanceMSO.getServiceInstanceId(),false));
+                       if (serviceInstanceMSO.getVnfs() != null) {
+                               for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO
+                                               .getVnfs()) {
+                                       if(vnf.getVnfId().equals(vnfId)){
+                                               aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VNF, vnf.getVnfId()));
+                                               resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getVnfId(),false));
+                                               if (vnf.getVfModules() != null) {
+                                                       for (VfModule vfModule : vnf.getVfModules()) {
+                                                               aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
+                                                               resourceCounter.add(new Resource(WorkflowType.VFMODULE,vfModule.getVfModuleId(),false));        
+                                                               findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(), resourceCounter, aaiResourceIds);
+                                                       }
+                                               }
+                                               if (vnf.getVolumeGroups() != null) {
+                                                       for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
+                                                                       .getVolumeGroups()) {
+                                                               aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
+                                                               resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,volumeGroup.getVolumeGroupId(),false));
+                                                       }
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+               } catch (Exception ex) {
+                       buildAndThrowException(execution,
+                                       "Could not find existing Vnf or related Instances to execute the request on.");
+               }
+       }
+
+       private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId, List<Resource> resourceCounter, 
+                       List<Pair<WorkflowType, String>> aaiResourceIds) {
+               try{
+                       org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
+                       AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
+                                       new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
+                       Optional<Relationships> relationshipsOp;
+                       relationshipsOp = vfModuleWrapper.getRelationships();
+                       if(relationshipsOp.isPresent()) {
+                               relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
+                               if(relationshipsOp.isPresent()){
+                                       Optional<Configuration> config = workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
+                                       if(config.isPresent()){
+                                               aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
+                                               resourceCounter.add(new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
+                                       }
+                               }
+                       }
+               }catch (Exception ex){
+                       buildAndThrowException(execution,
+                                       "Failed to find Configuration object from the vfModule.");
+               }
+       }
+       
        protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceCounter,
                        ServiceInstancesRequest sIRequest, String requestAction)
                        throws IOException {
@@ -664,35 +749,38 @@ public class WorkflowAction {
        }
 
        protected Resource extractResourceIdAndTypeFromUri(String uri) {
-               Pattern patt = Pattern.compile(
-                               "[vV]\\d+.*?(?:(?:/(?<type>" + supportedTypes + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?)?$");
-               Matcher m = patt.matcher(uri);
-               Boolean generated = false;
-
-               if (m.find()) {
-                       logger.debug("found match on {} : {} " , uri ,  m);
-                       String type = m.group("type");
-                       String id = m.group("id");
-                       String action = m.group("action");
-                       if (type == null) {
-                               throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
-                       }
-                       if (action == null) {
-                               if (type.equals(SERVICE_INSTANCES) && (id == null || id.equals("assign"))) {
-                                       id = UUID.randomUUID().toString();
-                                       generated = true;
-                               }
-                       } else {
-                               if (action.matches(supportedTypes)) {
-                                       id = UUID.randomUUID().toString();
-                                       generated = true;
-                                       type = action;
-                               }
-                       }
-                       return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
-               } else {
-                       throw new IllegalArgumentException("Uri could not be parsed: " + uri);
-               }
+           Pattern patt = Pattern.compile(
+                   "[vV]\\d+.*?(?:(?:/(?<type>" + supportedTypes + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?)?$");
+           Matcher m = patt.matcher(uri);
+           Boolean generated = false;
+
+           if (m.find()) {
+               logger.debug("found match on {} : {} " , uri ,  m);
+               String type = m.group("type");
+               String id = m.group("id");
+               String action = m.group("action");
+               if (type == null) {
+                   throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
+               }
+               if (action == null) {
+                   if (type.equals(SERVICE_INSTANCES) && (id == null || id.equals("assign"))) {
+                       id = UUID.randomUUID().toString();
+                       generated = true;
+                   }else if (type.equals(VF_MODULES) && id.equals("scaleOut")) {
+                       id = UUID.randomUUID().toString();
+                       generated = true;
+                   }
+               } else {
+                   if (action.matches(supportedTypes)) {
+                       id = UUID.randomUUID().toString();
+                       generated = true;
+                       type = action;
+                   }
+               }
+               return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
+           } else {
+               throw new IllegalArgumentException("Uri could not be parsed: " + uri);
+           }
        }
 
        protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
@@ -936,10 +1024,10 @@ public class WorkflowAction {
        }
 
        protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
-                       WorkflowType resourceName, boolean aLaCarte) {
+                       WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
                List<OrchestrationFlow> listToExecute = new ArrayList<>();
                NorthBoundRequest northBoundRequest = catalogDbClient
-                               .getNorthBoundRequestByActionAndIsALaCarteAndRequestScope(requestAction, resourceName.toString(), aLaCarte);
+                               .getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(requestAction, resourceName.toString(), aLaCarte, cloudOwner);
                if(northBoundRequest == null){
                        if(aLaCarte){
                                buildAndThrowException(execution,"The request: ALaCarte " + resourceName + " " + requestAction + " is not supported by GR_API.");