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