/*- * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. * ================================================================================ * 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; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.javatuples.Pair; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.L3Network; import org.onap.aai.domain.yang.ServiceInstance; import org.onap.aai.domain.yang.VolumeGroup; import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule; import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock; import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock; 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.client.exception.ExceptionBuilder; import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization; import org.onap.so.db.catalog.beans.CollectionResourceCustomization; import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization; import org.onap.so.db.catalog.beans.InstanceGroup; import org.onap.so.db.catalog.beans.NetworkCollectionResourceCustomization; import org.onap.so.db.catalog.beans.VfModuleCustomization; 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.MessageEnum; import org.onap.so.logger.MsoLogger; import org.onap.so.serviceinstancebeans.ModelInfo; import org.onap.so.serviceinstancebeans.ModelType; import org.onap.so.serviceinstancebeans.Networks; import org.onap.so.serviceinstancebeans.RequestDetails; import org.onap.so.serviceinstancebeans.Service; import org.onap.so.serviceinstancebeans.ServiceInstancesRequest; import org.onap.so.serviceinstancebeans.VfModules; import org.onap.so.serviceinstancebeans.Vnfs; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; @Component public class WorkflowAction { private static final String G_ORCHESTRATION_FLOW = "gOrchestrationFlow"; private static final String G_ACTION = "requestAction"; private static final String G_CURRENT_SEQUENCE = "gCurrentSequence"; private static final String G_REQUEST_ID = "mso-request-id"; private static final String G_BPMN_REQUEST = "bpmnRequest"; private static final String G_ALACARTE = "aLaCarte"; private static final String G_APIVERSION = "apiVersion"; private static final String G_URI = "requestUri"; private static final String G_ISTOPLEVELFLOW = "isTopLevelFlow"; private static final String VNF_TYPE = "vnfType"; private static final String SERVICE = "Service"; private static final String VNF = "Vnf"; private static final String VFMODULE = "VfModule"; private static final String VOLUMEGROUP = "VolumeGroup"; private static final String NETWORK = "Network"; private static final String NETWORKCOLLECTION = "NetworkCollection"; private static final String CONFIGURATION = "Configuration"; private static final String ASSIGNINSTANCE = "assignInstance"; private static final String CREATEINSTANCE = "createInstance"; private static final String USERPARAMSERVICE = "service"; private static final String supportedTypes = "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances"; private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, WorkflowAction.class); @Autowired protected BBInputSetup bbInputSetup; @Autowired protected BBInputSetupUtils bbInputSetupUtils; @Autowired private ExceptionBuilder exceptionBuilder; @Autowired private CatalogDbClient catalogDbClient; public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) { this.bbInputSetupUtils = bbInputSetupUtils; } public void setBbInputSetup(BBInputSetup bbInputSetup) { this.bbInputSetup = bbInputSetup; } public void selectExecutionList(DelegateExecution execution) throws Exception { final String requestAction = (String) execution.getVariable(G_ACTION); final String requestId = (String) execution.getVariable(G_REQUEST_ID); final String bpmnRequest = (String) execution.getVariable(G_BPMN_REQUEST); final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE); final String apiVersion = (String) execution.getVariable(G_APIVERSION); final String uri = (String) execution.getVariable(G_URI); final String vnfType = (String) execution.getVariable(VNF_TYPE); List orchFlows = (List) execution.getVariable(G_ORCHESTRATION_FLOW); List flowsToExecute = new ArrayList<>(); WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution); List> aaiResourceIds = new ArrayList<>(); List resourceCounter = new ArrayList<>(); execution.setVariable("sentSyncResponse", false); execution.setVariable("homing", false); execution.setVariable("calledHoming", false); try { ObjectMapper mapper = new ObjectMapper(); execution.setVariable(G_ISTOPLEVELFLOW, true); ServiceInstancesRequest sIRequest = mapper.readValue(bpmnRequest, ServiceInstancesRequest.class); RequestDetails requestDetails = sIRequest.getRequestDetails(); Resource resource = extractResourceIdAndTypeFromUri(uri); WorkflowType resourceType = resource.getResourceType(); execution.setVariable("resourceName", resourceType.toString()); String resourceId = ""; if (resource.isGenerated()) { resourceId = validateResourceIdInAAI(resource.getResourceId(), resourceType, sIRequest.getRequestDetails().getRequestInfo().getInstanceName(), sIRequest.getRequestDetails(), workflowResourceIds); } else { resourceId = resource.getResourceId(); } execution.setVariable("resourceId", resourceId); execution.setVariable("resourceType", resourceType); if (aLaCarte) { if (orchFlows == null || orchFlows.isEmpty()) { orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte); } String key = ""; ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo(); if(modelInfo.getModelType().equals(ModelType.service)) { key = modelInfo.getModelVersionId(); } else { key = modelInfo.getModelCustomizationId(); } for (OrchestrationFlow orchFlow : orchFlows) { ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, key, apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null); flowsToExecute.add(ebb); } } else { boolean foundRelated = false; boolean containsService = false; if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) { // SERVICE-MACRO-ASSIGN will always get user params with a // service. if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) { List> userParams = sIRequest.getRequestDetails().getRequestParameters() .getUserParams(); for (Map params : userParams) { if (params.containsKey(USERPARAMSERVICE)) { containsService = true; } } if (containsService) { traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction); } } else { buildAndThrowException(execution, "Service-Macro-Assign request details must contain user params with a service"); } } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) { // SERVICE-MACRO-CREATE will get user params with a service, // a service with a network, a service with a // networkcollection, OR an empty service. // If user params is just a service or null and macro // queries the SI and finds a VNF, macro fails. if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) { List> userParams = sIRequest.getRequestDetails().getRequestParameters() .getUserParams(); for (Map params : userParams) { if (params.containsKey(USERPARAMSERVICE)) { containsService = true; } } } if (containsService) { foundRelated = traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction); } if (!foundRelated) { traverseCatalogDbService(execution, sIRequest, resourceCounter); } } else if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase("activateInstance") || requestAction.equalsIgnoreCase("unassignInstance") || requestAction.equalsIgnoreCase("deleteInstance"))) { // 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, resourceCounter, resourceId, aaiResourceIds); } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase("deactivateInstance")) { resourceCounter.add(new Resource(WorkflowType.SERVICE,"",false)); } else { buildAndThrowException(execution, "Current Macro Request is not supported"); } String foundObjects = ""; for(WorkflowType type : WorkflowType.values()){ foundObjects = foundObjects + type + " - " + resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size() + " "; } msoLogger.info("Found " + foundObjects); if (orchFlows == null || orchFlows.isEmpty()) { orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte); } flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceCounter, requestId, apiVersion, resourceId, resourceType, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails); if (!resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) { msoLogger.info("Sorting for Vlan Tagging"); flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction); } if (resourceType == WorkflowType.SERVICE && (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); } if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))){ generateResourceIds(flowsToExecute, resourceCounter); }else{ updateResourceIdsFromAAITraversal(flowsToExecute, resourceCounter, aaiResourceIds); } } if (flowsToExecute.isEmpty()) { throw new IllegalStateException("Macro did not come up with a valid execution path."); } msoLogger.info("List of BuildingBlocks to execute:"); for (ExecuteBuildingBlock ebb : flowsToExecute) { msoLogger.info(ebb.getBuildingBlock().getBpmnFlowName()); } execution.setVariable(G_CURRENT_SEQUENCE, 0); execution.setVariable("retryCount", 0); execution.setVariable("flowsToExecute", flowsToExecute); } catch (Exception ex) { msoLogger.error(ex); buildAndThrowException(execution, "Exception in create execution list " + ex.getMessage(), ex); } } protected List sortVfModulesByBaseFirst(List vfModuleResources) { int count = 0; for(Resource resource : vfModuleResources){ if(resource.isBaseVfModule()){ Collections.swap(vfModuleResources, 0, count); break; } count++; } return vfModuleResources; } private void updateResourceIdsFromAAITraversal(List flowsToExecute, List resourceCounter, List> aaiResourceIds) { for(Pair pair : aaiResourceIds){ msoLogger.debug(pair.getValue0() + ", " + pair.getValue1()); } Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> { List resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()); for(int i = 0; i < resources.size(); i++){ updateWorkflowResourceIds(flowsToExecute, type, resources.get(i).getResourceId(), retrieveAAIResourceId(aaiResourceIds,type), null); } }); } private String retrieveAAIResourceId(List> aaiResourceIds, WorkflowType resource){ String id = null; for(int i = 0; i flowsToExecute, List resourceCounter) { Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> { List resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()); for(int i = 0; i < resources.size(); i++){ Resource resource = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())) .collect(Collectors.toList()).get(i); updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null, resource.getVirtualLinkKey()); } }); } protected void updateWorkflowResourceIds(List flowsToExecute, WorkflowType resource, String key, String id, String virtualLinkKey){ String resourceId = id; if(resourceId==null){ resourceId = UUID.randomUUID().toString(); } for(ExecuteBuildingBlock ebb : flowsToExecute){ if(key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && ebb.getBuildingBlock().getBpmnFlowName().contains(resource.toString())){ WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds(); if(resource == WorkflowType.VNF){ workflowResourceIds.setVnfId(resourceId); }else if(resource == WorkflowType.VFMODULE){ workflowResourceIds.setVfModuleId(resourceId); }else if(resource == WorkflowType.VOLUMEGROUP){ workflowResourceIds.setVolumeGroupId(resourceId); }else if(resource == WorkflowType.NETWORK){ workflowResourceIds.setNetworkId(resourceId); }else if(resource == WorkflowType.NETWORKCOLLECTION){ workflowResourceIds.setNetworkCollectionId(resourceId); } ebb.setWorkflowResourceIds(workflowResourceIds); } if(virtualLinkKey != null && ebb.getBuildingBlock().getIsVirtualLink() && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) { WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds(); workflowResourceIds.setNetworkId(resourceId); ebb.setWorkflowResourceIds(workflowResourceIds); } } } protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution, org.onap.so.db.catalog.beans.Service service) { CollectionResourceCustomization networkCollection = null; int count = 0; for(CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()){ if(catalogDbClient.getNetworkCollectionResourceCustomizationByID(collectionCust.getModelCustomizationUUID()) instanceof NetworkCollectionResourceCustomization) { networkCollection = collectionCust; count++; } } if(count == 0){ return null; }else if(count > 1) { buildAndThrowException(execution, "Found multiple Network Collections in the Service model, only one per Service is supported."); } return networkCollection; } protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest, List resourceCounter) { String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId(); org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID); if (service == null) { buildAndThrowException(execution, "Could not find the service model in catalog db."); } else { resourceCounter.add(new Resource(WorkflowType.SERVICE,service.getModelUUID(),false)); if (service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty()) { List customizations = service.getCollectionResourceCustomizations(); if(customizations.isEmpty()) { msoLogger.debug("No Collections found. CollectionResourceCustomization list is empty."); }else{ CollectionResourceCustomization collectionResourceCustomization = findCatalogNetworkCollection(execution, service); if(collectionResourceCustomization!=null){ resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,collectionResourceCustomization.getModelCustomizationUUID(),false)); msoLogger.debug("Found a network collection"); if(collectionResourceCustomization.getCollectionResource()!=null){ if(collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null){ String toscaNodeType = collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType(); if (toscaNodeType != null && toscaNodeType.contains("NetworkCollection")) { int minNetworks = 0; InstanceGroup instanceGroup = collectionResourceCustomization.getCollectionResource().getInstanceGroup(); CollectionResourceInstanceGroupCustomization collectionInstCust = null; if(!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) { for(CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup.getCollectionInstanceGroupCustomizations()) { if(collectionInstanceGroupTemp.getModelCustomizationUUID().equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) { collectionInstCust = collectionInstanceGroupTemp; break; } } if(collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null) { minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity(); } } msoLogger.debug("minNetworks: " + minNetworks); CollectionNetworkResourceCustomization collectionNetworkResourceCust = null; for(CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup.getCollectionNetworkResourceCustomizations()) { if(collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID().equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) { collectionNetworkResourceCust = collectionNetworkTemp; break; } } for (int i = 0; i < minNetworks; i++) { if(collectionNetworkResourceCust != null && collectionInstCust != null) { Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,collectionNetworkResourceCust.getModelCustomizationUUID(),false); resource.setVirtualLinkKey(Integer.toString(i)); resourceCounter.add(resource); } } } else { msoLogger.debug("Instance Group tosca node type does not contain NetworkCollection: " + toscaNodeType); } }else{ msoLogger.debug("No Instance Group found for network collection."); } }else{ msoLogger.debug("No Network Collection found. collectionResource is null"); } } else { msoLogger.debug("No Network Collection Customization found"); } } if (resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) { if (service.getNetworkCustomizations() == null) { msoLogger.debug("No networks were found on this service model"); } else { for (int i = 0; i < service.getNetworkCustomizations().size(); i++) { resourceCounter.add(new Resource(WorkflowType.NETWORK,service.getNetworkCustomizations().get(i).getModelCustomizationUUID(),false)); } } } } else { 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"); } } } protected void traverseAAIService(DelegateExecution execution, List resourceCounter, String resourceId, List> aaiResourceIds) { try { ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId); 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()) { aaiResourceIds.add(new Pair(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.VFMODULE, vfModule.getVfModuleId())); resourceCounter.add(new Resource(WorkflowType.VFMODULE,vfModule.getVfModuleId(),false)); } } if (vnf.getVolumeGroups() != null) { for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf .getVolumeGroups()) { aaiResourceIds.add(new Pair(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId())); resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,volumeGroup.getVolumeGroupId(),false)); } } } } if (serviceInstanceMSO.getNetworks() != null) { for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO .getNetworks()) { aaiResourceIds.add(new Pair(WorkflowType.NETWORK, network.getNetworkId())); resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getNetworkId(),false)); } } if (serviceInstanceMSO.getCollection() != null) { msoLogger.debug("found networkcollection"); aaiResourceIds.add(new Pair(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId())); resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,serviceInstanceMSO.getCollection().getId(),false)); } } catch (Exception ex) { buildAndThrowException(execution, "Could not find existing Service Instance or related Instances to execute the request on."); } } protected boolean traverseUserParamsService(DelegateExecution execution, List resourceCounter, ServiceInstancesRequest sIRequest, String requestAction) throws IOException { boolean foundRelated = false; boolean foundVfModuleOrVG = false; if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) { List> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams(); for (Map params : userParams) { if (params.containsKey(USERPARAMSERVICE)) { ObjectMapper obj = new ObjectMapper(); String input = obj.writeValueAsString(params.get(USERPARAMSERVICE)); Service validate = obj.readValue(input, Service.class); resourceCounter.add(new Resource(WorkflowType.SERVICE,validate.getModelInfo().getModelVersionId(),false)); if (validate.getResources().getVnfs() != null) { for (Vnfs vnf : validate.getResources().getVnfs()) { resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getModelInfo().getModelCustomizationId(),false)); foundRelated = true; if (vnf.getVfModules() != null) { for (VfModules vfModule : vnf.getVfModules()) { VfModuleCustomization vfModuleCustomization = catalogDbClient .getVfModuleCustomizationByModelCuztomizationUUID( vfModule.getModelInfo().getModelCustomizationUuid()); if (vfModuleCustomization != null) { if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getVolumeHeatTemplate()!=null &&vfModuleCustomization.getVolumeHeatEnv() != null) { resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,vfModuleCustomization.getModelCustomizationUUID(),false)); foundRelated = true; foundVfModuleOrVG = true; } if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getModuleHeatTemplate()!=null && vfModuleCustomization.getHeatEnvironment()!=null){ foundRelated = true; foundVfModuleOrVG = true; Resource resource = new Resource(WorkflowType.VFMODULE,vfModuleCustomization.getModelCustomizationUUID(),false); if(vfModuleCustomization.getVfModule().getIsBase()!=null && vfModuleCustomization.getVfModule().getIsBase()){ resource.setBaseVfModule(true); }else{ resource.setBaseVfModule(false); } resourceCounter.add(resource); } if(!foundVfModuleOrVG){ buildAndThrowException(execution, "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null"); } } } } } } if (validate.getResources().getNetworks() != null) { for (Networks network : validate.getResources().getNetworks()) { resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getModelInfo().getModelCustomizationId(),false)); foundRelated = true; } if (requestAction.equals(CREATEINSTANCE)) { String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest); if (networkColCustId != null) { resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,networkColCustId,false)); foundRelated = true; } } } break; } } } return foundRelated; } protected String queryCatalogDBforNetworkCollection(DelegateExecution execution, ServiceInstancesRequest sIRequest) { org.onap.so.db.catalog.beans.Service service = catalogDbClient .getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId()); if (service != null) { CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service); if(networkCollection != null) { return networkCollection.getModelCustomizationUUID(); } } return null; } protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) { WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds(); workflowResourceIds.setServiceInstanceId((String) execution.getVariable("serviceInstanceId")); workflowResourceIds.setNetworkId((String) execution.getVariable("networkId")); workflowResourceIds.setVfModuleId((String) execution.getVariable("vfModuleId")); workflowResourceIds.setVnfId((String) execution.getVariable("vnfId")); workflowResourceIds.setVolumeGroupId((String) execution.getVariable("volumeGroupId")); return workflowResourceIds; } protected Resource extractResourceIdAndTypeFromUri(String uri) { Pattern patt = Pattern.compile( "[vV]\\d+.*?(?:(?:/(?" + supportedTypes + ")(?:/(?[^/]+))?)(?:/(?[^/]+))?)?$"); Matcher m = patt.matcher(uri); Boolean generated = false; if (m.find()) { msoLogger.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("serviceInstances") && (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); } } protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName, RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception { try { if ("SERVICE".equalsIgnoreCase(type.toString())) { String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId(); String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType(); if (instanceName != null) { Optional serviceInstanceAAI = bbInputSetupUtils .getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName); if (serviceInstanceAAI.isPresent()) { return serviceInstanceAAI.get().getServiceInstanceId(); } } } else if ("NETWORK".equalsIgnoreCase(type.toString())) { Optional network = bbInputSetupUtils.getRelatedNetworkByNameFromServiceInstance( workflowResourceIds.getServiceInstanceId(), instanceName); if (network.isPresent()) { return network.get().getNetworkId(); } } else if ("VNF".equalsIgnoreCase(type.toString())) { Optional vnf = bbInputSetupUtils.getRelatedVnfByNameFromServiceInstance( workflowResourceIds.getServiceInstanceId(), instanceName); if (vnf.isPresent()) { return vnf.get().getVnfId(); } } else if ("VFMODULE".equalsIgnoreCase(type.toString())) { GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId()); if (vnf != null && vnf.getVfModules() != null) { for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) { if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) { return vfModule.getVfModuleId(); } } } } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) { Optional volumeGroup = bbInputSetupUtils .getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName); if (volumeGroup.isPresent()) { return volumeGroup.get().getVolumeGroupId(); } GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId()); if (vnf != null && vnf.getVfModules() != null) { for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) { Optional volumeGroupFromVfModule = bbInputSetupUtils .getRelatedVolumeGroupByNameFromVfModule(vnf.getVnfId(), vfModule.getVfModuleId(), instanceName); if (volumeGroupFromVfModule.isPresent()) { return volumeGroupFromVfModule.get().getVolumeGroupId(); } } } } return generatedResourceId; } catch (Exception ex) { msoLogger.error(ex); throw new IllegalStateException( "WorkflowAction was unable to verify if the instance name already exist in AAI."); } } protected String convertTypeFromPlural(String type) { if (!type.matches(supportedTypes)) { return type; } else { if (type.equals("serviceInstances")) { return SERVICE; } else { return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1); } } } protected List sortExecutionPathByObjectForVlanTagging(List orchFlows, String requestAction) { List sortedOrchFlows = new ArrayList<>(); if (requestAction.equals(CREATEINSTANCE)) { for (ExecuteBuildingBlock ebb : orchFlows) { if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) { String key = ebb.getBuildingBlock().getKey(); boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().getIsVirtualLink()); String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey(); sortedOrchFlows.add(ebb); for (ExecuteBuildingBlock ebb2 : orchFlows) { if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB") && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) { sortedOrchFlows.add(ebb2); break; } if(isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB") && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) { sortedOrchFlows.add(ebb2); break; } } for (ExecuteBuildingBlock ebb2 : orchFlows) { if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB") && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) { sortedOrchFlows.add(ebb2); break; } if(isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB") && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) { sortedOrchFlows.add(ebb2); break; } } } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB") || ebb.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")) { continue; } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) { sortedOrchFlows.add(ebb); } } } else if (requestAction.equals("deleteInstance")) { for (ExecuteBuildingBlock ebb : orchFlows) { if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) { sortedOrchFlows.add(ebb); String key = ebb.getBuildingBlock().getKey(); for (ExecuteBuildingBlock ebb2 : orchFlows) { if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB") && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) { sortedOrchFlows.add(ebb2); break; } } for (ExecuteBuildingBlock ebb2 : orchFlows) { if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB") && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) { sortedOrchFlows.add(ebb2); break; } } } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB") || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) { continue; } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) { sortedOrchFlows.add(ebb); } } } return sortedOrchFlows; } protected List buildExecuteBuildingBlockList(List orchFlows, List resourceCounter, String requestId, String apiVersion, String resourceId, WorkflowType resourceType, String requestAction, boolean aLaCarte, String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails) { List flowsToExecute = new ArrayList<>(); for (OrchestrationFlow orchFlow : orchFlows) { if (orchFlow.getFlowName().contains(SERVICE)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType()).collect(Collectors.toList()).size(); i++) { workflowResourceIds.setServiceInstanceId(resourceId); flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else if (orchFlow.getFlowName().contains(VNF)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType()).collect(Collectors.toList()).size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else if (orchFlow.getFlowName().contains(NETWORK) && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType()).collect(Collectors.toList()).size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType()).collect(Collectors.toList()).size(); i++) { Resource resource = resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType()) .collect(Collectors.toList()).get(i); flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource.getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, true, resource.getVirtualLinkKey())); } } else if (orchFlow.getFlowName().contains(VFMODULE)) { List vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceCounter.stream().filter(x -> WorkflowType.VFMODULE == x.getResourceType()) .collect(Collectors.toList())); for (int i = 0; i < vfModuleResourcesSorted.size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType()).collect(Collectors.toList()).size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else if (orchFlow.getFlowName().contains(CONFIGURATION)) { for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.CONFIGURATION == x.getResourceType()).collect(Collectors.toList()).size(); i++) { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.CONFIGURATION == x.getResourceType()) .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } else { flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, "", apiVersion, resourceId, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null)); } } return flowsToExecute; } protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId, String key, String apiVersion, String resourceId, String requestAction, boolean aLaCarte, String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean isVirtualLink, String virtualLinkKey) { ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock(); BuildingBlock buildingBlock = new BuildingBlock(); buildingBlock.setBpmnFlowName(orchFlow.getFlowName()); buildingBlock.setMsoId(UUID.randomUUID().toString()); buildingBlock.setKey(key); buildingBlock.setIsVirtualLink(isVirtualLink); buildingBlock.setVirtualLinkKey(virtualLinkKey); executeBuildingBlock.setApiVersion(apiVersion); executeBuildingBlock.setaLaCarte(aLaCarte); executeBuildingBlock.setRequestAction(requestAction); executeBuildingBlock.setResourceId(resourceId); executeBuildingBlock.setVnfType(vnfType); executeBuildingBlock.setWorkflowResourceIds(workflowResourceIds); executeBuildingBlock.setRequestId(requestId); executeBuildingBlock.setBuildingBlock(buildingBlock); executeBuildingBlock.setRequestDetails(requestDetails); return executeBuildingBlock; } protected List queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction, WorkflowType resourceName, boolean aLaCarte) { List listToExecute = new ArrayList<>(); NorthBoundRequest northBoundRequest = catalogDbClient .getNorthBoundRequestByActionAndIsALaCarteAndRequestScope(requestAction, resourceName.toString(), aLaCarte); if(northBoundRequest == null){ if(aLaCarte){ buildAndThrowException(execution,"The request: ALaCarte " + resourceName + " " + requestAction + " is not supported by GR_API."); }else{ buildAndThrowException(execution,"The request: Macro " + resourceName + " " + requestAction + " is not supported by GR_API."); } } else { if(northBoundRequest.getIsToplevelflow()!=null){ execution.setVariable(G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow()); } List flows = northBoundRequest.getOrchestrationFlowList(); if (flows == null) flows = new ArrayList<>(); for (OrchestrationFlow flow : flows) { if (!flow.getFlowName().contains("BB")) { List macroQueryFlows = catalogDbClient .getOrchestrationFlowByAction(flow.getFlowName()); for (OrchestrationFlow macroFlow : macroQueryFlows) { listToExecute.add(macroFlow); } } else { listToExecute.add(flow); } } } return listToExecute; } protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) { msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, msg, ex); execution.setVariable("WorkflowActionErrorMessage", msg); exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg); } protected void buildAndThrowException(DelegateExecution execution, String msg) { msoLogger.error(msg); execution.setVariable("WorkflowActionErrorMessage", msg); exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg); } public void handleRuntimeException (DelegateExecution execution){ StringBuffer wfeExpMsg = new StringBuffer("Runtime error "); String runtimeErrorMessage = null; try{ String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg"); if (javaExpMsg != null && !javaExpMsg.isEmpty()) { wfeExpMsg = wfeExpMsg.append(": ").append(javaExpMsg); } runtimeErrorMessage = wfeExpMsg.toString(); msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, runtimeErrorMessage, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, runtimeErrorMessage); execution.setVariable("WorkflowActionErrorMessage", runtimeErrorMessage); } catch (Exception e){ //if runtime message was mulformed runtimeErrorMessage = "Runtime error"; } exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage); } }