2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.so.bpmn.infrastructure.workflow.tasks;
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;
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;
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.CollectionNetworkResourceCustomization;
49 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
50 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
51 import org.onap.so.db.catalog.beans.InstanceGroup;
52 import org.onap.so.db.catalog.beans.NetworkCollectionResourceCustomization;
53 import org.onap.so.db.catalog.beans.VfModuleCustomization;
54 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
55 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
56 import org.onap.so.db.catalog.client.CatalogDbClient;
57 import org.onap.so.logger.MessageEnum;
58 import org.onap.so.logger.MsoLogger;
59 import org.onap.so.serviceinstancebeans.ModelInfo;
60 import org.onap.so.serviceinstancebeans.ModelType;
61 import org.onap.so.serviceinstancebeans.Networks;
62 import org.onap.so.serviceinstancebeans.RequestDetails;
63 import org.onap.so.serviceinstancebeans.Service;
64 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
65 import org.onap.so.serviceinstancebeans.VfModules;
66 import org.onap.so.serviceinstancebeans.Vnfs;
67 import org.springframework.beans.factory.annotation.Autowired;
68 import org.springframework.stereotype.Component;
70 import com.fasterxml.jackson.databind.ObjectMapper;
73 public class WorkflowAction {
75 private static final String G_ORCHESTRATION_FLOW = "gOrchestrationFlow";
76 private static final String G_ACTION = "requestAction";
77 private static final String G_CURRENT_SEQUENCE = "gCurrentSequence";
78 private static final String G_REQUEST_ID = "mso-request-id";
79 private static final String G_BPMN_REQUEST = "bpmnRequest";
80 private static final String G_ALACARTE = "aLaCarte";
81 private static final String G_APIVERSION = "apiVersion";
82 private static final String G_URI = "requestUri";
83 private static final String G_ISTOPLEVELFLOW = "isTopLevelFlow";
84 private static final String VNF_TYPE = "vnfType";
85 private static final String SERVICE = "Service";
86 private static final String VNF = "Vnf";
87 private static final String VFMODULE = "VfModule";
88 private static final String VOLUMEGROUP = "VolumeGroup";
89 private static final String NETWORK = "Network";
90 private static final String NETWORKCOLLECTION = "NetworkCollection";
91 private static final String CONFIGURATION = "Configuration";
92 private static final String ASSIGNINSTANCE = "assignInstance";
93 private static final String CREATEINSTANCE = "createInstance";
94 private static final String USERPARAMSERVICE = "service";
95 private static final String supportedTypes = "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances";
96 private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, WorkflowAction.class);
99 protected BBInputSetup bbInputSetup;
101 protected BBInputSetupUtils bbInputSetupUtils;
103 private ExceptionBuilder exceptionBuilder;
105 private CatalogDbClient catalogDbClient;
107 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
108 this.bbInputSetupUtils = bbInputSetupUtils;
111 public void setBbInputSetup(BBInputSetup bbInputSetup) {
112 this.bbInputSetup = bbInputSetup;
115 public void selectExecutionList(DelegateExecution execution) throws Exception {
116 final String requestAction = (String) execution.getVariable(G_ACTION);
117 final String requestId = (String) execution.getVariable(G_REQUEST_ID);
118 final String bpmnRequest = (String) execution.getVariable(G_BPMN_REQUEST);
119 final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE);
120 final String apiVersion = (String) execution.getVariable(G_APIVERSION);
121 final String uri = (String) execution.getVariable(G_URI);
122 final String vnfType = (String) execution.getVariable(VNF_TYPE);
123 List<OrchestrationFlow> orchFlows = (List<OrchestrationFlow>) execution.getVariable(G_ORCHESTRATION_FLOW);
124 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
125 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
126 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
127 List<Resource> resourceCounter = new ArrayList<>();
129 execution.setVariable("sentSyncResponse", false);
130 execution.setVariable("homing", false);
131 execution.setVariable("calledHoming", false);
134 ObjectMapper mapper = new ObjectMapper();
135 execution.setVariable(G_ISTOPLEVELFLOW, true);
136 ServiceInstancesRequest sIRequest = mapper.readValue(bpmnRequest, ServiceInstancesRequest.class);
137 RequestDetails requestDetails = sIRequest.getRequestDetails();
138 Resource resource = extractResourceIdAndTypeFromUri(uri);
139 WorkflowType resourceType = resource.getResourceType();
140 execution.setVariable("resourceName", resourceType.toString());
141 String resourceId = "";
142 if (resource.isGenerated()) {
143 resourceId = validateResourceIdInAAI(resource.getResourceId(), resourceType,
144 sIRequest.getRequestDetails().getRequestInfo().getInstanceName(), sIRequest.getRequestDetails(),
145 workflowResourceIds);
147 resourceId = resource.getResourceId();
149 execution.setVariable("resourceId", resourceId);
150 execution.setVariable("resourceType", resourceType);
153 if (orchFlows == null || orchFlows.isEmpty()) {
154 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
157 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
158 if(modelInfo.getModelType().equals(ModelType.service)) {
159 key = modelInfo.getModelVersionId();
161 key = modelInfo.getModelCustomizationId();
163 for (OrchestrationFlow orchFlow : orchFlows) {
164 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, key, apiVersion, resourceId,
165 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null);
166 flowsToExecute.add(ebb);
169 boolean foundRelated = false;
170 boolean containsService = false;
171 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
172 // SERVICE-MACRO-ASSIGN will always get user params with a
174 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
175 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
177 for (Map<String, Object> params : userParams) {
178 if (params.containsKey(USERPARAMSERVICE)) {
179 containsService = true;
182 if (containsService) {
183 traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
186 buildAndThrowException(execution,
187 "Service-Macro-Assign request details must contain user params with a service");
189 } else if (resourceType == WorkflowType.SERVICE
190 && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
191 // SERVICE-MACRO-CREATE will get user params with a service,
192 // a service with a network, a service with a
193 // networkcollection, OR an empty service.
194 // If user params is just a service or null and macro
195 // queries the SI and finds a VNF, macro fails.
197 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
198 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
200 for (Map<String, Object> params : userParams) {
201 if (params.containsKey(USERPARAMSERVICE)) {
202 containsService = true;
206 if (containsService) {
207 foundRelated = traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
210 traverseCatalogDbService(execution, sIRequest, resourceCounter);
212 } else if (resourceType == WorkflowType.SERVICE
213 && (requestAction.equalsIgnoreCase("activateInstance")
214 || requestAction.equalsIgnoreCase("unassignInstance")
215 || requestAction.equalsIgnoreCase("deleteInstance"))) {
216 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
217 // SERVICE-MACRO-DELETE
218 // Will never get user params with service, macro will have
219 // to query the SI in AAI to find related instances.
220 traverseAAIService(execution, resourceCounter, resourceId, aaiResourceIds);
221 } else if (resourceType == WorkflowType.SERVICE
222 && requestAction.equalsIgnoreCase("deactivateInstance")) {
223 resourceCounter.add(new Resource(WorkflowType.SERVICE,"",false));
225 buildAndThrowException(execution, "Current Macro Request is not supported");
228 String foundObjects = "";
229 for(WorkflowType type : WorkflowType.values()){
230 foundObjects = foundObjects + type + " - " + resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size() + " ";
232 msoLogger.info("Found " + foundObjects);
234 if (orchFlows == null || orchFlows.isEmpty()) {
235 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
237 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceCounter, requestId, apiVersion, resourceId,
238 resourceType, requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails);
239 if (!resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) {
240 msoLogger.info("Sorting for Vlan Tagging");
241 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
243 if (resourceType == WorkflowType.SERVICE
244 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
245 && !resourceCounter.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType())).collect(Collectors.toList()).isEmpty()) {
246 execution.setVariable("homing", true);
247 execution.setVariable("calledHoming", false);
249 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))){
250 generateResourceIds(flowsToExecute, resourceCounter);
252 updateResourceIdsFromAAITraversal(flowsToExecute, resourceCounter, aaiResourceIds);
256 if (flowsToExecute.isEmpty()) {
257 throw new IllegalStateException("Macro did not come up with a valid execution path.");
260 msoLogger.info("List of BuildingBlocks to execute:");
261 for (ExecuteBuildingBlock ebb : flowsToExecute) {
262 msoLogger.info(ebb.getBuildingBlock().getBpmnFlowName());
265 execution.setVariable(G_CURRENT_SEQUENCE, 0);
266 execution.setVariable("retryCount", 0);
267 execution.setVariable("flowsToExecute", flowsToExecute);
269 } catch (Exception ex) {
271 buildAndThrowException(execution, "Exception in create execution list " + ex.getMessage(), ex);
275 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
277 for(Resource resource : vfModuleResources){
278 if(resource.isBaseVfModule()){
279 Collections.swap(vfModuleResources, 0, count);
284 return vfModuleResources;
287 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
288 List<Resource> resourceCounter, List<Pair<WorkflowType, String>> aaiResourceIds) {
289 for(Pair<WorkflowType,String> pair : aaiResourceIds){
290 msoLogger.debug(pair.getValue0() + ", " + pair.getValue1());
293 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
294 List<Resource> resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList());
295 for(int i = 0; i < resources.size(); i++){
296 updateWorkflowResourceIds(flowsToExecute, type, resources.get(i).getResourceId(), retrieveAAIResourceId(aaiResourceIds,type), null);
301 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource){
303 for(int i = 0; i<aaiResourceIds.size();i++){
304 if(aaiResourceIds.get(i).getValue0() == resource){
305 id = aaiResourceIds.get(i).getValue1();
306 aaiResourceIds.remove(i);
312 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceCounter) {
313 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
314 List<Resource> resources = resourceCounter.stream().filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList());
315 for(int i = 0; i < resources.size(); i++){
316 Resource resource = resourceCounter.stream().filter(x -> type.equals(x.getResourceType()))
317 .collect(Collectors.toList()).get(i);
318 updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null, resource.getVirtualLinkKey()); }
322 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resource, String key, String id, String virtualLinkKey){
323 String resourceId = id;
324 if(resourceId==null){
325 resourceId = UUID.randomUUID().toString();
327 for(ExecuteBuildingBlock ebb : flowsToExecute){
328 if(key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && ebb.getBuildingBlock().getBpmnFlowName().contains(resource.toString())){
329 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
330 if(resource == WorkflowType.VNF){
331 workflowResourceIds.setVnfId(resourceId);
332 }else if(resource == WorkflowType.VFMODULE){
333 workflowResourceIds.setVfModuleId(resourceId);
334 }else if(resource == WorkflowType.VOLUMEGROUP){
335 workflowResourceIds.setVolumeGroupId(resourceId);
336 }else if(resource == WorkflowType.NETWORK){
337 workflowResourceIds.setNetworkId(resourceId);
338 }else if(resource == WorkflowType.NETWORKCOLLECTION){
339 workflowResourceIds.setNetworkCollectionId(resourceId);
341 ebb.setWorkflowResourceIds(workflowResourceIds);
343 if(virtualLinkKey != null && ebb.getBuildingBlock().getIsVirtualLink()
344 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
345 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
346 workflowResourceIds.setNetworkId(resourceId);
347 ebb.setWorkflowResourceIds(workflowResourceIds);
352 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution, org.onap.so.db.catalog.beans.Service service) {
353 CollectionResourceCustomization networkCollection = null;
355 for(CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()){
356 if(catalogDbClient.getNetworkCollectionResourceCustomizationByID(collectionCust.getModelCustomizationUUID())
357 instanceof NetworkCollectionResourceCustomization) {
358 networkCollection = collectionCust;
364 }else if(count > 1) {
365 buildAndThrowException(execution, "Found multiple Network Collections in the Service model, only one per Service is supported.");
367 return networkCollection;
370 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
371 List<Resource> resourceCounter) {
372 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
373 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
374 if (service == null) {
375 buildAndThrowException(execution, "Could not find the service model in catalog db.");
377 resourceCounter.add(new Resource(WorkflowType.SERVICE,service.getModelUUID(),false));
378 if (service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty()) {
379 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
380 if(customizations.isEmpty()) {
381 msoLogger.debug("No Collections found. CollectionResourceCustomization list is empty.");
383 CollectionResourceCustomization collectionResourceCustomization = findCatalogNetworkCollection(execution, service);
384 if(collectionResourceCustomization!=null){
385 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,collectionResourceCustomization.getModelCustomizationUUID(),false));
386 msoLogger.debug("Found a network collection");
387 if(collectionResourceCustomization.getCollectionResource()!=null){
388 if(collectionResourceCustomization.getCollectionResource().getInstanceGroup() != null){
389 String toscaNodeType = collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
390 if (toscaNodeType != null && toscaNodeType.contains("NetworkCollection")) {
392 InstanceGroup instanceGroup = collectionResourceCustomization.getCollectionResource().getInstanceGroup();
393 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
394 if(!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
395 for(CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup.getCollectionInstanceGroupCustomizations()) {
396 if(collectionInstanceGroupTemp.getModelCustomizationUUID().equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
397 collectionInstCust = collectionInstanceGroupTemp;
401 if(collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null) {
402 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
405 msoLogger.debug("minNetworks: " + minNetworks);
406 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
407 for(CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup.getCollectionNetworkResourceCustomizations()) {
408 if(collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID().equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
409 collectionNetworkResourceCust = collectionNetworkTemp;
413 for (int i = 0; i < minNetworks; i++) {
414 if(collectionNetworkResourceCust != null && collectionInstCust != null) {
415 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,collectionNetworkResourceCust.getModelCustomizationUUID(),false);
416 resource.setVirtualLinkKey(Integer.toString(i));
417 resourceCounter.add(resource);
421 msoLogger.debug("Instance Group tosca node type does not contain NetworkCollection: " + toscaNodeType);
424 msoLogger.debug("No Instance Group found for network collection.");
427 msoLogger.debug("No Network Collection found. collectionResource is null");
430 msoLogger.debug("No Network Collection Customization found");
433 if (resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).isEmpty()) {
434 if (service.getNetworkCustomizations() == null) {
435 msoLogger.debug("No networks were found on this service model");
437 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
438 resourceCounter.add(new Resource(WorkflowType.NETWORK,service.getNetworkCustomizations().get(i).getModelCustomizationUUID(),false));
443 buildAndThrowException(execution,
444 "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");
449 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceCounter, String resourceId, List<Pair<WorkflowType, String>> aaiResourceIds) {
451 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
452 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO = bbInputSetup
453 .getExistingServiceInstance(serviceInstanceAAI);
454 resourceCounter.add(new Resource(WorkflowType.SERVICE,serviceInstanceMSO.getServiceInstanceId(),false));
455 if (serviceInstanceMSO.getVnfs() != null) {
456 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO
458 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VNF, vnf.getVnfId()));
459 resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getVnfId(),false));
460 if (vnf.getVfModules() != null) {
461 for (VfModule vfModule : vnf.getVfModules()) {
462 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
463 resourceCounter.add(new Resource(WorkflowType.VFMODULE,vfModule.getVfModuleId(),false));
466 if (vnf.getVolumeGroups() != null) {
467 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
468 .getVolumeGroups()) {
469 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
470 resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,volumeGroup.getVolumeGroupId(),false));
475 if (serviceInstanceMSO.getNetworks() != null) {
476 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
478 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.NETWORK, network.getNetworkId()));
479 resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getNetworkId(),false));
482 if (serviceInstanceMSO.getCollection() != null) {
483 msoLogger.debug("found networkcollection");
484 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
485 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,serviceInstanceMSO.getCollection().getId(),false));
487 } catch (Exception ex) {
488 buildAndThrowException(execution,
489 "Could not find existing Service Instance or related Instances to execute the request on.");
493 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceCounter,
494 ServiceInstancesRequest sIRequest, String requestAction)
496 boolean foundRelated = false;
497 boolean foundVfModuleOrVG = false;
498 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
499 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
500 for (Map<String, Object> params : userParams) {
501 if (params.containsKey(USERPARAMSERVICE)) {
502 ObjectMapper obj = new ObjectMapper();
503 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
504 Service validate = obj.readValue(input, Service.class);
505 resourceCounter.add(new Resource(WorkflowType.SERVICE,validate.getModelInfo().getModelVersionId(),false));
506 if (validate.getResources().getVnfs() != null) {
507 for (Vnfs vnf : validate.getResources().getVnfs()) {
508 resourceCounter.add(new Resource(WorkflowType.VNF,vnf.getModelInfo().getModelCustomizationId(),false));
510 if (vnf.getVfModules() != null) {
511 for (VfModules vfModule : vnf.getVfModules()) {
512 VfModuleCustomization vfModuleCustomization = catalogDbClient
513 .getVfModuleCustomizationByModelCuztomizationUUID(
514 vfModule.getModelInfo().getModelCustomizationUuid());
515 if (vfModuleCustomization != null) {
516 if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getVolumeHeatTemplate()!=null &&vfModuleCustomization.getVolumeHeatEnv() != null) {
517 resourceCounter.add(new Resource(WorkflowType.VOLUMEGROUP,vfModuleCustomization.getModelCustomizationUUID(),false));
519 foundVfModuleOrVG = true;
521 if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getModuleHeatTemplate()!=null && vfModuleCustomization.getHeatEnvironment()!=null){
523 foundVfModuleOrVG = true;
524 Resource resource = new Resource(WorkflowType.VFMODULE,vfModuleCustomization.getModelCustomizationUUID(),false);
525 if(vfModuleCustomization.getVfModule().getIsBase()!=null && vfModuleCustomization.getVfModule().getIsBase()){
526 resource.setBaseVfModule(true);
528 resource.setBaseVfModule(false);
530 resourceCounter.add(resource);
532 if(!foundVfModuleOrVG){
533 buildAndThrowException(execution, "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
540 if (validate.getResources().getNetworks() != null) {
541 for (Networks network : validate.getResources().getNetworks()) {
542 resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getModelInfo().getModelCustomizationId(),false));
545 if (requestAction.equals(CREATEINSTANCE)) {
546 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
547 if (networkColCustId != null) {
548 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,networkColCustId,false));
560 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution, ServiceInstancesRequest sIRequest) {
561 org.onap.so.db.catalog.beans.Service service = catalogDbClient
562 .getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
563 if (service != null) {
564 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
565 if(networkCollection != null) {
566 return networkCollection.getModelCustomizationUUID();
572 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
573 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
574 workflowResourceIds.setServiceInstanceId((String) execution.getVariable("serviceInstanceId"));
575 workflowResourceIds.setNetworkId((String) execution.getVariable("networkId"));
576 workflowResourceIds.setVfModuleId((String) execution.getVariable("vfModuleId"));
577 workflowResourceIds.setVnfId((String) execution.getVariable("vnfId"));
578 workflowResourceIds.setVolumeGroupId((String) execution.getVariable("volumeGroupId"));
579 return workflowResourceIds;
582 protected Resource extractResourceIdAndTypeFromUri(String uri) {
583 Pattern patt = Pattern.compile(
584 "[vV]\\d+.*?(?:(?:/(?<type>" + supportedTypes + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?)?$");
585 Matcher m = patt.matcher(uri);
586 Boolean generated = false;
589 msoLogger.debug("found match on " + uri + ": " + m);
590 String type = m.group("type");
591 String id = m.group("id");
592 String action = m.group("action");
594 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
596 if (action == null) {
597 if (type.equals("serviceInstances") && (id == null || id.equals("assign"))) {
598 id = UUID.randomUUID().toString();
602 if (action.matches(supportedTypes)) {
603 id = UUID.randomUUID().toString();
608 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
610 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
614 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
615 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
617 if ("SERVICE".equalsIgnoreCase(type.toString())) {
618 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
619 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
620 if (instanceName != null) {
621 Optional<ServiceInstance> serviceInstanceAAI = bbInputSetupUtils
622 .getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
623 if (serviceInstanceAAI.isPresent()) {
624 return serviceInstanceAAI.get().getServiceInstanceId();
627 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
628 Optional<L3Network> network = bbInputSetupUtils.getRelatedNetworkByNameFromServiceInstance(
629 workflowResourceIds.getServiceInstanceId(), instanceName);
630 if (network.isPresent()) {
631 return network.get().getNetworkId();
633 } else if ("VNF".equalsIgnoreCase(type.toString())) {
634 Optional<GenericVnf> vnf = bbInputSetupUtils.getRelatedVnfByNameFromServiceInstance(
635 workflowResourceIds.getServiceInstanceId(), instanceName);
636 if (vnf.isPresent()) {
637 return vnf.get().getVnfId();
639 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
640 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
641 if (vnf != null && vnf.getVfModules() != null) {
642 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
643 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
644 return vfModule.getVfModuleId();
648 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
649 Optional<VolumeGroup> volumeGroup = bbInputSetupUtils
650 .getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
651 if (volumeGroup.isPresent()) {
652 return volumeGroup.get().getVolumeGroupId();
654 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
655 if (vnf != null && vnf.getVfModules() != null) {
656 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
657 Optional<VolumeGroup> volumeGroupFromVfModule = bbInputSetupUtils
658 .getRelatedVolumeGroupByNameFromVfModule(vnf.getVnfId(), vfModule.getVfModuleId(), instanceName);
659 if (volumeGroupFromVfModule.isPresent()) {
660 return volumeGroupFromVfModule.get().getVolumeGroupId();
665 return generatedResourceId;
666 } catch (Exception ex) {
668 throw new IllegalStateException(
669 "WorkflowAction was unable to verify if the instance name already exist in AAI.");
673 protected String convertTypeFromPlural(String type) {
674 if (!type.matches(supportedTypes)) {
677 if (type.equals("serviceInstances")) {
680 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
685 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
686 String requestAction) {
687 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
688 if (requestAction.equals(CREATEINSTANCE)) {
689 for (ExecuteBuildingBlock ebb : orchFlows) {
690 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
691 String key = ebb.getBuildingBlock().getKey();
692 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().getIsVirtualLink());
693 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
694 sortedOrchFlows.add(ebb);
695 for (ExecuteBuildingBlock ebb2 : orchFlows) {
696 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
697 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
698 sortedOrchFlows.add(ebb2);
701 if(isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
702 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
703 sortedOrchFlows.add(ebb2);
707 for (ExecuteBuildingBlock ebb2 : orchFlows) {
708 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")
709 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
710 sortedOrchFlows.add(ebb2);
713 if(isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")
714 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
715 sortedOrchFlows.add(ebb2);
719 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
720 || ebb.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")) {
722 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
723 sortedOrchFlows.add(ebb);
726 } else if (requestAction.equals("deleteInstance")) {
727 for (ExecuteBuildingBlock ebb : orchFlows) {
728 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
729 sortedOrchFlows.add(ebb);
730 String key = ebb.getBuildingBlock().getKey();
731 for (ExecuteBuildingBlock ebb2 : orchFlows) {
732 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
733 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
734 sortedOrchFlows.add(ebb2);
738 for (ExecuteBuildingBlock ebb2 : orchFlows) {
739 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
740 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
741 sortedOrchFlows.add(ebb2);
745 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
746 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
748 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
749 sortedOrchFlows.add(ebb);
753 return sortedOrchFlows;
756 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
757 List<Resource> resourceCounter, String requestId, String apiVersion, String resourceId, WorkflowType resourceType,
758 String requestAction, boolean aLaCarte, String vnfType,
759 WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails) {
760 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
761 for (OrchestrationFlow orchFlow : orchFlows) {
762 if (orchFlow.getFlowName().contains(SERVICE)) {
763 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
764 workflowResourceIds.setServiceInstanceId(resourceId);
765 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.SERVICE == x.getResourceType())
766 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
767 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
769 } else if (orchFlow.getFlowName().contains(VNF)) {
770 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
771 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VNF == x.getResourceType())
772 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
773 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
775 } else if (orchFlow.getFlowName().contains(NETWORK)
776 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
777 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
778 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORK == x.getResourceType())
779 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
780 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
782 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
783 Resource resource = resourceCounter.stream().filter(x -> WorkflowType.VIRTUAL_LINK == x.getResourceType())
784 .collect(Collectors.toList()).get(i);
785 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource.getResourceId(), apiVersion, resourceId,
786 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, true, resource.getVirtualLinkKey()));
788 } else if (orchFlow.getFlowName().contains(VFMODULE)) {
789 List<Resource> vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceCounter.stream().filter(x -> WorkflowType.VFMODULE == x.getResourceType())
790 .collect(Collectors.toList()));
791 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
792 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i).getResourceId(), apiVersion, resourceId,
793 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
795 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
796 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
797 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.VOLUMEGROUP == x.getResourceType())
798 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
799 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
801 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
802 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
803 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
804 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
805 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
807 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
808 for (int i = 0; i < resourceCounter.stream().filter(x -> WorkflowType.CONFIGURATION == x.getResourceType()).collect(Collectors.toList()).size(); i++) {
809 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resourceCounter.stream().filter(x -> WorkflowType.CONFIGURATION == x.getResourceType())
810 .collect(Collectors.toList()).get(i).getResourceId(), apiVersion, resourceId,
811 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
814 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, "", apiVersion, resourceId,
815 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false, null));
818 return flowsToExecute;
821 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId, String key,
822 String apiVersion, String resourceId, String requestAction, boolean aLaCarte, String vnfType,
823 WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails, boolean isVirtualLink, String virtualLinkKey) {
824 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock();
825 BuildingBlock buildingBlock = new BuildingBlock();
826 buildingBlock.setBpmnFlowName(orchFlow.getFlowName());
827 buildingBlock.setMsoId(UUID.randomUUID().toString());
828 buildingBlock.setKey(key);
829 buildingBlock.setIsVirtualLink(isVirtualLink);
830 buildingBlock.setVirtualLinkKey(virtualLinkKey);
831 executeBuildingBlock.setApiVersion(apiVersion);
832 executeBuildingBlock.setaLaCarte(aLaCarte);
833 executeBuildingBlock.setRequestAction(requestAction);
834 executeBuildingBlock.setResourceId(resourceId);
835 executeBuildingBlock.setVnfType(vnfType);
836 executeBuildingBlock.setWorkflowResourceIds(workflowResourceIds);
837 executeBuildingBlock.setRequestId(requestId);
838 executeBuildingBlock.setBuildingBlock(buildingBlock);
839 executeBuildingBlock.setRequestDetails(requestDetails);
840 return executeBuildingBlock;
843 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
844 WorkflowType resourceName, boolean aLaCarte) {
845 List<OrchestrationFlow> listToExecute = new ArrayList<>();
846 NorthBoundRequest northBoundRequest = catalogDbClient
847 .getNorthBoundRequestByActionAndIsALaCarteAndRequestScope(requestAction, resourceName.toString(), aLaCarte);
848 if(northBoundRequest == null){
850 buildAndThrowException(execution,"The request: ALaCarte " + resourceName + " " + requestAction + " is not supported by GR_API.");
852 buildAndThrowException(execution,"The request: Macro " + resourceName + " " + requestAction + " is not supported by GR_API.");
855 if(northBoundRequest.getIsToplevelflow()!=null){
856 execution.setVariable(G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
858 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
860 flows = new ArrayList<>();
861 for (OrchestrationFlow flow : flows) {
862 if (!flow.getFlowName().contains("BB")) {
863 List<OrchestrationFlow> macroQueryFlows = catalogDbClient
864 .getOrchestrationFlowByAction(flow.getFlowName());
865 for (OrchestrationFlow macroFlow : macroQueryFlows) {
866 listToExecute.add(macroFlow);
869 listToExecute.add(flow);
873 return listToExecute;
876 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
877 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, msg, "BPMN", MsoLogger.getServiceName(),
878 MsoLogger.ErrorCode.UnknownError, msg, ex);
879 execution.setVariable("WorkflowActionErrorMessage", msg);
880 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
883 protected void buildAndThrowException(DelegateExecution execution, String msg) {
884 msoLogger.error(msg);
885 execution.setVariable("WorkflowActionErrorMessage", msg);
886 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
889 public void handleRuntimeException (DelegateExecution execution){
890 StringBuffer wfeExpMsg = new StringBuffer("Runtime error ");
891 String runtimeErrorMessage = null;
893 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
894 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
895 wfeExpMsg = wfeExpMsg.append(": ").append(javaExpMsg);
897 runtimeErrorMessage = wfeExpMsg.toString();
898 msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION_ARG, runtimeErrorMessage, "BPMN", MsoLogger.getServiceName(),
899 MsoLogger.ErrorCode.UnknownError, runtimeErrorMessage);
900 execution.setVariable("WorkflowActionErrorMessage", runtimeErrorMessage);
901 } catch (Exception e){
902 //if runtime message was mulformed
903 runtimeErrorMessage = "Runtime error";
905 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);