Fix macro flow resource blocks processing order
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / ExecuteBuildingBlockBuilder.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ================================================================================
9  * Modifications Copyright (c) 2021 Nokia
10  * ================================================================================
11  * Modifications Copyright (c) 2020 Tech Mahindra
12  * ================================================================================
13  * Modifications Copyright (c) 2021 Orange
14  * ================================================================================
15  * Licensed under the Apache License, Version 2.0 (the "License");
16  * you may not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  *      http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an "AS IS" BASIS,
23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  * ============LICENSE_END=========================================================
27  */
28
29 package org.onap.so.bpmn.infrastructure.workflow.tasks;
30
31 import org.apache.commons.lang3.builder.ToStringBuilder;
32 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
33 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
34 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
35 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
36 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
37 import org.onap.so.serviceinstancebeans.RequestDetails;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.stereotype.Component;
41 import java.util.ArrayList;
42 import java.util.List;
43 import java.util.Optional;
44 import java.util.UUID;
45 import java.util.stream.Collectors;
46 import static org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowActionConstants.*;
47
48 @Component
49 public class ExecuteBuildingBlockBuilder {
50
51     private static final Logger logger = LoggerFactory.getLogger(ExecuteBuildingBlockBuilder.class);
52
53     private static final String VNF = "Vnf";
54     private static final String PNF = "Pnf";
55     private static final String VFMODULE = "VfModule";
56     private static final String NETWORK = "Network";
57
58     protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
59             List<Resource> originalResourceList, String requestId, String apiVersion, String resourceId,
60             String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
61             RequestDetails requestDetails, boolean replaceVnf) {
62         List<Resource> resourceList = getOnlyRootResourceList(originalResourceList);
63
64         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
65
66         boolean ascendingOrder = requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE)
67                 || requestAction.equals(ACTIVATE_INSTANCE);
68
69         ExecutionPlan plan = ExecutionPlan.build(resourceList, ascendingOrder);
70
71         logger.info("Orchestration Flows");
72         for (OrchestrationFlow orchFlow : orchFlows) {
73             String flowDetails = new ToStringBuilder(this).append("id", orchFlow.getId())
74                     .append("action", orchFlow.getAction()).append("sequenceNumber", orchFlow.getSequenceNumber())
75                     .append("flowName", orchFlow.getFlowName()).append("flowVersion", orchFlow.getFlowVersion())
76                     .append("bpmnAction", orchFlow.getBpmnAction()).append("bpmnScope", orchFlow.getBpmnScope())
77                     .toString();
78             logger.info("Flow: " + flowDetails);
79             buildExecuteBuildingBlockListPlan(orchFlow, plan, requestId, apiVersion, resourceId, requestAction, vnfType,
80                     workflowResourceIds, requestDetails, replaceVnf);
81         }
82
83         plan.flushBlocksFromCache(flowsToExecute);
84
85         return flowsToExecute;
86     }
87
88     protected void buildExecuteBuildingBlockListPlan(OrchestrationFlow flow, ExecutionPlan plan, String requestId,
89             String apiVersion, String resourceId, String requestAction, String vnfType,
90             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
91
92         List<ExecuteBuildingBlock> mainFlows = buildExecuteBuildingBlockListRaw(flow, plan.getResource(), requestId,
93                 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, replaceVnf);
94
95         plan.pushBlockToCache(mainFlows);
96
97         for (ExecutionGroup nestedGroup : plan.getNestedExecutions()) {
98             for (ExecutionPlan nestedPlan : nestedGroup.getNestedExecutions()) {
99                 buildExecuteBuildingBlockListPlan(flow, nestedPlan, requestId, apiVersion, resourceId, requestAction,
100                         vnfType, workflowResourceIds, requestDetails, replaceVnf);
101             }
102             if (nestedGroup.getCacheSize() > 0)
103                 plan.changeCurrentGroup(nestedGroup);
104         }
105     }
106
107     private List<ExecuteBuildingBlock> buildExecuteBuildingBlockListRaw(OrchestrationFlow orchFlow, Resource resource,
108             String requestId, String apiVersion, String resourceId, String requestAction, String vnfType,
109             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
110         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
111         if (orchFlow.getFlowName().contains(SERVICE) || (orchFlow.getFlowName().contains(CONTROLLER)
112                 && (SERVICE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
113             if (!replaceVnf) {
114                 workflowResourceIds.setServiceInstanceId(resourceId);
115             }
116             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.SERVICE, orchFlow, requestId,
117                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
118         } else if (orchFlow.getFlowName().contains(VNF)
119                 || (orchFlow.getFlowName().contains(CONTROLLER) && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
120             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
121                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
122         } else if (orchFlow.getFlowName().contains(PNF)
123                 || (orchFlow.getFlowName().contains(CONTROLLER) && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
124             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.PNF, orchFlow, requestId, apiVersion,
125                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
126         } else if (orchFlow.getFlowName().contains(NETWORK) && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
127             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORK, orchFlow, requestId,
128                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
129             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VIRTUAL_LINK, orchFlow, requestId,
130                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, true, false);
131         } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
132                 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
133             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VFMODULE, orchFlow, requestId,
134                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
135         } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
136             if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
137                     || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
138                 logger.debug("Replacing workflow resource id by volume group id");
139                 resourceId = workflowResourceIds.getVolumeGroupId();
140             }
141             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VOLUMEGROUP, orchFlow, requestId,
142                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
143         } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
144             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORKCOLLECTION, orchFlow,
145                     requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
146                     false, false);
147         } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
148             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.CONFIGURATION, orchFlow, requestId,
149                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, true);
150         } else {
151             flowsToExecute
152                     .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
153                             false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
154         }
155         return flowsToExecute;
156     }
157
158     protected List<Resource> getOnlyRootResourceList(List<Resource> resourceList) {
159         return resourceList.stream().filter(x -> countResourceOnTheResourceList(x, resourceList) == 1)
160                 .collect(Collectors.toList());
161     }
162
163     protected int countResourceOnTheResourceList(Resource resource, List<Resource> resourceList) {
164         int count = resourceList.stream()
165                 .mapToInt(x -> (x.equals(resource) ? 1 : 0) + countResourceOnTheResourceList(resource, x.getChildren()))
166                 .reduce(0, Integer::sum);
167         return count;
168     }
169
170     protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
171             Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
172             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
173             boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
174             ReplaceInstanceRelatedInformation replaceInfo) {
175
176         BuildingBlock buildingBlock =
177                 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
178                         .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
179                         .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
180         Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
181         Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
182         String oldVolumeGroupName = "";
183         if (replaceInfo != null) {
184             oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
185         }
186         if (resource != null
187                 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
188                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
189             logger.debug("Setting resourceId to volume group id for volume group flow on replace");
190             resourceId = workflowResourceIds.getVolumeGroupId();
191         }
192
193         ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
194                 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
195                 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
196                 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
197
198         if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
199             ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
200             executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
201         }
202         return executeBuildingBlock;
203     }
204
205     private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, Resource resource,
206             WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
207             String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
208             RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
209
210         if (resource == null || !resource.getResourceType().equals(workflowType))
211             return;
212         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
213                 requestAction, false, vnfType, workflowResourceIds, requestDetails, isVirtualLink,
214                 resource.getVirtualLinkKey(), null, isConfiguration, null));
215     }
216
217     protected ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
218         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
219         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
220         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
221         configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
222         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
223         return configurationResourceKeys;
224     }
225 }