2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Modifications Copyright (c) 2020 Nokia
10 * ================================================================================
11 * Modifications Copyright (c) 2020 Tech Mahindra
12 * ================================================================================
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
17 * http://www.apache.org/licenses/LICENSE-2.0
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 * ============LICENSE_END=========================================================
27 package org.onap.so.bpmn.infrastructure.workflow.tasks;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
35 import java.util.Optional;
36 import java.util.UUID;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39 import java.util.stream.Collectors;
40 import org.camunda.bpm.engine.delegate.DelegateExecution;
41 import org.javatuples.Pair;
42 import org.onap.aai.domain.yang.GenericVnf;
43 import org.onap.aai.domain.yang.GenericVnfs;
44 import org.onap.aai.domain.yang.L3Network;
45 import org.onap.aai.domain.yang.Relationship;
46 import org.onap.aai.domain.yang.ServiceInstance;
47 import org.onap.aai.domain.yang.ServiceInstances;
48 import org.onap.aai.domain.yang.Vnfc;
49 import org.onap.aai.domain.yang.VolumeGroup;
50 import org.onap.aai.domain.yang.VpnBinding;
51 import org.onap.aaiclient.client.aai.AAICommonObjectMapperProvider;
52 import org.onap.aaiclient.client.aai.AAIObjectType;
53 import org.onap.aaiclient.client.aai.entities.AAIResultWrapper;
54 import org.onap.aaiclient.client.aai.entities.Relationships;
55 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
56 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
57 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
58 import org.onap.so.bpmn.common.BBConstants;
59 import org.onap.so.bpmn.infrastructure.workflow.tasks.utils.WorkflowResourceIdsUtils;
60 import org.onap.so.bpmn.servicedecomposition.bbobjects.Configuration;
61 import org.onap.so.bpmn.servicedecomposition.bbobjects.VfModule;
62 import org.onap.so.bpmn.servicedecomposition.entities.BuildingBlock;
63 import org.onap.so.bpmn.servicedecomposition.entities.ConfigurationResourceKeys;
64 import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
65 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
66 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetup;
67 import org.onap.so.bpmn.servicedecomposition.tasks.BBInputSetupUtils;
68 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.DuplicateNameException;
69 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.MultipleObjectsFoundException;
70 import org.onap.so.client.exception.ExceptionBuilder;
71 import org.onap.so.client.orchestration.AAIConfigurationResources;
72 import org.onap.so.client.orchestration.AAIEntityNotFoundException;
73 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
74 import org.onap.so.db.catalog.beans.CollectionResourceCustomization;
75 import org.onap.so.db.catalog.beans.CollectionResourceInstanceGroupCustomization;
76 import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization;
77 import org.onap.so.db.catalog.beans.CvnfcCustomization;
78 import org.onap.so.db.catalog.beans.VfModuleCustomization;
79 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
80 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
81 import org.onap.so.db.catalog.client.CatalogDbClient;
82 import org.onap.so.serviceinstancebeans.CloudConfiguration;
83 import org.onap.so.serviceinstancebeans.ModelInfo;
84 import org.onap.so.serviceinstancebeans.ModelType;
85 import org.onap.so.serviceinstancebeans.Networks;
86 import org.onap.so.serviceinstancebeans.Pnfs;
87 import org.onap.so.serviceinstancebeans.RelatedInstance;
88 import org.onap.so.serviceinstancebeans.RequestDetails;
89 import org.onap.so.serviceinstancebeans.Service;
90 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
91 import org.onap.so.serviceinstancebeans.VfModules;
92 import org.onap.so.serviceinstancebeans.Vnfs;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
95 import org.springframework.beans.factory.annotation.Autowired;
96 import org.springframework.core.env.Environment;
97 import org.springframework.stereotype.Component;
98 import org.springframework.util.CollectionUtils;
99 import com.fasterxml.jackson.core.JsonProcessingException;
100 import com.fasterxml.jackson.databind.ObjectMapper;
103 public class WorkflowAction {
105 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
106 private static final String SERVICE_INSTANCES = "serviceInstances";
107 private static final String SERVICE_INSTANCE = "serviceInstance";
108 private static final String VF_MODULES = "vfModules";
109 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
110 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
111 private static final String VNF_TYPE = "vnfType";
112 private static final String SERVICE = "Service";
113 private static final String VNF = "Vnf";
114 private static final String PNF = "Pnf";
115 private static final String VFMODULE = "VfModule";
116 private static final String VOLUMEGROUP = "VolumeGroup";
117 private static final String NETWORK = "Network";
118 private static final String NETWORKCOLLECTION = "NetworkCollection";
119 private static final String CONFIGURATION = "Configuration";
120 private static final String ASSIGNINSTANCE = "assignInstance";
121 private static final String CREATEINSTANCE = "createInstance";
122 private static final String REPLACEINSTANCE = "replaceInstance";
123 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
124 private static final String USERPARAMSERVICE = "service";
125 private static final String SUPPORTEDTYPES =
126 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
127 private static final String HOMINGSOLUTION = "Homing_Solution";
128 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
129 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
130 private static final String SERVICE_TYPE_BONDING = "BONDING";
131 private static final String CLOUD_OWNER = "DEFAULT";
132 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
133 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
134 private static final String NAME_EXISTS_MULTIPLE =
135 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
136 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
137 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
138 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
139 "(%s), same parent and different customization id (%s)";
140 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
141 private static final String CREATENETWORKBB = "CreateNetworkBB";
142 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
143 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
144 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
145 private static final String CONTROLLER = "Controller";
148 protected BBInputSetup bbInputSetup;
150 protected BBInputSetupUtils bbInputSetupUtils;
152 private ExceptionBuilder exceptionBuilder;
154 private CatalogDbClient catalogDbClient;
156 private AAIConfigurationResources aaiConfigurationResources;
158 private WorkflowActionExtractResourcesAAI workflowActionUtils;
160 private VrfValidation vrfValidation;
163 private Environment environment;
164 private String defaultCloudOwner = "org.onap.so.cloud-owner";
166 public void setBbInputSetupUtils(BBInputSetupUtils bbInputSetupUtils) {
167 this.bbInputSetupUtils = bbInputSetupUtils;
170 public void setBbInputSetup(BBInputSetup bbInputSetup) {
171 this.bbInputSetup = bbInputSetup;
174 public void selectExecutionList(DelegateExecution execution) throws Exception {
176 final String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST);
177 ServiceInstancesRequest sIRequest =
178 new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class);
179 RequestDetails requestDetails = sIRequest.getRequestDetails();
180 String uri = (String) execution.getVariable(BBConstants.G_URI);
181 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
182 final boolean aLaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
183 boolean isResume = isUriResume(uri);
184 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
185 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
186 Resource resource = getResource(bbInputSetupUtils, isResume, aLaCarte, uri, requestId);
187 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
188 WorkflowType resourceType = resource.getResourceType();
189 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
190 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
191 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
192 if (isRequestMacroServiceResume(aLaCarte, resourceType, requestAction, serviceInstanceId)) {
193 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
194 if (flowsToExecute == null) {
195 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
197 } else if (aLaCarte && isResume) {
198 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
199 if (flowsToExecute == null) {
200 buildAndThrowException(execution,
201 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
204 String vnfType = (String) execution.getVariable(VNF_TYPE);
205 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
206 List<OrchestrationFlow> orchFlows =
207 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
208 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
209 final String serviceType =
210 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
212 if (orchFlows == null || orchFlows.isEmpty()) {
213 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
214 cloudOwner, serviceType);
216 Resource resourceKey = getResourceKey(sIRequest, resourceType);
217 boolean isConfiguration = isConfiguration(orchFlows);
218 if (isConfiguration && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
219 List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(
220 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
221 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
222 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
223 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
224 .setRequestDetails(requestDetails).setExecution(execution));
226 flowsToExecute.addAll(configBuildingBlocks);
228 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
229 .collect(Collectors.toList());
231 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
232 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
233 && resourceType.equals(WorkflowType.VFMODULE)) {
234 logger.debug("Build a BB list for replacing BB modules");
235 orchFlows = getVfModuleReplaceBuildingBlocks(
236 new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
237 .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion)
238 .setResourceId(resourceId).setRequestAction(requestAction).setaLaCarte(true)
239 .setVnfType(vnfType).setWorkflowResourceIds(workflowResourceIds)
240 .setRequestDetails(requestDetails).setExecution(execution));
242 for (OrchestrationFlow orchFlow : orchFlows) {
243 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
244 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
245 requestDetails, false, null, null, false);
246 flowsToExecute.add(ebb);
249 boolean foundRelated = false;
250 boolean containsService = false;
251 List<Resource> resourceList = new ArrayList<>();
252 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
253 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
254 // SERVICE-MACRO-ASSIGN will always get user params with a
256 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
257 List<Map<String, Object>> userParams =
258 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
259 for (Map<String, Object> params : userParams) {
260 if (params.containsKey(USERPARAMSERVICE)) {
261 containsService = true;
264 if (containsService) {
265 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
268 buildAndThrowException(execution,
269 "Service-Macro-Assign request details must contain user params with a service");
271 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
272 // SERVICE-MACRO-CREATE will get user params with a service,
273 // a service with a network, a service with a
274 // networkcollection, OR an empty service.
275 // If user params is just a service or null and macro
276 // queries the SI and finds a VNF, macro fails.
278 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
279 List<Map<String, Object>> userParams =
280 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
281 for (Map<String, Object> params : userParams) {
282 if (params.containsKey(USERPARAMSERVICE)) {
283 containsService = true;
287 if (containsService) {
288 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
291 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
293 } else if (resourceType == WorkflowType.SERVICE
294 && ("activateInstance".equalsIgnoreCase(requestAction)
295 || "unassignInstance".equalsIgnoreCase(requestAction)
296 || "deleteInstance".equalsIgnoreCase(requestAction)
297 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
298 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
299 // SERVICE-MACRO-DELETE
300 // Will never get user params with service, macro will have
301 // to query the SI in AAI to find related instances.
302 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
303 } else if (resourceType == WorkflowType.SERVICE
304 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
305 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
306 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
307 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
308 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
309 workflowResourceIds.getVnfId(), aaiResourceIds);
311 buildAndThrowException(execution, "Current Macro Request is not supported");
313 String foundObjects = "";
314 for (WorkflowType type : WorkflowType.values()) {
315 foundObjects = foundObjects + type + " - " + resourceList.stream()
316 .filter(x -> type.equals(x.getResourceType())).collect(Collectors.toList()).size()
319 logger.info("Found {}", foundObjects);
321 if (orchFlows == null || orchFlows.isEmpty()) {
322 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, aLaCarte,
323 cloudOwner, serviceType);
325 boolean vnfReplace = false;
326 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
327 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
330 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
331 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
332 if (isNetworkCollectionInTheResourceList(resourceList)) {
333 logger.info("Sorting for Vlan Tagging");
334 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
336 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
337 if (resourceType == WorkflowType.SERVICE
338 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
339 && !resourceList.stream().filter(x -> WorkflowType.VNF.equals(x.getResourceType()))
340 .collect(Collectors.toList()).isEmpty()) {
341 execution.setVariable("homing", true);
342 execution.setVariable("calledHoming", false);
344 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
345 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
346 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
348 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
353 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
355 if (sIRequest.getRequestDetails().getRequestParameters() != null
356 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
357 List<Map<String, Object>> userParams =
358 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
359 for (Map<String, Object> params : userParams) {
360 if (params.containsKey(HOMINGSOLUTION)) {
361 if ("none".equals(params.get(HOMINGSOLUTION))) {
362 execution.setVariable("homing", false);
364 execution.setVariable("homing", true);
370 if (CollectionUtils.isEmpty(flowsToExecute)) {
371 throw new IllegalStateException("Macro did not come up with a valid execution path.");
374 List<String> flowNames = new ArrayList<>();
375 logger.info("List of BuildingBlocks to execute:");
377 flowsToExecute.forEach(ebb -> {
378 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
379 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
383 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
385 execution.setVariable("flowNames", flowNames);
386 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
387 execution.setVariable("retryCount", 0);
388 execution.setVariable("isRollback", false);
389 execution.setVariable("flowsToExecute", flowsToExecute);
390 execution.setVariable("isRollbackComplete", false);
392 } catch (Exception ex) {
393 if (!(execution.hasVariable("WorkflowException")
394 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
395 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
402 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
403 String resourceId = "";
404 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
405 if (modelInfo != null) {
406 if (modelInfo.getModelType().equals(ModelType.service)) {
407 resourceId = modelInfo.getModelVersionId();
409 resourceId = modelInfo.getModelCustomizationId();
412 return new Resource(resourceType, resourceId, true);
415 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
416 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
417 return cloudConfiguration.getCloudOwner();
419 logger.warn("cloud owner value not found in request details, it will be set as default");
420 return environment.getProperty(defaultCloudOwner);
423 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
424 AAIObjectType type) {
425 List<T> vnfcs = new ArrayList<>();
426 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
427 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
428 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
429 if (!relationshipsOp.isPresent()) {
430 logger.debug("No relationships were found for vfModule in AAI");
432 Relationships relationships = relationshipsOp.get();
433 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
434 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
435 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
436 vnfcOp.ifPresent(vnfcs::add);
442 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
444 List<T> configurations = new ArrayList<>();
445 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
446 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
447 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
448 if (!relationshipsOp.isPresent()) {
449 logger.debug("No relationships were found for VNFC in AAI");
451 Relationships relationships = relationshipsOp.get();
452 List<AAIResultWrapper> configurationResultWrappers =
453 this.getResultWrappersFromRelationships(relationships, type);
454 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
455 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
456 configurationOp.ifPresent(configurations::add);
459 return configurations;
462 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
463 AAIObjectType type) {
464 return relationships.getByType(type);
467 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
468 for (OrchestrationFlow flow : orchFlows) {
469 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
476 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
479 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
480 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
481 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
482 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
483 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
485 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
486 String vfModuleCustomizationUUID = "";
487 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
489 if (aaiVfModule == null) {
490 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
492 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
493 + vnfId + " and vfModuleId : " + vfModuleId);
495 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
498 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
499 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
500 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
501 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
502 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
503 if (configurations.size() > 1) {
504 String multipleRelationshipsError =
505 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
506 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
507 new Exception(multipleRelationshipsError));
509 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
510 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
511 for (OrchestrationFlow orchFlow : result) {
512 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
513 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
514 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
515 String vnfcName = getVnfcNameForConfiguration(configuration);
516 if (vnfcName == null || vnfcName.isEmpty()) {
517 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
518 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
519 new Exception("Vnfc and Configuration do not match"));
521 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(),
522 dataObj.getResourceKey(), dataObj.getApiVersion(), dataObj.getResourceId(),
523 dataObj.getRequestAction(), dataObj.isaLaCarte(), dataObj.getVnfType(),
524 dataObj.getWorkflowResourceIds(), dataObj.getRequestDetails(), false, null, vnfcName, true);
525 flowsToExecuteConfigs.add(ebb);
529 return flowsToExecuteConfigs;
532 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
535 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
536 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
538 logger.debug("BUILDING REPLACE LIST");
540 boolean volumeGroupExisted = false;
541 boolean volumeGroupWillExist = false;
542 boolean keepVolumeGroup = false;
544 boolean rebuildVolumeGroups = false;
545 if (dataObj.getRequestDetails().getRequestParameters() != null
546 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
547 rebuildVolumeGroups =
548 dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups().booleanValue();
551 Optional<VolumeGroup> volumeGroupFromVfModule =
552 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
553 if (volumeGroupFromVfModule.isPresent()) {
554 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
555 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
556 volumeGroupExisted = true;
557 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
560 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
561 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
562 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
563 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
564 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
565 && vfModuleCustomization.getVolumeHeatEnv() != null) {
566 volumeGroupWillExist = true;
567 if (!volumeGroupExisted) {
568 String newVolumeGroupId = UUID.randomUUID().toString();
569 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
570 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
574 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
575 keepVolumeGroup = true;
578 if (!volumeGroupExisted || keepVolumeGroup) {
579 logger.debug("Filtering out deletion of volume groups");
580 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
581 .collect(Collectors.toList());
583 if (!volumeGroupWillExist || keepVolumeGroup) {
584 logger.debug("Filtering out creation of volume groups");
585 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
586 .collect(Collectors.toList());
592 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
593 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
594 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
595 if (!relationshipsOp.isPresent()) {
596 logger.debug("No relationships were found for Configuration in AAI");
599 Relationships relationships = relationshipsOp.get();
600 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
601 if (vnfcResultWrappers.size() > 1 || vnfcResultWrappers.isEmpty()) {
602 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
604 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
605 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
609 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
611 for (Resource resource : vfModuleResources) {
612 if (resource.isBaseVfModule()) {
613 Collections.swap(vfModuleResources, 0, count);
618 return vfModuleResources;
621 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
623 for (Resource resource : vfModuleResources) {
624 if (resource.isBaseVfModule()) {
625 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
630 return vfModuleResources;
633 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
634 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
635 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
636 logger.debug(pair.getValue0() + ", " + pair.getValue1());
639 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
640 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
641 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
642 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId));
646 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
648 for (int i = 0; i < aaiResourceIds.size(); i++) {
649 if (aaiResourceIds.get(i).getValue0() == resource) {
650 id = aaiResourceIds.get(i).getValue1();
651 aaiResourceIds.remove(i);
658 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
659 String serviceInstanceId) {
660 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE)).forEach(type -> {
661 resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
662 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(), null,
663 resource.getVirtualLinkKey(), serviceInstanceId));
667 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
668 String key, String id, String virtualLinkKey, String serviceInstanceId) {
669 String resourceId = id;
670 if (resourceId == null) {
671 resourceId = UUID.randomUUID().toString();
673 for (ExecuteBuildingBlock ebb : flowsToExecute) {
674 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
675 .getBpmnFlowName().contains(resourceType.toString())
676 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
677 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
678 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
679 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
680 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
681 ebb.setWorkflowResourceIds(workflowResourceIds);
683 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
684 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
685 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
686 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
687 workflowResourceIds.setNetworkId(resourceId);
688 ebb.setWorkflowResourceIds(workflowResourceIds);
693 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
694 org.onap.so.db.catalog.beans.Service service) {
695 CollectionResourceCustomization networkCollection = null;
697 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
698 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
699 collectionCust.getModelCustomizationUUID()) != null) {
700 networkCollection = collectionCust;
706 } else if (count > 1) {
707 buildAndThrowException(execution,
708 "Found multiple Network Collections in the Service model, only one per Service is supported.");
710 return networkCollection;
713 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
714 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
715 throws JsonProcessingException, VrfBondingServiceException {
716 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
717 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
718 if (service == null) {
719 buildAndThrowException(execution, "Could not find the service model in catalog db.");
721 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
722 RelatedInstance relatedVpnBinding =
723 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
724 RelatedInstance relatedLocalNetwork =
725 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
726 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
727 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
729 traverseNetworkCollection(execution, resourceList, service);
734 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
735 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
736 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
737 throws VrfBondingServiceException, JsonProcessingException {
738 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
739 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
740 vrfValidation.vrfServiceValidation(service);
741 vrfValidation.vrfCatalogDbChecks(service);
742 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
743 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
744 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
745 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
746 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
747 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
748 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
749 if (existingAAIVrfConfiguration != null) {
750 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
752 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
753 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
757 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
758 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
759 throws JsonProcessingException, VrfBondingServiceException {
760 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
761 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
762 if (relationshipsOp.isPresent()) {
763 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
764 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
765 if (configurationsRelatedToLocalNetwork.size() > 1) {
766 throw new VrfBondingServiceException(
767 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
769 if (configurationsRelatedToLocalNetwork.size() == 1) {
770 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
771 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
772 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
773 relatedConfiguration.get(), configWrapper)) {
774 return relatedConfiguration.get().getConfigurationId();
781 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
782 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
783 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
784 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
785 if (relationshipsConfigOp.isPresent()) {
786 Optional<VpnBinding> relatedInfraVpnBindingOp =
787 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
788 if (relatedInfraVpnBindingOp.isPresent()) {
789 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
790 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
791 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
792 + " is not connected to the same vpn binding id provided in request: "
793 + relatedVpnBinding.getInstanceId());
803 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
804 org.onap.so.db.catalog.beans.Service service) {
805 if (isVnfCustomizationsEmpty(service)) {
806 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
807 if (customizations.isEmpty()) {
808 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
810 CollectionResourceCustomization collectionResourceCustomization =
811 findCatalogNetworkCollection(execution, service);
812 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
814 traverseNetworkCollectionCustomization(resourceList, service);
816 buildAndThrowException(execution,
817 "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");
821 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
822 CollectionResourceCustomization collectionResourceCustomization) {
823 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
826 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
827 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
828 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
829 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
830 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
831 .getCollectionInstanceGroupCustomizations()) {
832 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
833 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
834 collectionInstCust = collectionInstanceGroupTemp;
838 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
839 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
842 logger.debug("minNetworks: {}", minNetworks);
843 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
844 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
845 .getCollectionNetworkResourceCustomizations()) {
846 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
847 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
848 collectionNetworkResourceCust = collectionNetworkTemp;
852 for (int i = 0; i < minNetworks; i++) {
853 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
854 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
855 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
856 resource.setVirtualLinkKey(Integer.toString(i));
857 resourceList.add(resource);
862 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
863 CollectionResourceCustomization collectionResourceCustomization) {
864 if (collectionResourceCustomization == null) {
865 logger.debug("No Network Collection Customization found");
868 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
869 collectionResourceCustomization.getModelCustomizationUUID(), false));
870 logger.debug("Found a network collection");
871 if (collectionResourceCustomization.getCollectionResource() == null) {
872 logger.debug("No Network Collection found. collectionResource is null");
875 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
876 logger.debug("No Instance Group found for network collection.");
879 String toscaNodeType =
880 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
881 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
882 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
888 private boolean interfaceNetworkQuantityIsAvailableInCollection(
889 CollectionResourceInstanceGroupCustomization collectionInstCust) {
890 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
893 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
894 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
897 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
898 org.onap.so.db.catalog.beans.Service service) {
899 if (isNetworkCollectionInTheResourceList(resourceList)) {
902 if (service.getNetworkCustomizations() == null) {
903 logger.debug("No networks were found on this service model");
906 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
907 resourceList.add(new Resource(WorkflowType.NETWORK,
908 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
912 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
913 return !(resourceList.stream().filter(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType())
914 .collect(Collectors.toList()).isEmpty());
917 private boolean isVnfCustomizationsEmpty(org.onap.so.db.catalog.beans.Service service) {
918 return service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty();
921 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
922 List<Pair<WorkflowType, String>> aaiResourceIds) {
924 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
925 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
926 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
927 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
928 if (serviceInstanceMSO.getVnfs() != null) {
929 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
930 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
931 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
932 if (vnf.getVfModules() != null) {
933 for (VfModule vfModule : vnf.getVfModules()) {
934 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
935 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
936 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
937 resourceList.add(resource);
940 if (vnf.getVolumeGroups() != null) {
941 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
942 .getVolumeGroups()) {
943 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
945 .add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
950 if (serviceInstanceMSO.getNetworks() != null) {
951 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
953 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
954 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
957 if (serviceInstanceMSO.getCollection() != null) {
958 logger.debug("found networkcollection");
960 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
961 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
962 serviceInstanceMSO.getCollection().getId(), false));
964 if (serviceInstanceMSO.getConfigurations() != null) {
965 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
966 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
967 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
968 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
969 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
970 if (relationship.getRelatedTo().contains("vnfc")
971 || relationship.getRelatedTo().contains("vpn-binding")) {
972 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
974 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
981 } catch (Exception ex) {
982 logger.error("Exception in traverseAAIService", ex);
983 buildAndThrowException(execution,
984 "Could not find existing Service Instance or related Instances to execute the request on.");
988 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
989 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
991 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
992 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
993 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
994 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
995 if (serviceInstanceMSO.getVnfs() != null) {
996 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
997 if (vnf.getVnfId().equals(vnfId)) {
998 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
999 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1000 if (vnf.getVfModules() != null) {
1001 for (VfModule vfModule : vnf.getVfModules()) {
1002 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1003 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1004 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1005 resourceList, aaiResourceIds);
1008 if (vnf.getVolumeGroups() != null) {
1009 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1010 .getVolumeGroups()) {
1012 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1014 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1021 } catch (Exception ex) {
1022 logger.error("Exception in traverseAAIVnf", ex);
1023 buildAndThrowException(execution,
1024 "Could not find existing Vnf or related Instances to execute the request on.");
1028 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1029 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1031 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1032 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1033 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1034 Optional<Relationships> relationshipsOp;
1035 relationshipsOp = vfModuleWrapper.getRelationships();
1036 if (relationshipsOp.isPresent()) {
1037 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1038 if (relationshipsOp.isPresent()) {
1039 Optional<Configuration> config =
1040 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1041 if (config.isPresent()) {
1042 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1044 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1048 } catch (Exception ex) {
1049 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1050 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1054 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1055 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1056 boolean foundRelated = false;
1057 boolean foundVfModuleOrVG = false;
1058 String vnfCustomizationUUID = "";
1059 String vfModuleCustomizationUUID = "";
1060 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1061 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1062 for (Map<String, Object> params : userParams) {
1063 if (params.containsKey(USERPARAMSERVICE)) {
1064 ObjectMapper obj = new ObjectMapper();
1065 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1066 Service validate = obj.readValue(input, Service.class);
1068 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1069 if (validate.getResources().getVnfs() != null) {
1070 for (Vnfs vnf : validate.getResources().getVnfs()) {
1071 resourceList.add(new Resource(WorkflowType.VNF,
1072 vnf.getModelInfo().getModelCustomizationId(), false));
1073 foundRelated = true;
1074 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1075 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1077 if (vnf.getVfModules() != null) {
1078 for (VfModules vfModule : vnf.getVfModules()) {
1079 VfModuleCustomization vfModuleCustomization =
1080 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1081 vfModule.getModelInfo().getModelCustomizationUuid());
1082 if (vfModuleCustomization != null) {
1084 if (vfModuleCustomization.getVfModule() != null
1085 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1086 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1087 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1088 vfModuleCustomization.getModelCustomizationUUID(), false));
1089 foundRelated = true;
1090 foundVfModuleOrVG = true;
1093 if (vfModuleCustomization.getVfModule() != null
1094 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1095 && vfModuleCustomization.getHeatEnvironment() != null) {
1096 foundRelated = true;
1097 foundVfModuleOrVG = true;
1098 Resource resource = new Resource(WorkflowType.VFMODULE,
1099 vfModuleCustomization.getModelCustomizationUUID(), false);
1100 if (vfModuleCustomization.getVfModule().getIsBase() != null
1101 && vfModuleCustomization.getVfModule().getIsBase()) {
1102 resource.setBaseVfModule(true);
1104 resource.setBaseVfModule(false);
1106 resourceList.add(resource);
1107 if (vfModule.getModelInfo() != null
1108 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1109 vfModuleCustomizationUUID =
1110 vfModule.getModelInfo().getModelCustomizationUuid();
1112 if (!vnfCustomizationUUID.isEmpty()
1113 && !vfModuleCustomizationUUID.isEmpty()) {
1114 List<CvnfcConfigurationCustomization> configs =
1115 traverseCatalogDbForConfiguration(
1116 validate.getModelInfo().getModelVersionId(),
1117 vnfCustomizationUUID, vfModuleCustomizationUUID);
1118 for (CvnfcConfigurationCustomization config : configs) {
1119 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1120 config.getConfigurationResource().getModelUUID(), false);
1121 resource.setVnfCustomizationId(
1122 vnf.getModelInfo().getModelCustomizationId());
1123 resource.setVfModuleCustomizationId(
1124 vfModule.getModelInfo().getModelCustomizationId());
1125 resourceList.add(configResource);
1129 if (!foundVfModuleOrVG) {
1130 buildAndThrowException(execution,
1131 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1138 if (validate.getResources().getPnfs() != null) {
1139 for (Pnfs pnf : validate.getResources().getPnfs()) {
1140 resourceList.add(new Resource(WorkflowType.PNF,
1141 pnf.getModelInfo().getModelCustomizationId(), false));
1142 foundRelated = true;
1145 if (validate.getResources().getNetworks() != null) {
1146 for (Networks network : validate.getResources().getNetworks()) {
1147 resourceList.add(new Resource(WorkflowType.NETWORK,
1148 network.getModelInfo().getModelCustomizationId(), false));
1149 foundRelated = true;
1151 if (requestAction.equals(CREATEINSTANCE)) {
1152 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1153 if (networkColCustId != null) {
1154 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1155 foundRelated = true;
1163 return foundRelated;
1166 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1167 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1168 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1170 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1171 vnfCustomizationUUID, vfModuleCustomizationUUID);
1172 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1173 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1174 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1175 configurations.add(customization);
1179 logger.debug("found {} fabric configuration(s)", configurations.size());
1180 return configurations;
1181 } catch (Exception ex) {
1182 logger.error("Error in finding configurations", ex);
1183 return configurations;
1187 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1188 ServiceInstancesRequest sIRequest) {
1189 org.onap.so.db.catalog.beans.Service service =
1190 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1191 if (service != null) {
1192 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1193 if (networkCollection != null) {
1194 return networkCollection.getModelCustomizationUUID();
1200 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1201 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1204 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1205 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1206 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1207 Matcher m = patt.matcher(uri);
1208 boolean generated = false;
1211 logger.debug("found match on {} : {} ", uri, m);
1212 String type = m.group("type");
1213 String id = m.group("id");
1214 String action = m.group("action");
1216 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1218 if (action == null) {
1219 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1220 id = UUID.randomUUID().toString();
1222 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1223 id = UUID.randomUUID().toString();
1227 if (action.matches(SUPPORTEDTYPES)) {
1228 id = UUID.randomUUID().toString();
1233 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1235 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1239 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1240 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1242 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1243 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1244 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1245 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1246 workflowResourceIds);
1247 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1248 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1249 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1250 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1251 workflowResourceIds);
1252 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1253 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1254 workflowResourceIds);
1255 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1256 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1257 workflowResourceIds);
1259 return generatedResourceId;
1260 } catch (DuplicateNameException dne) {
1262 } catch (Exception ex) {
1263 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1264 throw new IllegalStateException(
1265 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1269 protected String convertTypeFromPlural(String type) {
1270 if (!type.matches(SUPPORTEDTYPES)) {
1273 if (type.equals(SERVICE_INSTANCES)) {
1276 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1281 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1282 String requestAction) {
1283 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1284 if (requestAction.equals(CREATEINSTANCE)) {
1285 for (ExecuteBuildingBlock ebb : orchFlows) {
1286 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1287 String key = ebb.getBuildingBlock().getKey();
1288 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1289 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1290 sortedOrchFlows.add(ebb);
1291 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1292 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1293 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1294 sortedOrchFlows.add(ebb2);
1297 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1298 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1299 sortedOrchFlows.add(ebb2);
1303 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1304 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1305 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1306 sortedOrchFlows.add(ebb2);
1309 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1310 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1311 sortedOrchFlows.add(ebb2);
1315 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1316 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1318 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1319 sortedOrchFlows.add(ebb);
1322 } else if (requestAction.equals("deleteInstance")) {
1323 for (ExecuteBuildingBlock ebb : orchFlows) {
1324 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1325 sortedOrchFlows.add(ebb);
1326 String key = ebb.getBuildingBlock().getKey();
1327 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1328 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1329 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1330 sortedOrchFlows.add(ebb2);
1334 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1335 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1336 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1337 sortedOrchFlows.add(ebb2);
1341 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1342 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1344 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1345 sortedOrchFlows.add(ebb);
1349 return sortedOrchFlows;
1352 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1353 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1354 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1355 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1357 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1358 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1359 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1360 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration)));
1363 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1364 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1365 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1366 boolean replaceVnf) {
1367 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1368 for (OrchestrationFlow orchFlow : orchFlows) {
1369 if (orchFlow.getFlowName().contains(SERVICE)) {
1371 workflowResourceIds.setServiceInstanceId(resourceId);
1373 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1374 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1376 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1377 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1378 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1379 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1381 } else if (orchFlow.getFlowName().contains(PNF)) {
1382 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1383 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1385 } else if (orchFlow.getFlowName().contains(NETWORK)
1386 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1387 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1388 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1390 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1391 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1393 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1394 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1395 List<Resource> vfModuleResourcesSorted = null;
1396 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1397 || requestAction.equals("activateInstance")) {
1398 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1399 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1401 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1402 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1404 for (int i = 0; i < vfModuleResourcesSorted.size(); i++) {
1405 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, vfModuleResourcesSorted.get(i),
1406 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1407 false, null, null, false));
1409 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1410 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1411 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1412 logger.debug("Replacing workflow resource id by volume group id");
1413 resourceId = workflowResourceIds.getVolumeGroupId();
1415 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1416 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1418 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1419 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1420 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1422 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1423 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1424 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1427 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId,
1428 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null, false));
1431 return flowsToExecute;
1434 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1435 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1436 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1437 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration) {
1439 BuildingBlock buildingBlock =
1440 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1441 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1442 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1443 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(action -> buildingBlock.setBpmnAction(action));
1444 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(scope -> buildingBlock.setBpmnScope(scope));
1446 if (resource != null
1447 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1448 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1449 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1450 resourceId = workflowResourceIds.getVolumeGroupId();
1453 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1454 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1455 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1456 .setRequestDetails(requestDetails);
1458 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1459 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1460 Optional.ofNullable(vnfcName).ifPresent(name -> configurationResourceKeys.setVnfcName(name));
1461 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1462 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1463 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1464 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1466 return executeBuildingBlock;
1469 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1470 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1471 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1474 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1475 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1476 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1477 NorthBoundRequest northBoundRequest = null;
1478 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1479 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1481 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1482 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1484 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1485 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1487 if (northBoundRequest == null) {
1488 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1489 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1491 if (northBoundRequest == null) {
1492 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1493 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1495 if (northBoundRequest.getIsToplevelflow() != null) {
1496 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1498 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1500 flows = new ArrayList<>();
1501 for (OrchestrationFlow flow : flows) {
1502 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1503 List<OrchestrationFlow> macroQueryFlows =
1504 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1505 listToExecute.addAll(macroQueryFlows);
1507 listToExecute.add(flow);
1511 return listToExecute;
1514 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1515 logger.error(msg, ex);
1516 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1517 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1520 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1522 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1523 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1526 public void handleRuntimeException(DelegateExecution execution) {
1527 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1528 String runtimeErrorMessage;
1530 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1531 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1532 wfeExpMsg.append(": ").append(javaExpMsg);
1534 runtimeErrorMessage = wfeExpMsg.toString();
1535 logger.error(runtimeErrorMessage);
1536 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1537 } catch (Exception e) {
1538 logger.error("Runtime error", e);
1539 // if runtime message was mulformed
1540 runtimeErrorMessage = "Runtime error";
1542 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1545 protected boolean isUriResume(String uri) {
1546 return uri.endsWith("/resume");
1549 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1550 String serviceInstanceId) {
1551 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1552 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1553 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1554 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1557 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1558 RequestDetails reqDetails) throws DuplicateNameException, MultipleObjectsFoundException {
1559 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1560 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1561 if (instanceName != null) {
1562 Optional<ServiceInstance> serviceInstanceAAI =
1563 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1564 if (serviceInstanceAAI.isPresent()) {
1565 if (serviceInstanceAAI.get().getModelVersionId()
1566 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1567 return serviceInstanceAAI.get().getServiceInstanceId();
1569 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1570 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1573 ServiceInstances aaiServiceInstances =
1574 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1575 if (aaiServiceInstances != null) {
1576 if (aaiServiceInstances.getServiceInstance() != null
1577 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1578 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1579 throw new DuplicateNameException(SERVICE_INSTANCE,
1580 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1582 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1583 Map<String, String> keys =
1584 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1586 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1587 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1588 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1590 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1591 si.getModelVersionId()));
1597 return generatedResourceId;
1600 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1601 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1602 throws DuplicateNameException, MultipleObjectsFoundException {
1603 Optional<L3Network> network = bbInputSetupUtils
1604 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1605 if (network.isPresent()) {
1606 if (network.get().getModelCustomizationId()
1607 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1608 return network.get().getNetworkId();
1610 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1611 instanceName, network.get().getModelCustomizationId()));
1614 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1615 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1616 workflowResourceIds.getServiceInstanceId()));
1618 return generatedResourceId;
1621 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1622 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1623 throws DuplicateNameException, MultipleObjectsFoundException {
1624 Optional<GenericVnf> vnf = bbInputSetupUtils
1625 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1626 if (vnf.isPresent()) {
1627 if (vnf.get().getModelCustomizationId()
1628 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1629 return vnf.get().getVnfId();
1631 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1632 instanceName, vnf.get().getModelCustomizationId()));
1635 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1637 throw new DuplicateNameException("generic-vnf",
1638 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1640 return generatedResourceId;
1643 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1644 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1645 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1646 if (vnf != null && vnf.getVfModules() != null) {
1647 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1648 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1649 if (vfModule.getModelCustomizationId()
1650 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1651 return vfModule.getVfModuleId();
1653 throw new DuplicateNameException("vfModule",
1654 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1655 reqDetails.getModelInfo().getModelCustomizationId()));
1660 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1661 throw new DuplicateNameException("vfModule", instanceName);
1663 return generatedResourceId;
1666 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1667 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1668 throws DuplicateNameException, MultipleObjectsFoundException {
1669 Optional<VolumeGroup> volumeGroup =
1670 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1671 if (volumeGroup.isPresent()) {
1672 if (volumeGroup.get().getVfModuleModelCustomizationId()
1673 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1674 return volumeGroup.get().getVolumeGroupId();
1676 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1679 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1680 throw new DuplicateNameException("volumeGroup", instanceName);
1682 return generatedResourceId;
1685 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1686 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1687 throws DuplicateNameException, MultipleObjectsFoundException {
1688 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1689 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1690 workflowResourceIds.getServiceInstanceId(), instanceName);
1691 if (configuration.isPresent()) {
1692 if (configuration.get().getModelCustomizationId()
1693 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1694 return configuration.get().getConfigurationId();
1696 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1697 instanceName, configuration.get().getConfigurationId()));
1700 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1701 throw new DuplicateNameException("configuration", instanceName);
1703 return generatedResourceId;
1706 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1707 WorkflowType resourceType) {
1708 execution.setVariable("sentSyncResponse", false);
1709 execution.setVariable("homing", false);
1710 execution.setVariable("calledHoming", false);
1711 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1712 execution.setVariable("suppressRollback", suppressRollback);
1713 execution.setVariable("resourceId", resourceId);
1714 execution.setVariable("resourceType", resourceType);
1715 execution.setVariable("resourceName", resourceType.toString());
1718 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1720 if (!alaCarte && isResume) {
1721 logger.debug("replacing URI {}", uri);
1722 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1723 logger.debug("for RESUME with original value {}", uri);
1725 return extractResourceIdAndTypeFromUri(uri);
1728 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1729 WorkflowResourceIds workflowResourceIds) throws Exception {
1730 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1731 && requestDetails.getRequestInfo().getInstanceName() != null) {
1732 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1733 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1735 return resource.getResourceId();
1739 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1740 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1741 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1742 serviceInstanceId = resourceId;
1744 return serviceInstanceId;