* ================================================================================
* Modifications Copyright (c) 2020 Tech Mahindra
* ================================================================================
+ * 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
package org.onap.so.bpmn.infrastructure.workflow.tasks;
-import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGNINSTANCE;
+import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.IS_CHILD_PROCESS;
+import static org.onap.so.bpmn.infrastructure.service.composition.ServiceCompositionConstants.PARENT_CORRELATION_ID;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.ASSIGN_INSTANCE;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CONTROLLER;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.CREATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.DELETE_INSTANCE;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.FABRIC_CONFIGURATION;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.RECREATE_INSTANCE;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCE;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.REPLACEINSTANCERETAINASSIGNMENTS;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.SERVICE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPDATE_INSTANCE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.HEALTH_CHECK;
import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.WORKFLOW_ACTION_ERROR_MESSAGE;
+import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.UPGRADE_CNF;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.javatuples.Pair;
import org.onap.aai.domain.yang.Vnfc;
import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types;
+import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.NetworkSliceSubnetEBBLoader;
import org.onap.so.bpmn.common.BBConstants;
+import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.PnfEBBLoader;
import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.ServiceEBBLoader;
import org.onap.so.bpmn.infrastructure.workflow.tasks.ebb.loader.VnfEBBLoader;
import org.onap.so.bpmn.infrastructure.workflow.tasks.excpetion.VnfcMultipleRelationshipException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.so.serviceinstancebeans.InstanceDirection;
@Component
public class WorkflowAction {
private static final String VNF_TYPE = "vnfType";
private static final String CONFIGURATION = "Configuration";
private static final String SUPPORTEDTYPES =
- "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
+ "vnfs|pnfs|cnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups|NetworkSliceSubnet";
private static final String HOMINGSOLUTION = "Homing_Solution";
private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
private static final String SERVICE_TYPE_BONDING = "BONDING";
@Autowired
private VnfEBBLoader vnfEBBLoader;
@Autowired
+ private PnfEBBLoader pnfEBBLoader;
+ @Autowired
private ServiceEBBLoader serviceEBBLoader;
+ @Autowired
+ private NetworkSliceSubnetEBBLoader networkSliceSubnetEBBLoader;
public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
this.bbInputSetupUtils = bbInputSetupUtils;
List<Resource> resourceList = new ArrayList<>();
List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
- if (resourceType == WorkflowType.SERVICE) {
+ if (resourceType == WorkflowType.SERVICE || isVNFCreate(resourceType, requestAction)
+ || isPNFCreate(resourceType, requestAction)) {
resourceList = serviceEBBLoader.getResourceListForService(sIRequest, requestAction, execution,
serviceInstanceId, resourceId, aaiResourceIds);
- } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
- || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
+ } else if (resourceType == WorkflowType.NETWORK_SLICE_SUBNET) {
+ resourceList = networkSliceSubnetEBBLoader.setNetworkSliceSubnetResource(resourceId);
+ } else if (isPNFDelete(resourceType, requestAction)) {
+ pnfEBBLoader.traverseAAIPnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(), resourceId,
+ aaiResourceIds);
+ } else if (isPNFUpdate(resourceType, requestAction)) {
+ pnfEBBLoader.traverseAAIPnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(), resourceId,
+ aaiResourceIds);
+ } else if (resourceType == WorkflowType.VNF
+ && (DELETE_INSTANCE.equalsIgnoreCase(requestAction) || REPLACEINSTANCE.equalsIgnoreCase(requestAction)
+ || (RECREATE_INSTANCE.equalsIgnoreCase(requestAction)))) {
vnfEBBLoader.traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
workflowResourceIds.getVnfId(), aaiResourceIds);
- } else if (resourceType == WorkflowType.VNF && "updateInstance".equalsIgnoreCase(requestAction)) {
+ } else if (resourceType == WorkflowType.VNF && UPDATE_INSTANCE.equalsIgnoreCase(requestAction)) {
+ vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+ workflowResourceIds.getVnfId(), aaiResourceIds);
+ } else if (resourceType == WorkflowType.VNF && HEALTH_CHECK.equalsIgnoreCase(requestAction)) {
+ vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
+ workflowResourceIds.getVnfId(), aaiResourceIds);
+ } else if (resourceType == WorkflowType.VNF && UPGRADE_CNF.equalsIgnoreCase(requestAction)) {
vnfEBBLoader.customTraverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
workflowResourceIds.getVnfId(), aaiResourceIds);
} else {
logger.info("Sorting for Vlan Tagging");
flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
}
+ logger.info("Building Block Execution Order");
+ for (ExecuteBuildingBlock block : flowsToExecute) {
+ Resource res = resourceList.stream()
+ .filter(resource -> resource.getResourceId() == block.getBuildingBlock().getKey()).findAny()
+ .orElse(null);
+ String log = "Block: " + block.getBuildingBlock().getBpmnFlowName();
+ if (res != null) {
+ log += ", Resource: " + res.getResourceType() + "[" + res.getResourceId() + "]";
+ log += ", Priority: " + res.getProcessingPriority();
+ if (res.getResourceType() == WorkflowType.VFMODULE)
+ log += ", Base: " + res.isBaseVfModule();
+ }
+ if (block.getBuildingBlock().getBpmnScope() != null)
+ log += ", Scope: " + block.getBuildingBlock().getBpmnScope();
+ if (block.getBuildingBlock().getBpmnAction() != null)
+ log += ", Action: " + block.getBuildingBlock().getBpmnAction();
+ logger.info(log);
+ }
+
+ RelatedInstanceList[] instanceList = sIRequest.getRequestDetails().getRelatedInstanceList();
+ execution.setVariable(IS_CHILD_PROCESS, Boolean.FALSE);
+ if (instanceList != null) {
+ for (RelatedInstanceList relatedInstanceList : instanceList) {
+ RelatedInstance relatedInstance = relatedInstanceList.getRelatedInstance();
+ if (InstanceDirection.source.equals(relatedInstance.getInstanceDirection())) {
+ execution.setVariable(IS_CHILD_PROCESS, Boolean.TRUE);
+ execution.setVariable(PARENT_CORRELATION_ID, requestDetails.getRequestInfo().getCorrelator());
+ }
+ }
+ }
+
// By default, enable homing at VNF level for CREATE_INSTANCE and ASSIGNINSTANCE
if (resourceType == WorkflowType.SERVICE
- && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGNINSTANCE))
+ && (requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE))
&& resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
execution.setVariable(HOMING, true);
execution.setVariable("calledHoming", false);
}
- if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
+ if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE)
|| requestAction.equalsIgnoreCase(CREATE_INSTANCE))) {
generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
} else {
updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds, serviceInstanceId);
}
+ execution.setVariable("resources", resourceList);
return flowsToExecute;
}
+ private boolean isVNFCreate(WorkflowType resourceType, String requestAction) {
+ return resourceType == WorkflowType.VNF && CREATE_INSTANCE.equalsIgnoreCase(requestAction);
+ }
+
+
+ private boolean isPNFCreate(WorkflowType resourceType, String requestAction) {
+ return resourceType == WorkflowType.PNF && CREATE_INSTANCE.equalsIgnoreCase(requestAction);
+ }
+
+
+ private boolean isPNFDelete(WorkflowType resourceType, String requestAction) {
+ return resourceType == WorkflowType.PNF && DELETE_INSTANCE.equalsIgnoreCase(requestAction);
+ }
+
+ private boolean isPNFUpdate(WorkflowType resourceType, String requestAction) {
+ return resourceType == WorkflowType.PNF && UPDATE_INSTANCE.equalsIgnoreCase(requestAction);
+ }
+
private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
List<String> flowNames) {
execution.setVariable("flowNames", flowNames);
resourceId = modelInfo.getModelCustomizationId();
}
}
- return new Resource(resourceType, resourceId, true);
+ return new Resource(resourceType, resourceId, true, null);
}
private String getCloudOwner(CloudConfiguration cloudConfiguration) {
for (Pair<WorkflowType, String> pair : aaiResourceIds) {
logger.debug("{}, {}", pair.getValue0(), pair.getValue1());
}
-
- Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
- .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
- .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
- retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
+ Map<Resource, String> resourceInstanceIds = new HashMap<>();
+ Arrays.stream(WorkflowType.values()).forEach(type -> resourceList.stream()
+ .filter(resource -> type.equals(resource.getResourceType())
+ && !(WorkflowType.SERVICE.equals(type) && !resource.hasParent()))
+ .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource,
+ retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId, resourceInstanceIds)));
}
private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
String serviceInstanceId) {
- Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
- .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
- .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
- null, resource.getVirtualLinkKey(), serviceInstanceId)));
+ Map<Resource, String> resourceInstanceIds = new HashMap<>();
+ Arrays.stream(WorkflowType.values())
+ .forEach(type -> resourceList.stream()
+ .filter(resource -> resource.hasParent() && type.equals(resource.getResourceType()))
+ .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource, null,
+ resource.getVirtualLinkKey(), serviceInstanceId, resourceInstanceIds)));
}
protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
- String key, String id, String virtualLinkKey, String serviceInstanceId) {
+ Resource resource, String id, String virtualLinkKey, String serviceInstanceId,
+ Map<Resource, String> resourceInstanceIds) {
+ String key = resource.getResourceId();
String resourceId = id;
if (resourceId == null) {
resourceId = UUID.randomUUID().toString();
}
+ resourceInstanceIds.put(resource, resourceId);
+ Set<String> assignedFlows = new LinkedHashSet<>();
for (ExecuteBuildingBlock ebb : flowsToExecute) {
- if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
- .getBpmnFlowName().contains(resourceType.toString())
- || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
- && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
+ String resourceTypeStr = resourceType.toString();
+ String flowName = ebb.getBuildingBlock().getBpmnFlowName();
+ String scope = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnScope());
+ String action = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnAction());
+
+ if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey())
+ && isFlowAssignable(assignedFlows, ebb, resourceType, flowName + action)
+ && (flowName.contains(resourceTypeStr)
+ || (flowName.contains(CONTROLLER) && resourceTypeStr.equalsIgnoreCase(scope)))) {
WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
workflowResourceIds.setServiceInstanceId(serviceInstanceId);
- WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
+ Resource parent = resource.getParent();
+ if (resource.hasParent() && resourceInstanceIds.containsKey(parent)) {
+ WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, parent.getResourceType(),
+ resourceInstanceIds.get(parent));
+ }
+ if (resource.hasParent() && WorkflowType.SERVICE.equals(resourceType)
+ && WorkflowType.SERVICE.equals(parent.getResourceType())) {
+ String childServiceInstanceId = resource.isGenerated() ? resourceId : resource.getResourceId();
+ workflowResourceIds.setChildServiceInstanceId(childServiceInstanceId);
+ workflowResourceIds.setChildServiceInstanceName(resource.getInstanceName());
+ } else {
+ WorkflowResourceIdsUtils.setInstanceNameByWorkflowType(workflowResourceIds, resourceType,
+ resource.getInstanceName());
+ WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
+ }
ebb.setWorkflowResourceIds(workflowResourceIds);
+ assignedFlows.add(flowName + action);
}
if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
&& virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
}
}
+ private boolean isFlowAssignable(Set<String> assignedFlows, ExecuteBuildingBlock ebb, WorkflowType resourceType,
+ String assignedFlowName) {
+ String id = WorkflowType.SERVICE.equals(resourceType)
+ ? StringUtils.defaultString(ebb.getWorkflowResourceIds().getChildServiceInstanceId())
+ : WorkflowResourceIdsUtils.getResourceIdByWorkflowType(ebb.getWorkflowResourceIds(), resourceType);
+ return !assignedFlows.contains(assignedFlowName) && id.isEmpty();
+ }
+
protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
}
type = action;
}
}
- return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
+ return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated, null);
} else {
throw new IllegalArgumentException("Uri could not be parsed: " + uri);
}
}
protected String convertTypeFromPlural(String type) {
- if (!type.matches(SUPPORTEDTYPES)) {
+ if (!type.matches(SUPPORTEDTYPES) || type.equals("NetworkSliceSubnet")) {
return type;
} else {
if (type.equals(SERVICE_INSTANCES)) {
protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
String serviceInstanceId) {
return (!aLaCarte && resourceType == WorkflowType.SERVICE
- && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
+ && (requestAction.equalsIgnoreCase(ASSIGN_INSTANCE) || requestAction.equalsIgnoreCase(CREATE_INSTANCE))
&& (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
&& (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
}