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.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;
69 import com.fasterxml.jackson.databind.ObjectMapper;
72 public class WorkflowAction {
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);
97 protected BBInputSetup bbInputSetup;
99 protected BBInputSetupUtils bbInputSetupUtils;
101 private ExceptionBuilder exceptionBuilder;
103 private CatalogDbClient catalogDbClient;
105 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
106 this.bbInputSetupUtils = bbInputSetupUtils;
109 public void setBbInputSetup(BBInputSetup bbInputSetup) {
110 this.bbInputSetup = bbInputSetup;
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<>();
127 execution.setVariable("sentSyncResponse", false);
128 execution.setVariable("homing", false);
129 execution.setVariable("calledHoming", false);
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);
144 resourceId = resource.getResourceId();
146 execution.setVariable("resourceId", resourceId);
147 execution.setVariable("resourceType", resourceType);
150 if (orchFlows == null || orchFlows.isEmpty()) {
151 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
154 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
155 if(modelInfo.getModelType().equals(ModelType.service)) {
156 key = modelInfo.getModelVersionId();
158 key = modelInfo.getModelCustomizationId();
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);
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
171 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
172 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
174 for (Map<String, Object> params : userParams) {
175 if (params.containsKey(USERPARAMSERVICE)) {
176 containsService = true;
179 if (containsService) {
180 traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
183 buildAndThrowException(execution,
184 "Service-Macro-Assign request details must contain user params with a service");
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.
194 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
195 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters()
197 for (Map<String, Object> params : userParams) {
198 if (params.containsKey(USERPARAMSERVICE)) {
199 containsService = true;
203 if (containsService) {
204 foundRelated = traverseUserParamsService(execution, resourceCounter, sIRequest, requestAction);
207 traverseCatalogDbService(execution, sIRequest, resourceCounter);
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));
222 buildAndThrowException(execution, "Current Macro Request is not supported");
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() + " ";
229 msoLogger.info("Found " + foundObjects);
231 if (orchFlows == null || orchFlows.isEmpty()) {
232 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte);
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);
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);
246 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))){
247 generateResourceIds(flowsToExecute, resourceCounter);
249 updateResourceIdsFromAAITraversal(flowsToExecute, resourceCounter, aaiResourceIds);
253 if (flowsToExecute.isEmpty()) {
254 throw new IllegalStateException("Macro did not come up with a valid execution path.");
257 msoLogger.info("List of BuildingBlocks to execute:");
258 for (ExecuteBuildingBlock ebb : flowsToExecute) {
259 msoLogger.info(ebb.getBuildingBlock().getBpmnFlowName());
262 execution.setVariable(G_CURRENT_SEQUENCE, 0);
263 execution.setVariable("retryCount", 0);
264 execution.setVariable("flowsToExecute", flowsToExecute);
266 } catch (Exception ex) {
267 buildAndThrowException(execution, "Exception in create execution list " + ex.getMessage(), ex);
271 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
273 for(Resource resource : vfModuleResources){
274 if(resource.isBaseVfModule()){
275 Collections.swap(vfModuleResources, 0, count);
280 return vfModuleResources;
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());
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));
297 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource){
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);
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); }
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();
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);
336 ebb.setWorkflowResourceIds(workflowResourceIds);
341 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution, org.onap.so.db.catalog.beans.Service service) {
342 CollectionResourceCustomization networkCollection = null;
344 for(CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()){
345 if(catalogDbClient.getNetworkCollectionResourceCustomizationByID(collectionCust.getModelCustomizationUUID())
346 instanceof NetworkCollectionResourceCustomization) {
347 networkCollection = collectionCust;
353 }else if(count > 1) {
354 buildAndThrowException(execution, "Found multiple Network Collections in the Service model, only one per Service is supported.");
356 return networkCollection;
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.");
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.");
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")) {
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();
389 msoLogger.debug("minNetworks: " + minNetworks);
390 for (int i = 0; i < minNetworks; i++) {
391 if(collectionInstCust != null) {
394 new Resource(WorkflowType.VIRTUAL_LINK,instanceGroup.getCollectionNetworkResourceCustomizations()
395 .get(0).getModelCustomizationUUID(),false));
399 msoLogger.debug("Instance Group tosca node type does not contain NetworkCollection: " + toscaNodeType);
402 msoLogger.debug("No Instance Group found for network collection.");
405 msoLogger.debug("No Network Collection found. collectionResource is null");
408 msoLogger.debug("No Network Collection Customization found");
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");
415 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
416 resourceCounter.add(new Resource(WorkflowType.NETWORK,service.getNetworkCustomizations().get(i).getModelCustomizationUUID(),false));
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");
427 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceCounter, String resourceId, List<Pair<WorkflowType, String>> aaiResourceIds) {
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
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));
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));
453 if (serviceInstanceMSO.getNetworks() != null) {
454 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
456 aaiResourceIds.add(new Pair<WorkflowType, String>(WorkflowType.NETWORK, network.getNetworkId()));
457 resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getNetworkId(),false));
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));
465 } catch (Exception ex) {
466 buildAndThrowException(execution,
467 "Could not find existing Service Instance or related Instances to execute the request on.");
471 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceCounter,
472 ServiceInstancesRequest sIRequest, String requestAction)
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));
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));
497 foundVfModuleOrVG = true;
499 if(vfModuleCustomization.getVfModule()!=null && vfModuleCustomization.getVfModule().getModuleHeatTemplate()!=null && vfModuleCustomization.getHeatEnvironment()!=null){
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);
506 resource.setBaseVfModule(false);
508 resourceCounter.add(resource);
510 if(!foundVfModuleOrVG){
511 buildAndThrowException(execution, "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
518 if (validate.getResources().getNetworks() != null) {
519 for (Networks network : validate.getResources().getNetworks()) {
520 resourceCounter.add(new Resource(WorkflowType.NETWORK,network.getModelInfo().getModelCustomizationId(),false));
523 if (requestAction.equals(CREATEINSTANCE)) {
524 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
525 if (networkColCustId != null) {
526 resourceCounter.add(new Resource(WorkflowType.NETWORKCOLLECTION,networkColCustId,false));
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();
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;
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;
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");
572 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
574 if (action == null) {
575 if (type.equals("serviceInstances") && (id == null || id.equals("assign"))) {
576 id = UUID.randomUUID().toString();
580 if (action.matches(supportedTypes)) {
581 id = UUID.randomUUID().toString();
586 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
588 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
592 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
593 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
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();
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();
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();
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();
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();
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();
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.");
650 protected String convertTypeFromPlural(String type) {
651 if (!type.matches(supportedTypes)) {
654 if (type.equals("serviceInstances")) {
657 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
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);
677 for (ExecuteBuildingBlock ebb2 : orchFlows) {
678 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")
679 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
680 sortedOrchFlows.add(ebb2);
684 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("CreateNetworkBB")
685 || ebb.getBuildingBlock().getBpmnFlowName().equals("ActivateNetworkBB")) {
687 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
688 sortedOrchFlows.add(ebb);
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);
703 for (ExecuteBuildingBlock ebb2 : orchFlows) {
704 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
705 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
706 sortedOrchFlows.add(ebb2);
710 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
711 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
713 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
714 sortedOrchFlows.add(ebb);
718 return sortedOrchFlows;
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));
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));
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));
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));
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));
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));
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));
772 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, "", apiVersion, resourceId,
773 requestAction, aLaCarte, vnfType, workflowResourceIds, requestDetails, false));
776 return flowsToExecute;
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;
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){
807 buildAndThrowException(execution,"The request: ALaCarte " + resourceName + " " + requestAction + " is not supported by GR_API.");
809 buildAndThrowException(execution,"The request: Macro " + resourceName + " " + requestAction + " is not supported by GR_API.");
812 if(northBoundRequest.getIsToplevelflow()!=null){
813 execution.setVariable(G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
815 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
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);
826 listToExecute.add(flow);
830 return listToExecute;
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);
840 protected void buildAndThrowException(DelegateExecution execution, String msg) {
841 msoLogger.error(msg);
842 execution.setVariable("WorkflowActionErrorMessage", msg);
843 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
846 public void handleRuntimeException (DelegateExecution execution){
847 StringBuffer wfeExpMsg = new StringBuffer("Runtime error ");
848 String runtimeErrorMessage = null;
850 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
851 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
852 wfeExpMsg = wfeExpMsg.append(": ").append(javaExpMsg);
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";
862 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);