Containerization feature of SO
[so.git] / bpmn / so-bpmn-tasks / src / main / java / org / onap / so / bpmn / infrastructure / workflow / tasks / WorkflowAction.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.infrastructure.workflow.tasks;
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Optional;
30 import java.util.UUID;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import java.util.stream.Collectors;
34
35 import org.camunda.bpm.engine.delegate.DelegateExecution;
36 import org.javatuples.Pair;
37 import org.onap.aai.domain.yang.GenericVnf;
38 import org.onap.aai.domain.yang.L3Network;
39 import org.onap.aai.domain.yang.ServiceInstance;
40 import org.onap.aai.domain.yang.VolumeGroup;
41 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
42 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
43 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
44 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
45 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
46 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
47 import org.onap.so.client.exception.ExceptionBuilder;
48 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
49 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
50 import org.onap.so.db.catalog.beans.InstanceGroup;
51 import org.onap.so.db.catalog.beans.NetworkCollectionResourceCustomization;
52 import org.onap.so.db.catalog.beans.VfModuleCustomization;
53 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
54 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
55 import org.onap.so.db.catalog.client.CatalogDbClient;
56 import org.onap.so.logger.MessageEnum;
57 import org.onap.so.logger.MsoLogger;
58 import org.onap.so.serviceinstancebeans.ModelInfo;
59 import org.onap.so.serviceinstancebeans.ModelType;
60 import org.onap.so.serviceinstancebeans.Networks;
61 import org.onap.so.serviceinstancebeans.RequestDetails;
62 import org.onap.so.serviceinstancebeans.Service;
63 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
64 import org.onap.so.serviceinstancebeans.VfModules;
65 import org.onap.so.serviceinstancebeans.Vnfs;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.stereotype.Component;
68
69 import com.fasterxml.jackson.databind.ObjectMapper;
70
71 @Component
72 public class WorkflowAction {
73
74         private static final String G_ORCHESTRATION_FLOW = "gOrchestrationFlow";
75         private static final String G_ACTION = "requestAction";
76         private static final String G_CURRENT_SEQUENCE = "gCurrentSequence";
77         private static final String G_REQUEST_ID = "mso-request-id";
78         private static final String G_BPMN_REQUEST = "bpmnRequest";
79         private static final String G_ALACARTE = "aLaCarte";
80         private static final String G_APIVERSION = "apiVersion";
81         private static final String G_URI = "requestUri";
82         private static final String G_ISTOPLEVELFLOW = "isTopLevelFlow";
83         private static final String VNF_TYPE = "vnfType";
84         private static final String SERVICE = "Service";
85         private static final String VNF = "Vnf";
86         private static final String VFMODULE = "VfModule";
87         private static final String VOLUMEGROUP = "VolumeGroup";
88         private static final String NETWORK = "Network";
89         private static final String NETWORKCOLLECTION = "NetworkCollection";
90         private static final String ASSIGNINSTANCE = "assignInstance";
91         private static final String CREATEINSTANCE = "createInstance";
92         private static final String USERPARAMSERVICE = "service";
93         private static final String supportedTypes = "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances";
94         private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, WorkflowAction.class);
95         
96         @Autowired
97         protected BBInputSetup bbInputSetup;
98         @Autowired
99         protected BBInputSetupUtils bbInputSetupUtils;
100         @Autowired
101         private ExceptionBuilder exceptionBuilder;
102         @Autowired
103         private CatalogDbClient catalogDbClient;
104
105         public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
106                 this.bbInputSetupUtils = bbInputSetupUtils;
107         }
108
109         public void setBbInputSetup(BBInputSetup bbInputSetup) {
110                 this.bbInputSetup = bbInputSetup;
111         }
112
113         public void selectExecutionList(DelegateExecution execution) throws Exception {
114                 final String requestAction = (String) execution.getVariable(G_ACTION);
115                 final String requestId = (String) execution.getVariable(G_REQUEST_ID);
116                 final String bpmnRequest = (String) execution.getVariable(G_BPMN_REQUEST);
117                 final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE);
118                 final String apiVersion = (String) execution.getVariable(G_APIVERSION);
119                 final String uri = (String) execution.getVariable(G_URI);
120                 final String vnfType = (String) execution.getVariable(VNF_TYPE);
121                 List<OrchestrationFlow> orchFlows = (List<OrchestrationFlow>) execution.getVariable(G_ORCHESTRATION_FLOW);
122                 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
123                 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
124                 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
125                 List<Resource> resourceCounter = new ArrayList<>();
126                 
127                 execution.setVariable("sentSyncResponse", false);
128                 execution.setVariable("homing", false);
129                 execution.setVariable("calledHoming", false);
130
131                 try {
132                         ObjectMapper mapper = new ObjectMapper();
133                         execution.setVariable(G_ISTOPLEVELFLOW, true);
134                         ServiceInstancesRequest sIRequest = mapper.readValue(bpmnRequest, ServiceInstancesRequest.class);
135                         RequestDetails requestDetails = sIRequest.getRequestDetails();
136                         Resource resource = extractResourceIdAndTypeFromUri(uri);
137                         WorkflowType resourceType = resource.getResourceType();
138                         String resourceId = "";
139                         if (resource.isGenerated()) {
140                                 resourceId = validateResourceIdInAAI(resource.getResourceId(), resourceType,
141                                                 sIRequest.getRequestDetails().getRequestInfo().getInstanceName(), sIRequest.getRequestDetails(),
142                                                 workflowResourceIds);
143                         } else {
144                                 resourceId = resource.getResourceId();
145                         }
146                         execution.setVariable("resourceId", resourceId);
147                         execution.setVariable("resourceType", resourceType);
148
149                         if (aLaCarte) {
150                                 if (orchFlows == null || orchFlows.isEmpty()) {
151                                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
152                                 }
153                                 String key = "";
154                                 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
155                                 if(modelInfo.getModelType().equals(ModelType.service)) {
156                                         key = modelInfo.getModelVersionId();
157                                 } else {
158                                         key = modelInfo.getModelCustomizationId();
159                                 }
160                                 for (OrchestrationFlow orchFlow : orchFlows) {
161                                         ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, key, apiVersion, resourceId,
162                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false);
163                                         flowsToExecute.add(ebb);
164                                 }
165                         } else {
166                                 boolean foundRelated = false;
167                                 boolean containsService = false;
168                                 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
169                                         // SERVICE-MACRO-ASSIGN will always get user params with a
170                                         // service.
171                                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
172                                                 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
173                                                                 .getUserParams();
174                                                 for (Map<String, Object> params : userParams) {
175                                                         if (params.containsKey(USERPARAMSERVICE)) {
176                                                                 containsService = true;
177                                                         }
178                                                 }
179                                                 if (containsService) {
180                                                         traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
181                                                 }
182                                         } else {
183                                                 buildAndThrowException(execution,
184                                                                 "Service-Macro-Assign request details must contain user params with a service");
185                                         }
186                                 } else if (resourceType == WorkflowType.SERVICE
187                                                 && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
188                                         // SERVICE-MACRO-CREATE will get user params with a service,
189                                         // a service with a network, a service with a
190                                         // networkcollection, OR an empty service.
191                                         // If user params is just a service or null and macro
192                                         // queries the SI and finds a VNF, macro fails.
193
194                                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
195                                                 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
196                                                                 .getUserParams();
197                                                 for (Map<String, Object> params : userParams) {
198                                                         if (params.containsKey(USERPARAMSERVICE)) {
199                                                                 containsService = true;
200                                                         }
201                                                 }
202                                         }
203                                         if (containsService) {
204                                                 foundRelated = traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
205                                         }
206                                         if (!foundRelated) {
207                                                 traverseCatalogDbService(execution, sIRequest, resourceCounter);
208                                         }
209                                 } else if (resourceType == WorkflowType.SERVICE
210                                                 && (requestAction.equalsIgnoreCase("activateInstance")
211                                                                 || requestAction.equalsIgnoreCase("unassignInstance")
212                                                                 || requestAction.equalsIgnoreCase("deleteInstance"))) {
213                                         // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
214                                         // SERVICE-MACRO-DELETE
215                                         // Will never get user params with service, macro will have
216                                         // to query the SI in AAI to find related instances.
217                                         traverseAAIService(execution, resourceCounter, resourceId, aaiResourceIds);
218                                 } else if (resourceType == WorkflowType.SERVICE
219                                                 && requestAction.equalsIgnoreCase("deactivateInstance")) {
220                                         resourceCounter.add(new Resource(WorkflowType.SERVICE,"",false));
221                                 } else {
222                                         buildAndThrowException(execution, "Current Macro Request is not supported");
223                                 }
224
225                                 String foundObjects = "";
226                                 for(WorkflowType type : WorkflowType.values()){
227                                         foundObjects = foundObjects + type + " - " + resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size() + "    ";
228                                 }
229                                 msoLogger.info("Found " + foundObjects);
230                         
231                                 if (orchFlows == null || orchFlows.isEmpty()) {
232                                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
233                                 }
234                                 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceCounter, requestId, apiVersion, resourceId,
235                                                 resourceType, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails);
236                                 if (!resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) {
237                                         msoLogger.info("Sorting for Vlan Tagging");
238                                         flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
239                                 }
240                                 if (resourceType == WorkflowType.SERVICE
241                                                 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
242                                                 && !resourceCounter.stream().filter(x -> VNF.equals(x.getResourceType())).collect(Collectors.toList()).isEmpty()) {
243                                         execution.setVariable("homing", true);
244                                         execution.setVariable("calledHoming", false);
245                                 }
246                                 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))){
247                                         generateResourceIds(flowsToExecute, resourceCounter);
248                                 }else{
249                                         updateResourceIdsFromAAITraversal(flowsToExecute, resourceCounter, aaiResourceIds);
250                                 }
251                         }
252
253                         if (flowsToExecute.isEmpty()) {
254                                 throw new IllegalStateException("Macro did not come up with a valid execution path.");
255                         }
256
257                         msoLogger.info("List of BuildingBlocks to execute:");
258                         for (ExecuteBuildingBlock ebb : flowsToExecute) {
259                                 msoLogger.info(ebb.getBuildingBlock().getBpmnFlowName());
260                         }
261
262                         execution.setVariable(G_CURRENT_SEQUENCE, 0);
263                         execution.setVariable("retryCount", 0);
264                         execution.setVariable("flowsToExecute", flowsToExecute);
265
266                 } catch (Exception ex) {
267                         buildAndThrowException(execution, "Exception in create execution list " + ex.getMessage(), ex);
268                 }
269         }
270
271         protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
272                 int count = 0;
273                 for(Resource resource : vfModuleResources){
274                         if(resource.isBaseVfModule()){
275                                 Collections.swap(vfModuleResources, 0, count);
276                                 break;
277                         }
278                         count++;
279                 }
280                 return vfModuleResources;
281         }
282
283         private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
284                         List<Resource> resourceCounter, List<Pair<WorkflowType, String>> aaiResourceIds) {
285                 for(Pair<WorkflowType,String> pair : aaiResourceIds){
286                         msoLogger.debug(pair.getValue0() + ", " + pair.getValue1());
287                 }
288                 
289                 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
290                         List<Resource> resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList());
291                         for(int i = 0; i < resources.size(); i++){
292                                 updateWorkflowResourceIds(flowsToExecute, type, resources.get(i).getResourceId(), retrieveAAIResourceId(aaiResourceIds,type));
293                         }
294                 });
295         }
296
297         private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource){
298                 String id = null;
299                 for(int i = 0; i<aaiResourceIds.size();i++){
300                         if(aaiResourceIds.get(i).getValue0() == resource){
301                                 id = aaiResourceIds.get(i).getValue1();
302                                 aaiResourceIds.remove(i);
303                                 break;
304                         }
305                 }
306                 return id;
307         }
308         private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceCounter) {
309                 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
310                         List<Resource> resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList());
311                         for(int i = 0; i < resources.size(); i++){
312                                 updateWorkflowResourceIds(flowsToExecute, type, resourceCounter.stream().filter(x -> type.equals(x.getResourceType()))
313                                                 .collect(Collectors.toList()).get(i).getResourceId(), null);                    }
314                 });
315         }
316         
317         protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resource, String key, String id){
318                 String resourceId = id;
319                 if(resourceId==null){
320                         resourceId = UUID.randomUUID().toString();
321                 }
322                 for(ExecuteBuildingBlock ebb : flowsToExecute){
323                         if(key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && ebb.getBuildingBlock().getBpmnFlowName().contains(resource.toString())){
324                                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
325                                 if(resource == WorkflowType.VNF){
326                                         workflowResourceIds.setVnfId(resourceId);
327                                 }else if(resource == WorkflowType.VFMODULE){
328                                         workflowResourceIds.setVfModuleId(resourceId);
329                                 }else if(resource == WorkflowType.VOLUMEGROUP){
330                                         workflowResourceIds.setVolumeGroupId(resourceId);
331                                 }else if(resource == WorkflowType.NETWORK){
332                                         workflowResourceIds.setNetworkId(resourceId);
333                                 }else if(resource == WorkflowType.NETWORKCOLLECTION){
334                                         workflowResourceIds.setNetworkCollectionId(resourceId);
335                                 }
336                                 ebb.setWorkflowResourceIds(workflowResourceIds);
337                         }
338                 }
339         }
340
341         protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution, org.onap.so.db.catalog.beans.Service service) {
342                 CollectionResourceCustomization networkCollection = null;
343                 int count = 0;
344                 for(CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()){
345                         if(catalogDbClient.getNetworkCollectionResourceCustomizationByID(collectionCust.getModelCustomizationUUID()) 
346                                         instanceof NetworkCollectionResourceCustomization) {
347                                 networkCollection = collectionCust;
348                                 count++;
349                         }
350                 }
351                 if(count == 0){
352                         return null;
353                 }else if(count > 1) {
354                         buildAndThrowException(execution, "Found multiple Network Collections in the Service model, only one per Service is supported.");
355                 }
356                 return networkCollection;
357         }
358         
359         protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
360                         List<Resource> resourceCounter) {
361                 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
362                 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
363                 if (service == null) {
364                         buildAndThrowException(execution, "Could not find the service model in catalog db.");
365                 } else {
366                         resourceCounter.add(new Resource(WorkflowType.SERVICE,service.getModelUUID(),false));
367                         if (service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty()) {
368                                 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
369                                 if(customizations.isEmpty()) {
370                                         msoLogger.debug("No Collections found. CollectionResourceCustomization list is empty.");
371                                 }else{
372                                         CollectionResourceCustomization collectionResourceCustomization = findCatalogNetworkCollection(execution, service);
373                                         if(collectionResourceCustomization!=null){
374                                                 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,collectionResourceCustomization.getModelCustomizationUUID(),false));
375                                                 msoLogger.debug("Found a network collection");
376                                                 if(collectionResourceCustomization.getCollectionResource()!=null){
377                                                         if(collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null){
378                                                                 String toscaNodeType = collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
379                                                                 if (toscaNodeType != null && toscaNodeType.contains("NetworkCollection")) {
380                                                                         int minNetworks = 0;
381                                                                         InstanceGroup instanceGroup = collectionResourceCustomization.getCollectionResource().getInstanceGroup();
382                                                                         CollectionResourceInstanceGroupCustomization collectionInstCust = null;
383                                                                         if(!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
384                                                                                 collectionInstCust = instanceGroup.getCollectionInstanceGroupCustomizations().get(0);
385                                                                                 if(collectionInstCust.getSubInterfaceNetworkQuantity() != null) {
386                                                                                         minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
387                                                                                 }
388                                                                         }
389                                                                         msoLogger.debug("minNetworks: " + minNetworks);
390                                                                         for (int i = 0; i < minNetworks; i++) {
391                                                                                 if(collectionInstCust != null) {
392                                                                                         
393                                                                                         resourceCounter.add(
394                                                                                                         new Resource(WorkflowType.VIRTUAL_LINK,instanceGroup.getCollectionNetworkResourceCustomizations()
395                                                                                                                         .get(0).getModelCustomizationUUID(),false));
396                                                                                 }
397                                                                         }
398                                                                 } else {
399                                                                                 msoLogger.debug("Instance Group tosca node type does not contain NetworkCollection: " + toscaNodeType);
400                                                         }
401                                                 }else{
402                                                                 msoLogger.debug("No Instance Group found for network collection.");
403                                                 }
404                                         }else{
405                                                 msoLogger.debug("No Network Collection found. collectionResource is null");
406                                         }
407                                         } else {
408                                                 msoLogger.debug("No Network Collection Customization found");
409                                         }
410                                 }
411                                 if (resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) {
412                                         if (service.getNetworkCustomizations() == null) {
413                                                 msoLogger.debug("No networks were found on this service model");
414                                         } else {
415                                                 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
416                                                         resourceCounter.add(new Resource(WorkflowType.NETWORK,service.getNetworkCustomizations().get(i).getModelCustomizationUUID(),false));
417                                                 }
418                                         }
419                                 }
420                         } else {
421                                 buildAndThrowException(execution,
422                                                 "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");
423                         }
424                 }
425         }
426
427         protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceCounter, String resourceId, List<Pair<WorkflowType, String>> aaiResourceIds) {
428                 try {
429                         ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
430                         org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO = bbInputSetup
431                                         .getExistingServiceInstance(serviceInstanceAAI);
432                         resourceCounter.add(new Resource(WorkflowType.SERVICE,serviceInstanceMSO.getServiceInstanceId(),false));
433                         if (serviceInstanceMSO.getVnfs() != null) {
434                                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO
435                                                 .getVnfs()) {
436                                         aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VNF, vnf.getVnfId()));
437                                         resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getVnfId(),false));
438                                         if (vnf.getVfModules() != null) {
439                                                 for (VfModule vfModule : vnf.getVfModules()) {
440                                                         aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
441                                                         resourceCounter.add(new Resource(WorkflowType.VFMODULE,vfModule.getVfModuleId(),false));
442                                                 }
443                                         }
444                                         if (vnf.getVolumeGroups() != null) {
445                                                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
446                                                                 .getVolumeGroups()) {
447                                                         aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
448                                                         resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,volumeGroup.getVolumeGroupId(),false));
449                                                 }
450                                         }
451                                 }
452                         }
453                         if (serviceInstanceMSO.getNetworks() != null) {
454                                 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
455                                                 .getNetworks()) {
456                                         aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.NETWORK, network.getNetworkId()));
457                                         resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getNetworkId(),false));
458                                 }
459                         }
460                         if (serviceInstanceMSO.getCollection() != null) {
461                                 msoLogger.debug("found networkcollection");
462                                 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
463                                 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,serviceInstanceMSO.getCollection().getId(),false));
464                         }
465                 } catch (Exception ex) {
466                         buildAndThrowException(execution,
467                                         "Could not find existing Service Instance or related Instances to execute the request on.");
468                 }
469         }
470
471         protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceCounter,
472                         ServiceInstancesRequest sIRequest, String requestAction)
473                         throws IOException {
474                 boolean foundRelated = false;
475                 boolean foundVfModuleOrVG = false;
476                 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
477                         List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
478                         for (Map<String, Object> params : userParams) {
479                                 if (params.containsKey(USERPARAMSERVICE)) {
480                                         ObjectMapper obj = new ObjectMapper();
481                                         String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
482                                         Service validate = obj.readValue(input, Service.class);
483                                         resourceCounter.add(new Resource(WorkflowType.SERVICE,validate.getModelInfo().getModelVersionId(),false));
484                                         if (validate.getResources().getVnfs() != null) {
485                                                 for (Vnfs vnf : validate.getResources().getVnfs()) {
486                                                         resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getModelInfo().getModelCustomizationId(),false));
487                                                         foundRelated = true;
488                                                         if (vnf.getVfModules() != null) {
489                                                                 for (VfModules vfModule : vnf.getVfModules()) {
490                                                                         VfModuleCustomization vfModuleCustomization = catalogDbClient
491                                                                                         .getVfModuleCustomizationByModelCuztomizationUUID(
492                                                                                                         vfModule.getModelInfo().getModelCustomizationUuid());
493                                                                         if (vfModuleCustomization != null) {
494                                                                                 if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getVolumeHeatTemplate()!=null &&vfModuleCustomization.getVolumeHeatEnv() != null) {
495                                                                                         resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,vfModuleCustomization.getModelCustomizationUUID(),false));
496                                                                                         foundRelated = true;
497                                                                                         foundVfModuleOrVG = true;
498                                                                                 }
499                                                                                 if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getModuleHeatTemplate()!=null && vfModuleCustomization.getHeatEnvironment()!=null){
500                                                                                         foundRelated = true;
501                                                                                         foundVfModuleOrVG = true;
502                                                                                         Resource resource = new Resource(WorkflowType.VFMODULE,vfModuleCustomization.getModelCustomizationUUID(),false);
503                                                                                         if(vfModuleCustomization.getVfModule().getIsBase()!=null && vfModuleCustomization.getVfModule().getIsBase()){
504                                                                                                 resource.setBaseVfModule(true);
505                                                                                         }else{
506                                                                                                 resource.setBaseVfModule(false);
507                                                                                         }
508                                                                                         resourceCounter.add(resource);
509                                                                                 }
510                                                                                 if(!foundVfModuleOrVG){
511                                                                                         buildAndThrowException(execution, "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
512                                                                                 }
513                                                                         }
514                                                                 }
515                                                         }
516                                                 }
517                                         }
518                                         if (validate.getResources().getNetworks() != null) {
519                                                 for (Networks network : validate.getResources().getNetworks()) {
520                                                         resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getModelInfo().getModelCustomizationId(),false));
521                                                         foundRelated = true;
522                                                 }
523                                                 if (requestAction.equals(CREATEINSTANCE)) {
524                                                         String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
525                                                         if (networkColCustId != null) {
526                                                                 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,networkColCustId,false));
527                                                                 foundRelated = true;
528                                                         }
529                                                 }
530                                         }
531                                         break;
532                                 }
533                         }
534                 }
535                 return foundRelated;
536         }
537
538         protected String queryCatalogDBforNetworkCollection(DelegateExecution execution, ServiceInstancesRequest sIRequest) {
539                 org.onap.so.db.catalog.beans.Service service = catalogDbClient
540                                 .getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
541                 if (service != null) {
542                         CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
543                         if(networkCollection != null) {
544                                 return networkCollection.getModelCustomizationUUID();
545                         }
546                 }
547                 return null;
548         }
549
550         protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
551                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
552                 workflowResourceIds.setServiceInstanceId((String) execution.getVariable("serviceInstanceId"));
553                 workflowResourceIds.setNetworkId((String) execution.getVariable("networkId"));
554                 workflowResourceIds.setVfModuleId((String) execution.getVariable("vfModuleId"));
555                 workflowResourceIds.setVnfId((String) execution.getVariable("vnfId"));
556                 workflowResourceIds.setVolumeGroupId((String) execution.getVariable("volumeGroupId"));
557                 return workflowResourceIds;
558         }
559
560         protected Resource extractResourceIdAndTypeFromUri(String uri) {
561                 Pattern patt = Pattern.compile(
562                                 "[vV]\\d+.*?(?:(?:/(?<type>" + supportedTypes + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?)?$");
563                 Matcher m = patt.matcher(uri);
564                 Boolean generated = false;
565
566                 if (m.find()) {
567                         msoLogger.debug("found match on " + uri + ": " + m);
568                         String type = m.group("type");
569                         String id = m.group("id");
570                         String action = m.group("action");
571                         if (type == null) {
572                                 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
573                         }
574                         if (action == null) {
575                                 if (type.equals("serviceInstances") && (id == null || id.equals("assign"))) {
576                                         id = UUID.randomUUID().toString();
577                                         generated = true;
578                                 }
579                         } else {
580                                 if (action.matches(supportedTypes)) {
581                                         id = UUID.randomUUID().toString();
582                                         generated = true;
583                                         type = action;
584                                 }
585                         }
586                         return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
587                 } else {
588                         throw new IllegalArgumentException("Uri could not be parsed: " + uri);
589                 }
590         }
591
592         protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
593                         RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
594                 try {
595                         if ("SERVICE".equalsIgnoreCase(type.toString())) {
596                                 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
597                                 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
598                                 if (instanceName != null) {
599                                         Optional<ServiceInstance> serviceInstanceAAI = bbInputSetupUtils
600                                                         .getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
601                                         if (serviceInstanceAAI.isPresent()) {
602                                                 return serviceInstanceAAI.get().getServiceInstanceId();
603                                         }
604                                 }
605                         } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
606                                 Optional<L3Network> network = bbInputSetupUtils.getRelatedNetworkByNameFromServiceInstance(
607                                                 workflowResourceIds.getServiceInstanceId(), instanceName);
608                                 if (network.isPresent()) {
609                                         return network.get().getNetworkId();
610                                 }
611                         } else if ("VNF".equalsIgnoreCase(type.toString())) {
612                                 Optional<GenericVnf> vnf = bbInputSetupUtils.getRelatedVnfByNameFromServiceInstance(
613                                                 workflowResourceIds.getServiceInstanceId(), instanceName);
614                                 if (vnf.isPresent()) {
615                                         return vnf.get().getVnfId();
616                                 }
617                         } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
618                                 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
619                                 if (vnf != null && vnf.getVfModules() != null) {
620                                         for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
621                                                 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
622                                                         return vfModule.getVfModuleId();
623                                                 }
624                                         }
625                                 }
626                         } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
627                                 Optional<VolumeGroup> volumeGroup = bbInputSetupUtils
628                                                 .getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
629                                 if (volumeGroup.isPresent()) {
630                                         return volumeGroup.get().getVolumeGroupId();
631                                 }
632                                 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
633                                 if (vnf != null && vnf.getVfModules() != null) {
634                                         for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
635                                                 Optional<VolumeGroup> volumeGroupFromVfModule = bbInputSetupUtils
636                                                                 .getRelatedVolumeGroupByNameFromVfModule(vfModule.getVfModuleId(), instanceName);
637                                                 if (volumeGroupFromVfModule.isPresent()) {
638                                                         return volumeGroupFromVfModule.get().getVolumeGroupId();
639                                                 }
640                                         }
641                                 }
642                         }
643                         return generatedResourceId;
644                 } catch (Exception ex) {
645                         throw new IllegalStateException(
646                                         "WorkflowAction was unable to verify if the instance name already exist in AAI.");
647                 }
648         }
649
650         protected String convertTypeFromPlural(String type) {
651                 if (!type.matches(supportedTypes)) {
652                         return type;
653                 } else {
654                         if (type.equals("serviceInstances")) {
655                                 return SERVICE;
656                         } else {
657                                 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
658                         }
659                 }
660         }
661
662         protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
663                         String requestAction) {
664                 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
665                 if (requestAction.equals(CREATEINSTANCE)) {
666                         for (ExecuteBuildingBlock ebb : orchFlows) {
667                                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
668                                         String key = ebb.getBuildingBlock().getKey();
669                                         sortedOrchFlows.add(ebb);
670                                         for (ExecuteBuildingBlock ebb2 : orchFlows) {
671                                                 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
672                                                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
673                                                         sortedOrchFlows.add(ebb2);
674                                                         break;
675                                                 }
676                                         }
677                                         for (ExecuteBuildingBlock ebb2 : orchFlows) {
678                                                 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")
679                                                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
680                                                         sortedOrchFlows.add(ebb2);
681                                                         break;
682                                                 }
683                                         }
684                                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
685                                                 || ebb.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")) {
686                                         continue;
687                                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
688                                         sortedOrchFlows.add(ebb);
689                                 }
690                         }
691                 } else if (requestAction.equals("deleteInstance")) {
692                         for (ExecuteBuildingBlock ebb : orchFlows) {
693                                 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
694                                         sortedOrchFlows.add(ebb);
695                                         String key = ebb.getBuildingBlock().getKey();
696                                         for (ExecuteBuildingBlock ebb2 : orchFlows) {
697                                                 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
698                                                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
699                                                         sortedOrchFlows.add(ebb2);
700                                                         break;
701                                                 }
702                                         }
703                                         for (ExecuteBuildingBlock ebb2 : orchFlows) {
704                                                 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
705                                                                 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
706                                                         sortedOrchFlows.add(ebb2);
707                                                         break;
708                                                 }
709                                         }
710                                 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
711                                                 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
712                                         continue;
713                                 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
714                                         sortedOrchFlows.add(ebb);
715                                 }
716                         }
717                 }
718                 return sortedOrchFlows;
719         }
720
721         protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
722                         List<Resource> resourceCounter, String requestId, String apiVersion, String resourceId, WorkflowType resourceType,
723                         String requestAction, boolean aLaCarte, String vnfType,
724                         WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails) {
725                 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
726                 for (OrchestrationFlow orchFlow : orchFlows) {
727                         if (orchFlow.getFlowName().contains(SERVICE)) {
728                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
729                                         workflowResourceIds.setServiceInstanceId(resourceId);
730                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType())
731                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
732                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
733                                 }
734                         } else if (orchFlow.getFlowName().contains(VNF)) {
735                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
736                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType())
737                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
738                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
739                                 }
740                         } else if (orchFlow.getFlowName().contains(NETWORK)
741                                         && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
742                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
743                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType())
744                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
745                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
746                                 }
747                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
748                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType())
749                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
750                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, true));
751                                 }
752                         } else if (orchFlow.getFlowName().contains(VFMODULE)) {
753                                 List<Resource> vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceCounter.stream().filter(x -> WorkflowType.VFMODULE == x.getResourceType())
754                                                 .collect(Collectors.toList()));
755                                 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
756                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i).getResourceId(), apiVersion, resourceId,
757                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
758                                 }
759                         } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
760                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
761                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType())
762                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
763                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
764                                 }
765                         } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
766                                 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
767                                         flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
768                                                         .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
769                                                         requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
770                                 }
771                         } else {
772                                 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, "", apiVersion, resourceId,
773                                                 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
774                         }
775                 }
776                 return flowsToExecute;
777         }
778
779         protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId, String key,
780                         String apiVersion, String resourceId, String requestAction, boolean aLaCarte, String vnfType,
781                         WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean isVirtualLink) {
782                 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock();
783                 BuildingBlock buildingBlock = new BuildingBlock();
784                 buildingBlock.setBpmnFlowName(orchFlow.getFlowName());
785                 buildingBlock.setMsoId(UUID.randomUUID().toString());
786                 buildingBlock.setKey(key);
787                 buildingBlock.setIsVirtualLink(isVirtualLink);
788                 executeBuildingBlock.setApiVersion(apiVersion);
789                 executeBuildingBlock.setaLaCarte(aLaCarte);
790                 executeBuildingBlock.setRequestAction(requestAction);
791                 executeBuildingBlock.setResourceId(resourceId);
792                 executeBuildingBlock.setVnfType(vnfType);
793                 executeBuildingBlock.setWorkflowResourceIds(workflowResourceIds);
794                 executeBuildingBlock.setRequestId(requestId);
795                 executeBuildingBlock.setBuildingBlock(buildingBlock);
796                 executeBuildingBlock.setRequestDetails(requestDetails);
797                 return executeBuildingBlock;
798         }
799
800         protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
801                         WorkflowType resourceName, boolean aLaCarte) {
802                 List<OrchestrationFlow> listToExecute = new ArrayList<>();
803                 NorthBoundRequest northBoundRequest = catalogDbClient
804                                 .getNorthBoundRequestByActionAndIsALaCarteAndRequestScope(requestAction, resourceName.toString(), aLaCarte);
805                 if(northBoundRequest == null){
806                         if(aLaCarte){
807                                 buildAndThrowException(execution,"The request: ALaCarte " + resourceName + " " + requestAction + " is not supported by GR_API.");
808                         }else{
809                                 buildAndThrowException(execution,"The request: Macro " + resourceName + " " + requestAction + " is not supported by GR_API.");
810                         }
811                 } else {
812                         if(northBoundRequest.getIsToplevelflow()!=null){
813                                 execution.setVariable(G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
814                         }
815                         List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
816                         if (flows == null)
817                                 flows = new ArrayList<>();
818                         for (OrchestrationFlow flow : flows) {
819                                 if (!flow.getFlowName().contains("BB")) {
820                                         List<OrchestrationFlow> macroQueryFlows = catalogDbClient
821                                                         .getOrchestrationFlowByAction(flow.getFlowName());
822                                         for (OrchestrationFlow macroFlow : macroQueryFlows) {
823                                                 listToExecute.add(macroFlow);
824                                         }
825                                 } else {
826                                         listToExecute.add(flow);
827                                 }
828                         }
829                 }
830                 return listToExecute;
831         }
832
833         protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
834                 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(),
835                                 MsoLogger.ErrorCode.UnknownError, msg, ex);
836                 execution.setVariable("WorkflowActionErrorMessage", msg);
837                 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
838         }
839
840         protected void buildAndThrowException(DelegateExecution execution, String msg) {
841                 msoLogger.error(msg);
842                 execution.setVariable("WorkflowActionErrorMessage", msg);
843                 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
844         }
845         
846         public void handleRuntimeException (DelegateExecution execution){
847                 StringBuffer wfeExpMsg = new StringBuffer("Runtime error ");
848                 String runtimeErrorMessage = null;
849                 try{
850                         String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
851                         if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
852                                 wfeExpMsg = wfeExpMsg.append(": ").append(javaExpMsg);
853                         }
854                         runtimeErrorMessage = wfeExpMsg.toString();
855                         msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, runtimeErrorMessage, "BPMN", MsoLogger.getServiceName(),
856                                         MsoLogger.ErrorCode.UnknownError, runtimeErrorMessage);
857                         execution.setVariable("WorkflowActionErrorMessage", runtimeErrorMessage);
858                 } catch (Exception e){
859                         //if runtime message was mulformed
860                         runtimeErrorMessage = "Runtime error";
861                 }
862                 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
863         }
864 }