Merge branch 'recursive-orch'
[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     private static final String HEALTH_CHECK = "HealthCheckBB";
58     private static final String UPGRADE_CNF = "UpgradeVfModuleBB";
59
60     protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
61             List<Resource> originalResourceList, String requestId, String apiVersion, String resourceId,
62             String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
63             RequestDetails requestDetails, boolean replaceVnf) {
64         List<Resource> resourceList = getOnlyRootResourceList(originalResourceList);
65
66         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
67
68         boolean ascendingOrder = requestAction.equals(CREATE_INSTANCE) || requestAction.equals(ASSIGN_INSTANCE)
69                 || requestAction.equals(ACTIVATE_INSTANCE);
70
71         ExecutionPlan plan = ExecutionPlan.build(resourceList, ascendingOrder);
72
73         logger.info("Orchestration Flows");
74         for (OrchestrationFlow orchFlow : orchFlows) {
75             String flowDetails = new ToStringBuilder(this).append("id", orchFlow.getId())
76                     .append("action", orchFlow.getAction()).append("sequenceNumber", orchFlow.getSequenceNumber())
77                     .append("flowName", orchFlow.getFlowName()).append("flowVersion", orchFlow.getFlowVersion())
78                     .append("bpmnAction", orchFlow.getBpmnAction()).append("bpmnScope", orchFlow.getBpmnScope())
79                     .toString();
80             logger.info("Flow: " + flowDetails);
81             buildExecuteBuildingBlockListPlan(orchFlow, plan, requestId, apiVersion, resourceId, requestAction, vnfType,
82                     workflowResourceIds, requestDetails, replaceVnf);
83         }
84
85         plan.flushBlocksFromCache(flowsToExecute);
86
87         return flowsToExecute;
88     }
89
90     protected void buildExecuteBuildingBlockListPlan(OrchestrationFlow flow, ExecutionPlan plan, String requestId,
91             String apiVersion, String resourceId, String requestAction, String vnfType,
92             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
93
94         List<ExecuteBuildingBlock> mainFlows = buildExecuteBuildingBlockListRaw(flow, plan.getResource(), requestId,
95                 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, replaceVnf);
96
97         plan.pushBlockToCache(mainFlows);
98
99         for (ExecutionGroup nestedGroup : plan.getNestedExecutions()) {
100             for (ExecutionPlan nestedPlan : nestedGroup.getNestedExecutions()) {
101                 buildExecuteBuildingBlockListPlan(flow, nestedPlan, requestId, apiVersion, resourceId, requestAction,
102                         vnfType, workflowResourceIds, requestDetails, replaceVnf);
103             }
104             if (nestedGroup.getCacheSize() > 0)
105                 plan.changeCurrentGroup(nestedGroup);
106         }
107     }
108
109     private List<ExecuteBuildingBlock> buildExecuteBuildingBlockListRaw(OrchestrationFlow orchFlow, Resource resource,
110             String requestId, String apiVersion, String resourceId, String requestAction, String vnfType,
111             WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean replaceVnf) {
112         List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
113         if (orchFlow.getFlowName().contains(CHILD_SERVICE)) {
114             if (WorkflowType.SERVICE.equals(resource.getResourceType()) && resource.hasParent()) {
115                 addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.SERVICE, orchFlow, requestId,
116                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
117                         false);
118             }
119         } else if (orchFlow.getFlowName().contains(SERVICE) || (orchFlow.getFlowName().contains(CONTROLLER)
120                 && (SERVICE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
121             if (!replaceVnf) {
122                 workflowResourceIds.setServiceInstanceId(resourceId);
123             }
124             if (!resource.hasParent()) {
125                 addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.SERVICE, orchFlow, requestId,
126                         apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
127                         false);
128             }
129         } else if (orchFlow.getFlowName().contains(VNF)
130                 || (orchFlow.getFlowName().contains(CONTROLLER) && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
131             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
132                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
133         } else if ((orchFlow.getFlowName().equalsIgnoreCase(HEALTH_CHECK))
134                 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope())) {
135             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
136                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
137         } else if ((orchFlow.getFlowName().equalsIgnoreCase(UPGRADE_CNF))
138                 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope())) {
139             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VNF, orchFlow, requestId, apiVersion,
140                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
141         } else if (orchFlow.getFlowName().contains(PNF)
142                 || (orchFlow.getFlowName().contains(CONTROLLER) && (PNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
143             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.PNF, orchFlow, requestId, apiVersion,
144                     resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
145         } else if (orchFlow.getFlowName().contains(NETWORK) && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
146             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORK, orchFlow, requestId,
147                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
148             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VIRTUAL_LINK, orchFlow, requestId,
149                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, true, false);
150         } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
151                 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
152             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VFMODULE, orchFlow, requestId,
153                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
154         } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
155             if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
156                     || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
157                 logger.debug("Replacing workflow resource id by volume group id");
158                 resourceId = workflowResourceIds.getVolumeGroupId();
159             }
160             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.VOLUMEGROUP, orchFlow, requestId,
161                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, false);
162         } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
163             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.NETWORKCOLLECTION, orchFlow,
164                     requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
165                     false, false);
166         } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
167             addBuildingBlockToExecuteBBList(flowsToExecute, resource, WorkflowType.CONFIGURATION, orchFlow, requestId,
168                     apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false, true);
169         } else {
170             flowsToExecute
171                     .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
172                             false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
173         }
174         return flowsToExecute;
175     }
176
177     protected List<Resource> getOnlyRootResourceList(List<Resource> resourceList) {
178         return resourceList.stream().filter(x -> countResourceOnTheResourceList(x, resourceList) == 1)
179                 .collect(Collectors.toList());
180     }
181
182     protected int countResourceOnTheResourceList(Resource resource, List<Resource> resourceList) {
183         int count = resourceList.stream()
184                 .mapToInt(x -> (x.equals(resource) ? 1 : 0) + countResourceOnTheResourceList(resource, x.getChildren()))
185                 .reduce(0, Integer::sum);
186         return count;
187     }
188
189     protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
190             Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
191             String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
192             boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
193             ReplaceInstanceRelatedInformation replaceInfo) {
194
195         BuildingBlock buildingBlock =
196                 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
197                         .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
198                         .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
199         Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
200         Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
201         String oldVolumeGroupName = "";
202         if (replaceInfo != null) {
203             oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
204         }
205         if (resource != null
206                 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
207                         || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
208             logger.debug("Setting resourceId to volume group id for volume group flow on replace");
209             resourceId = workflowResourceIds.getVolumeGroupId();
210         }
211
212         ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
213                 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
214                 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
215                 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
216
217         if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
218             ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
219             executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
220         }
221         return executeBuildingBlock;
222     }
223
224     private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, Resource resource,
225             WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
226             String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
227             RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
228
229         if (resource == null || !resource.getResourceType().equals(workflowType))
230             return;
231         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
232                 requestAction, false, vnfType, workflowResourceIds, requestDetails, isVirtualLink,
233                 resource.getVirtualLinkKey(), null, isConfiguration, null));
234     }
235
236     protected ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
237         ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
238         Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
239         configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
240         configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
241         configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
242         return configurationResourceKeys;
243     }
244 }