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.InstanceGroup;
79 import org.onap.so.db.catalog.beans.VfModuleCustomization;
80 import org.onap.so.db.catalog.beans.macro.NorthBoundRequest;
81 import org.onap.so.db.catalog.beans.macro.OrchestrationFlow;
82 import org.onap.so.db.catalog.client.CatalogDbClient;
83 import org.onap.so.serviceinstancebeans.CloudConfiguration;
84 import org.onap.so.serviceinstancebeans.ModelInfo;
85 import org.onap.so.serviceinstancebeans.ModelType;
86 import org.onap.so.serviceinstancebeans.Networks;
87 import org.onap.so.serviceinstancebeans.Pnfs;
88 import org.onap.so.serviceinstancebeans.RelatedInstance;
89 import org.onap.so.serviceinstancebeans.RequestDetails;
90 import org.onap.so.serviceinstancebeans.Service;
91 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
92 import org.onap.so.serviceinstancebeans.VfModules;
93 import org.onap.so.serviceinstancebeans.Vnfs;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96 import org.springframework.beans.factory.annotation.Autowired;
97 import org.springframework.core.env.Environment;
98 import org.springframework.stereotype.Component;
99 import org.springframework.util.CollectionUtils;
100 import com.fasterxml.jackson.core.JsonProcessingException;
101 import com.fasterxml.jackson.databind.ObjectMapper;
104 public class WorkflowAction {
106 private static final String WORKFLOW_ACTION_ERROR_MESSAGE = "WorkflowActionErrorMessage";
107 private static final String SERVICE_INSTANCES = "serviceInstances";
108 private static final String SERVICE_INSTANCE = "serviceInstance";
109 private static final String VF_MODULES = "vfModules";
110 private static final String WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI =
111 "WorkflowAction was unable to verify if the instance name already exist in AAI.";
112 private static final String VNF_TYPE = "vnfType";
113 private static final String SERVICE = "Service";
114 private static final String VNF = "Vnf";
115 private static final String PNF = "Pnf";
116 private static final String VFMODULE = "VfModule";
117 private static final String VOLUMEGROUP = "VolumeGroup";
118 private static final String NETWORK = "Network";
119 private static final String NETWORKCOLLECTION = "NetworkCollection";
120 private static final String CONFIGURATION = "Configuration";
121 private static final String ASSIGNINSTANCE = "assignInstance";
122 private static final String CREATEINSTANCE = "createInstance";
123 private static final String REPLACEINSTANCE = "replaceInstance";
124 private static final String REPLACEINSTANCERETAINASSIGNMENTS = "replaceInstanceRetainAssignments";
125 private static final String USERPARAMSERVICE = "service";
126 private static final String SUPPORTEDTYPES =
127 "vnfs|vfModules|networks|networkCollections|volumeGroups|serviceInstances|instanceGroups";
128 private static final String HOMINGSOLUTION = "Homing_Solution";
129 private static final String FABRIC_CONFIGURATION = "FabricConfiguration";
130 private static final String SERVICE_TYPE_TRANSPORT = "TRANSPORT";
131 private static final String SERVICE_TYPE_BONDING = "BONDING";
132 private static final String CLOUD_OWNER = "DEFAULT";
133 private static final Logger logger = LoggerFactory.getLogger(WorkflowAction.class);
134 private static final String NAME_EXISTS_WITH_DIFF_VERSION_ID = "(%s) and different version id (%s)";
135 private static final String NAME_EXISTS_MULTIPLE =
136 "(%s) and multiple combination of model-version-id + service-type + global-customer-id";
137 private static final String NAME_EXISTS_WITH_DIFF_COMBINATION =
138 "(%s) and global-customer-id (%s), service-type (%s), model-version-id (%s)";
139 private static final String NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID =
140 "(%s), same parent and different customization id (%s)";
141 private static final String NAME_EXISTS_WITH_DIFF_PARENT = "(%s) id (%s) and different parent relationship";
142 private static final String CREATENETWORKBB = "CreateNetworkBB";
143 private static final String ACTIVATENETWORKBB = "ActivateNetworkBB";
144 private static final String VOLUMEGROUP_DELETE_PATTERN = "(Un|De)(.*)Volume(.*)";
145 private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
146 private static final String CONTROLLER = "Controller";
147 private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
150 protected BBInputSetup bbInputSetup;
152 protected BBInputSetupUtils bbInputSetupUtils;
154 private ExceptionBuilder exceptionBuilder;
156 private CatalogDbClient catalogDbClient;
158 private AAIConfigurationResources aaiConfigurationResources;
160 private WorkflowActionExtractResourcesAAI workflowActionUtils;
162 private VrfValidation vrfValidation;
164 private Environment environment;
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);
180 final String requestId = (String) execution.getVariable(BBConstants.G_REQUEST_ID);
182 String uri = (String) execution.getVariable(BBConstants.G_URI);
183 boolean isResume = isUriResume(uri);
185 final boolean isALaCarte = (boolean) execution.getVariable(BBConstants.G_ALACARTE);
186 Resource resource = getResource(bbInputSetupUtils, isResume, isALaCarte, uri, requestId);
188 WorkflowResourceIds workflowResourceIds = populateResourceIdsFromApiHandler(execution);
189 RequestDetails requestDetails = sIRequest.getRequestDetails();
190 String requestAction = (String) execution.getVariable(BBConstants.G_ACTION);
191 String resourceId = getResourceId(resource, requestAction, requestDetails, workflowResourceIds);
192 WorkflowType resourceType = resource.getResourceType();
194 String serviceInstanceId = getServiceInstanceId(execution, resourceId, resourceType);
196 fillExecution(execution, requestDetails.getRequestInfo().getSuppressRollback(), resourceId, resourceType);
197 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
199 if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
200 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
201 if (flowsToExecute == null) {
202 buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
204 } else if (isALaCarte && isResume) {
205 flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
206 if (flowsToExecute == null) {
207 buildAndThrowException(execution,
208 "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
211 String vnfType = (String) execution.getVariable(VNF_TYPE);
212 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
213 List<OrchestrationFlow> orchFlows =
214 (List<OrchestrationFlow>) execution.getVariable(BBConstants.G_ORCHESTRATION_FLOW);
215 final String apiVersion = (String) execution.getVariable(BBConstants.G_APIVERSION);
216 final String serviceType =
217 Optional.ofNullable((String) execution.getVariable(BBConstants.G_SERVICE_TYPE)).orElse("");
219 if (orchFlows == null || orchFlows.isEmpty()) {
220 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, true,
221 cloudOwner, serviceType);
223 Resource resourceKey = getResourceKey(sIRequest, resourceType);
225 ReplaceInstanceRelatedInformation replaceInfo = new ReplaceInstanceRelatedInformation();
226 if ((requestAction.equalsIgnoreCase(REPLACEINSTANCE)
227 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
228 && resourceType.equals(WorkflowType.VFMODULE)) {
229 logger.debug("Build a BB list for replacing BB modules");
230 orchFlows = getVfModuleReplaceBuildingBlocks(new ConfigBuildingBlocksDataObject()
231 .setsIRequest(sIRequest).setOrchFlows(orchFlows).setRequestId(requestId)
232 .setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
233 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
234 .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails)
235 .setExecution(execution).setReplaceInformation(replaceInfo));
236 for (OrchestrationFlow orchFlow : orchFlows) {
237 if (orchFlow.getFlowName().contains(CONFIGURATION)) {
238 List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
239 configOrchFlows.add(orchFlow);
240 List<ExecuteBuildingBlock> configBuildingBlocks =
241 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject()
242 .setsIRequest(sIRequest).setOrchFlows(configOrchFlows)
243 .setRequestId(requestId).setResourceKey(resourceKey)
244 .setApiVersion(apiVersion).setResourceId(resourceId)
245 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
246 .setWorkflowResourceIds(workflowResourceIds)
247 .setRequestDetails(requestDetails).setExecution(execution)
248 .setReplaceInformation(replaceInfo));
249 flowsToExecute.addAll(configBuildingBlocks);
251 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
252 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
253 requestDetails, false, null, null, false, replaceInfo);
254 flowsToExecute.add(ebb);
258 if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
259 List<ExecuteBuildingBlock> configBuildingBlocks =
260 getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest)
261 .setOrchFlows(orchFlows).setRequestId(requestId).setResourceKey(resourceKey)
262 .setApiVersion(apiVersion).setResourceId(resourceId)
263 .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
264 .setWorkflowResourceIds(workflowResourceIds)
265 .setRequestDetails(requestDetails).setExecution(execution));
267 flowsToExecute.addAll(configBuildingBlocks);
270 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
271 .collect(Collectors.toList());
273 for (OrchestrationFlow orchFlow : orchFlows) {
274 ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
275 apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
276 requestDetails, false, null, null, false, replaceInfo);
277 flowsToExecute.add(ebb);
281 boolean foundRelated = false;
282 boolean containsService = false;
283 List<Resource> resourceList = new ArrayList<>();
284 List<Pair<WorkflowType, String>> aaiResourceIds = new ArrayList<>();
285 if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(ASSIGNINSTANCE)) {
286 // SERVICE-MACRO-ASSIGN will always get user params with a
288 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
289 List<Map<String, Object>> userParams =
290 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
292 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
293 if (containsService) {
294 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
297 buildAndThrowException(execution,
298 "Service-Macro-Assign request details must contain user params with a service");
300 } else if (resourceType == WorkflowType.SERVICE && requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
301 // SERVICE-MACRO-CREATE will get user params with a service,
302 // a service with a network, a service with a
303 // networkcollection, OR an empty service.
304 // If user params is just a service or null and macro
305 // queries the SI and finds a VNF, macro fails.
307 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
308 List<Map<String, Object>> userParams =
309 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
311 userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
313 if (containsService) {
314 foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
317 traverseCatalogDbService(execution, sIRequest, resourceList, aaiResourceIds);
319 } else if (resourceType == WorkflowType.SERVICE
320 && ("activateInstance".equalsIgnoreCase(requestAction)
321 || "unassignInstance".equalsIgnoreCase(requestAction)
322 || "deleteInstance".equalsIgnoreCase(requestAction)
323 || requestAction.equalsIgnoreCase("activate" + FABRIC_CONFIGURATION))) {
324 // SERVICE-MACRO-ACTIVATE, SERVICE-MACRO-UNASSIGN, and
325 // SERVICE-MACRO-DELETE
326 // Will never get user params with service, macro will have
327 // to query the SI in AAI to find related instances.
328 traverseAAIService(execution, resourceList, resourceId, aaiResourceIds);
329 } else if (resourceType == WorkflowType.SERVICE
330 && "deactivateInstance".equalsIgnoreCase(requestAction)) {
331 resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
332 } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
333 || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
334 traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
335 workflowResourceIds.getVnfId(), aaiResourceIds);
337 buildAndThrowException(execution, "Current Macro Request is not supported");
339 StringBuilder foundObjects = new StringBuilder();
340 for (WorkflowType type : WorkflowType.values()) {
341 foundObjects.append(type).append(" - ").append(
342 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
345 logger.info("Found {}", foundObjects.toString());
347 if (orchFlows == null || orchFlows.isEmpty()) {
348 orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
349 cloudOwner, serviceType);
351 boolean vnfReplace = false;
352 if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
353 || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
356 flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
357 resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, vnfReplace);
358 if (isNetworkCollectionInTheResourceList(resourceList)) {
359 logger.info("Sorting for Vlan Tagging");
360 flowsToExecute = sortExecutionPathByObjectForVlanTagging(flowsToExecute, requestAction);
362 // By default, enable homing at VNF level for CREATEINSTANCE and ASSIGNINSTANCE
363 if (resourceType == WorkflowType.SERVICE
364 && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
365 && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
366 execution.setVariable("homing", true);
367 execution.setVariable("calledHoming", false);
369 if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
370 || requestAction.equalsIgnoreCase(CREATEINSTANCE))) {
371 generateResourceIds(flowsToExecute, resourceList, serviceInstanceId);
373 updateResourceIdsFromAAITraversal(flowsToExecute, resourceList, aaiResourceIds,
378 // If the user set "Homing_Solution" to "none", disable homing, else if "Homing_Solution" is specified,
380 if (sIRequest.getRequestDetails().getRequestParameters() != null
381 && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
382 List<Map<String, Object>> userParams =
383 sIRequest.getRequestDetails().getRequestParameters().getUserParams();
384 for (Map<String, Object> params : userParams) {
385 if (params.containsKey(HOMINGSOLUTION)) {
386 execution.setVariable("homing", !"none".equals(params.get(HOMINGSOLUTION)));
391 if (CollectionUtils.isEmpty(flowsToExecute)) {
392 throw new IllegalStateException("Macro did not come up with a valid execution path.");
395 List<String> flowNames = new ArrayList<>();
396 logger.info("List of BuildingBlocks to execute:");
398 flowsToExecute.forEach(ebb -> {
399 logger.info(ebb.getBuildingBlock().getBpmnFlowName());
400 flowNames.add(ebb.getBuildingBlock().getBpmnFlowName());
404 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
406 execution.setVariable("flowNames", flowNames);
407 execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
408 execution.setVariable("retryCount", 0);
409 execution.setVariable("isRollback", false);
410 execution.setVariable("flowsToExecute", flowsToExecute);
411 execution.setVariable("isRollbackComplete", false);
413 } catch (Exception ex) {
414 if (!(execution.hasVariable("WorkflowException")
415 || execution.hasVariable("WorkflowExceptionExceptionMessage"))) {
416 buildAndThrowException(execution, "Exception while setting execution list. ", ex);
423 private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
424 String resourceId = "";
425 ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
426 if (modelInfo != null) {
427 if (modelInfo.getModelType().equals(ModelType.service)) {
428 resourceId = modelInfo.getModelVersionId();
430 resourceId = modelInfo.getModelCustomizationId();
433 return new Resource(resourceType, resourceId, true);
436 private String getCloudOwner(CloudConfiguration cloudConfiguration) {
437 if (cloudConfiguration != null && cloudConfiguration.getCloudOwner() != null) {
438 return cloudConfiguration.getCloudOwner();
440 logger.warn("cloud owner value not found in request details, it will be set as default");
441 return environment.getProperty(DEFAULT_CLOUD_OWNER);
444 protected <T> List<T> getRelatedResourcesInVfModule(String vnfId, String vfModuleId, Class<T> resultClass,
445 AAIObjectType type) {
446 List<T> vnfcs = new ArrayList<>();
447 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId);
448 AAIResultWrapper vfModuleResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
449 Optional<Relationships> relationshipsOp = vfModuleResultsWrapper.getRelationships();
450 if (!relationshipsOp.isPresent()) {
451 logger.debug("No relationships were found for vfModule in AAI");
453 Relationships relationships = relationshipsOp.get();
454 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(type);
455 for (AAIResultWrapper vnfcResultWrapper : vnfcResultWrappers) {
456 Optional<T> vnfcOp = vnfcResultWrapper.asBean(resultClass);
457 vnfcOp.ifPresent(vnfcs::add);
463 protected <T> List<T> getRelatedResourcesInVnfc(Vnfc vnfc, Class<T> resultClass, AAIObjectType type) {
465 List<T> configurations = new ArrayList<>();
466 AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.VNFC, vnfc.getVnfcName());
467 AAIResultWrapper vnfcResultsWrapper = bbInputSetupUtils.getAAIResourceDepthOne(uri);
468 Optional<Relationships> relationshipsOp = vnfcResultsWrapper.getRelationships();
469 if (!relationshipsOp.isPresent()) {
470 logger.debug("No relationships were found for VNFC in AAI");
472 Relationships relationships = relationshipsOp.get();
473 List<AAIResultWrapper> configurationResultWrappers =
474 this.getResultWrappersFromRelationships(relationships, type);
475 for (AAIResultWrapper configurationResultWrapper : configurationResultWrappers) {
476 Optional<T> configurationOp = configurationResultWrapper.asBean(resultClass);
477 configurationOp.ifPresent(configurations::add);
480 return configurations;
483 protected List<AAIResultWrapper> getResultWrappersFromRelationships(Relationships relationships,
484 AAIObjectType type) {
485 return relationships.getByType(type);
488 protected boolean isConfiguration(List<OrchestrationFlow> orchFlows) {
489 for (OrchestrationFlow flow : orchFlows) {
490 if (flow.getFlowName().contains(CONFIGURATION) && !"ConfigurationScaleOutBB".equals(flow.getFlowName())) {
497 protected List<ExecuteBuildingBlock> getConfigBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
500 List<ExecuteBuildingBlock> flowsToExecuteConfigs = new ArrayList<>();
501 List<OrchestrationFlow> result = dataObj.getOrchFlows().stream()
502 .filter(item -> item.getFlowName().contains(FABRIC_CONFIGURATION)).collect(Collectors.toList());
503 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
504 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
506 String vnfCustomizationUUID = bbInputSetupUtils.getAAIGenericVnf(vnfId).getModelCustomizationId();
507 String vfModuleCustomizationUUID;
508 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
510 if (aaiVfModule == null) {
511 logger.error("No matching VfModule is found in Generic-Vnf in AAI for vnfId: {} and vfModuleId : {}", vnfId,
513 throw new AAIEntityNotFoundException("No matching VfModule is found in Generic-Vnf in AAI for vnfId: "
514 + vnfId + " and vfModuleId : " + vfModuleId);
516 vfModuleCustomizationUUID = aaiVfModule.getModelCustomizationId();
519 List<org.onap.aai.domain.yang.Vnfc> vnfcs = getRelatedResourcesInVfModule(vnfId, vfModuleId,
520 org.onap.aai.domain.yang.Vnfc.class, AAIObjectType.VNFC);
521 for (org.onap.aai.domain.yang.Vnfc vnfc : vnfcs) {
522 List<org.onap.aai.domain.yang.Configuration> configurations = getRelatedResourcesInVnfc(vnfc,
523 org.onap.aai.domain.yang.Configuration.class, AAIObjectType.CONFIGURATION);
524 if (configurations.size() > 1) {
525 String multipleRelationshipsError =
526 "Multiple relationships exist from VNFC " + vnfc.getVnfcName() + " to Configurations";
527 buildAndThrowException(dataObj.getExecution(), "Exception in getConfigBuildingBlock: ",
528 new Exception(multipleRelationshipsError));
530 for (org.onap.aai.domain.yang.Configuration configuration : configurations) {
531 dataObj.getWorkflowResourceIds().setConfigurationId(configuration.getConfigurationId());
532 for (OrchestrationFlow orchFlow : result) {
533 dataObj.getResourceKey().setVfModuleCustomizationId(vfModuleCustomizationUUID);
534 dataObj.getResourceKey().setCvnfModuleCustomizationId(vnfc.getModelCustomizationId());
535 dataObj.getResourceKey().setVnfCustomizationId(vnfCustomizationUUID);
536 String vnfcName = getVnfcNameForConfiguration(configuration);
537 if (vnfcName == null || vnfcName.isEmpty()) {
538 buildAndThrowException(dataObj.getExecution(), "Exception in create execution list "
539 + ": VnfcName does not exist or is null while there is a configuration for the vfModule",
540 new Exception("Vnfc and Configuration do not match"));
542 ExecuteBuildingBlock ebb =
543 buildExecuteBuildingBlock(orchFlow, dataObj.getRequestId(), dataObj.getResourceKey(),
544 dataObj.getApiVersion(), dataObj.getResourceId(), dataObj.getRequestAction(),
545 dataObj.isaLaCarte(), dataObj.getVnfType(), dataObj.getWorkflowResourceIds(),
546 dataObj.getRequestDetails(), false, null, vnfcName, true, null);
547 flowsToExecuteConfigs.add(ebb);
551 return flowsToExecuteConfigs;
554 protected List<OrchestrationFlow> getVfModuleReplaceBuildingBlocks(ConfigBuildingBlocksDataObject dataObj)
557 String vnfId = dataObj.getWorkflowResourceIds().getVnfId();
558 String vfModuleId = dataObj.getWorkflowResourceIds().getVfModuleId();
560 logger.debug("BUILDING REPLACE LIST");
562 boolean volumeGroupExisted = false;
563 boolean volumeGroupWillExist = false;
564 boolean keepVolumeGroup = false;
566 boolean rebuildVolumeGroups = false;
567 if (dataObj.getRequestDetails().getRequestParameters() != null
568 && dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups() != null) {
569 rebuildVolumeGroups = dataObj.getRequestDetails().getRequestParameters().getRebuildVolumeGroups();
571 String volumeGroupName = "";
572 Optional<VolumeGroup> volumeGroupFromVfModule =
573 bbInputSetupUtils.getRelatedVolumeGroupFromVfModule(vnfId, vfModuleId);
574 if (volumeGroupFromVfModule.isPresent()) {
575 String volumeGroupId = volumeGroupFromVfModule.get().getVolumeGroupId();
576 volumeGroupName = volumeGroupFromVfModule.get().getVolumeGroupName();
577 logger.debug("Volume group id of the existing volume group is: " + volumeGroupId);
578 volumeGroupExisted = true;
579 dataObj.getWorkflowResourceIds().setVolumeGroupId(volumeGroupId);
580 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
583 List<OrchestrationFlow> orchFlows = dataObj.getOrchFlows();
584 VfModuleCustomization vfModuleCustomization = catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
585 dataObj.getRequestDetails().getModelInfo().getModelCustomizationUuid());
586 if (vfModuleCustomization != null && vfModuleCustomization.getVfModule() != null
587 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
588 && vfModuleCustomization.getVolumeHeatEnv() != null) {
589 volumeGroupWillExist = true;
590 if (!volumeGroupExisted) {
591 String newVolumeGroupId = UUID.randomUUID().toString();
592 dataObj.getWorkflowResourceIds().setVolumeGroupId(newVolumeGroupId);
593 dataObj.getReplaceInformation().setOldVolumeGroupName(volumeGroupName);
594 logger.debug("newVolumeGroupId: " + newVolumeGroupId);
598 if (volumeGroupExisted && volumeGroupWillExist && !rebuildVolumeGroups) {
599 keepVolumeGroup = true;
602 if (!volumeGroupExisted || keepVolumeGroup) {
603 logger.debug("Filtering out deletion of volume groups");
604 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_DELETE_PATTERN))
605 .collect(Collectors.toList());
607 if (!volumeGroupWillExist || keepVolumeGroup) {
608 logger.debug("Filtering out creation of volume groups");
609 orchFlows = orchFlows.stream().filter(item -> !item.getFlowName().matches(VOLUMEGROUP_CREATE_PATTERN))
610 .collect(Collectors.toList());
616 protected String getVnfcNameForConfiguration(org.onap.aai.domain.yang.Configuration configuration) {
617 AAIResultWrapper wrapper = new AAIResultWrapper(configuration);
618 Optional<Relationships> relationshipsOp = wrapper.getRelationships();
619 if (!relationshipsOp.isPresent()) {
620 logger.debug("No relationships were found for Configuration in AAI");
623 Relationships relationships = relationshipsOp.get();
624 List<AAIResultWrapper> vnfcResultWrappers = relationships.getByType(AAIObjectType.VNFC);
625 if (vnfcResultWrappers.size() != 1) {
626 logger.debug("Too many vnfcs or no vnfc found that are related to configuration");
628 Optional<Vnfc> vnfcOp = vnfcResultWrappers.get(0).asBean(Vnfc.class);
629 return vnfcOp.map(Vnfc::getVnfcName).orElse(null);
633 protected List<Resource> sortVfModulesByBaseFirst(List<Resource> vfModuleResources) {
635 for (Resource resource : vfModuleResources) {
636 if (resource.isBaseVfModule()) {
637 Collections.swap(vfModuleResources, 0, count);
642 return vfModuleResources;
645 protected List<Resource> sortVfModulesByBaseLast(List<Resource> vfModuleResources) {
647 for (Resource resource : vfModuleResources) {
648 if (resource.isBaseVfModule()) {
649 Collections.swap(vfModuleResources, vfModuleResources.size() - 1, count);
654 return vfModuleResources;
657 private void updateResourceIdsFromAAITraversal(List<ExecuteBuildingBlock> flowsToExecute,
658 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds, String serviceInstanceId) {
659 for (Pair<WorkflowType, String> pair : aaiResourceIds) {
660 logger.debug(pair.getValue0() + ", " + pair.getValue1());
663 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
664 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
665 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
666 retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
669 private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
671 for (int i = 0; i < aaiResourceIds.size(); i++) {
672 if (aaiResourceIds.get(i).getValue0() == resource) {
673 id = aaiResourceIds.get(i).getValue1();
674 aaiResourceIds.remove(i);
681 private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
682 String serviceInstanceId) {
683 Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
684 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
685 .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
686 null, resource.getVirtualLinkKey(), serviceInstanceId)));
689 protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
690 String key, String id, String virtualLinkKey, String serviceInstanceId) {
691 String resourceId = id;
692 if (resourceId == null) {
693 resourceId = UUID.randomUUID().toString();
695 for (ExecuteBuildingBlock ebb : flowsToExecute) {
696 if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
697 .getBpmnFlowName().contains(resourceType.toString())
698 || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
699 && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
700 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
701 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
702 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
703 ebb.setWorkflowResourceIds(workflowResourceIds);
705 if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
706 && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
707 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
708 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
709 workflowResourceIds.setNetworkId(resourceId);
710 ebb.setWorkflowResourceIds(workflowResourceIds);
715 protected CollectionResourceCustomization findCatalogNetworkCollection(DelegateExecution execution,
716 org.onap.so.db.catalog.beans.Service service) {
717 CollectionResourceCustomization networkCollection = null;
719 for (CollectionResourceCustomization collectionCust : service.getCollectionResourceCustomizations()) {
720 if (catalogDbClient.getNetworkCollectionResourceCustomizationByID(
721 collectionCust.getModelCustomizationUUID()) != null) {
722 networkCollection = collectionCust;
728 } else if (count > 1) {
729 buildAndThrowException(execution,
730 "Found multiple Network Collections in the Service model, only one per Service is supported.");
732 return networkCollection;
735 protected void traverseCatalogDbService(DelegateExecution execution, ServiceInstancesRequest sIRequest,
736 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds)
737 throws JsonProcessingException, VrfBondingServiceException {
738 String modelUUID = sIRequest.getRequestDetails().getModelInfo().getModelVersionId();
739 org.onap.so.db.catalog.beans.Service service = catalogDbClient.getServiceByID(modelUUID);
740 if (service == null) {
741 buildAndThrowException(execution, "Could not find the service model in catalog db.");
743 resourceList.add(new Resource(WorkflowType.SERVICE, service.getModelUUID(), false));
744 RelatedInstance relatedVpnBinding =
745 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.vpnBinding);
746 RelatedInstance relatedLocalNetwork =
747 bbInputSetupUtils.getRelatedInstanceByType(sIRequest.getRequestDetails(), ModelType.network);
748 if (relatedVpnBinding != null && relatedLocalNetwork != null) {
749 traverseVrfConfiguration(aaiResourceIds, resourceList, service, relatedVpnBinding, relatedLocalNetwork);
751 traverseNetworkCollection(execution, resourceList, service);
756 protected void traverseVrfConfiguration(List<Pair<WorkflowType, String>> aaiResourceIds,
757 List<Resource> resourceList, org.onap.so.db.catalog.beans.Service service,
758 RelatedInstance relatedVpnBinding, RelatedInstance relatedLocalNetwork)
759 throws VrfBondingServiceException, JsonProcessingException {
760 org.onap.aai.domain.yang.L3Network aaiLocalNetwork =
761 bbInputSetupUtils.getAAIL3Network(relatedLocalNetwork.getInstanceId());
762 vrfValidation.vrfServiceValidation(service);
763 vrfValidation.vrfCatalogDbChecks(service);
764 vrfValidation.aaiVpnBindingValidation(relatedVpnBinding.getInstanceId(),
765 bbInputSetupUtils.getAAIVpnBinding(relatedVpnBinding.getInstanceId()));
766 vrfValidation.aaiNetworkValidation(relatedLocalNetwork.getInstanceId(), aaiLocalNetwork);
767 vrfValidation.aaiSubnetValidation(aaiLocalNetwork);
768 vrfValidation.aaiAggregateRouteValidation(aaiLocalNetwork);
769 vrfValidation.aaiRouteTargetValidation(aaiLocalNetwork);
770 String existingAAIVrfConfiguration = getExistingAAIVrfConfiguration(relatedVpnBinding, aaiLocalNetwork);
771 if (existingAAIVrfConfiguration != null) {
772 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, existingAAIVrfConfiguration));
774 resourceList.add(new Resource(WorkflowType.CONFIGURATION,
775 service.getConfigurationCustomizations().get(0).getModelCustomizationUUID(), false));
779 protected String getExistingAAIVrfConfiguration(RelatedInstance relatedVpnBinding,
780 org.onap.aai.domain.yang.L3Network aaiLocalNetwork)
781 throws JsonProcessingException, VrfBondingServiceException {
782 Optional<Relationships> relationshipsOp = new AAIResultWrapper(
783 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiLocalNetwork)).getRelationships();
784 if (relationshipsOp.isPresent()) {
785 List<AAIResultWrapper> configurationsRelatedToLocalNetwork =
786 relationshipsOp.get().getByType(AAIObjectType.CONFIGURATION);
787 if (configurationsRelatedToLocalNetwork.size() > 1) {
788 throw new VrfBondingServiceException(
789 "Network: " + aaiLocalNetwork.getNetworkId() + " has more than 1 configuration related to it");
791 if (configurationsRelatedToLocalNetwork.size() == 1) {
792 AAIResultWrapper configWrapper = configurationsRelatedToLocalNetwork.get(0);
793 Optional<Configuration> relatedConfiguration = configWrapper.asBean(Configuration.class);
794 if (relatedConfiguration.isPresent() && vrfConfigurationAlreadyExists(relatedVpnBinding,
795 relatedConfiguration.get(), configWrapper)) {
796 return relatedConfiguration.get().getConfigurationId();
803 protected boolean vrfConfigurationAlreadyExists(RelatedInstance relatedVpnBinding, Configuration vrfConfiguration,
804 AAIResultWrapper configWrapper) throws VrfBondingServiceException {
805 if ("VRF-ENTRY".equalsIgnoreCase(vrfConfiguration.getConfigurationType())) {
806 Optional<Relationships> relationshipsConfigOp = configWrapper.getRelationships();
807 if (relationshipsConfigOp.isPresent()) {
808 Optional<VpnBinding> relatedInfraVpnBindingOp =
809 workflowActionUtils.extractRelationshipsVpnBinding(relationshipsConfigOp.get());
810 if (relatedInfraVpnBindingOp.isPresent()) {
811 VpnBinding relatedInfraVpnBinding = relatedInfraVpnBindingOp.get();
812 if (!relatedInfraVpnBinding.getVpnId().equalsIgnoreCase(relatedVpnBinding.getInstanceId())) {
813 throw new VrfBondingServiceException("Configuration: " + vrfConfiguration.getConfigurationId()
814 + " is not connected to the same vpn binding id provided in request: "
815 + relatedVpnBinding.getInstanceId());
825 protected void traverseNetworkCollection(DelegateExecution execution, List<Resource> resourceList,
826 org.onap.so.db.catalog.beans.Service service) {
827 if (isVnfCustomizationsInTheService(service)) {
828 buildAndThrowException(execution,
829 "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");
831 List<CollectionResourceCustomization> customizations = service.getCollectionResourceCustomizations();
832 if (customizations.isEmpty()) {
833 logger.debug("No Collections found. CollectionResourceCustomization list is empty.");
835 CollectionResourceCustomization collectionResourceCustomization =
836 findCatalogNetworkCollection(execution, service);
837 traverseNetworkCollectionResourceCustomization(resourceList, collectionResourceCustomization);
839 traverseNetworkCollectionCustomization(resourceList, service);
842 private void traverseNetworkCollectionResourceCustomization(List<Resource> resourceList,
843 CollectionResourceCustomization collectionResourceCustomization) {
844 if (collectionResourceCustomizationShouldNotBeProcessed(resourceList, collectionResourceCustomization))
847 org.onap.so.db.catalog.beans.InstanceGroup instanceGroup =
848 collectionResourceCustomization.getCollectionResource().getInstanceGroup();
849 CollectionResourceInstanceGroupCustomization collectionInstCust = null;
850 if (!instanceGroup.getCollectionInstanceGroupCustomizations().isEmpty()) {
851 for (CollectionResourceInstanceGroupCustomization collectionInstanceGroupTemp : instanceGroup
852 .getCollectionInstanceGroupCustomizations()) {
853 if (collectionInstanceGroupTemp.getModelCustomizationUUID()
854 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
855 collectionInstCust = collectionInstanceGroupTemp;
859 if (interfaceNetworkQuantityIsAvailableInCollection(collectionInstCust)) {
860 minNetworks = collectionInstCust.getSubInterfaceNetworkQuantity();
863 logger.debug("minNetworks: {}", minNetworks);
864 CollectionNetworkResourceCustomization collectionNetworkResourceCust =
865 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
866 for (int i = 0; i < minNetworks; i++) {
867 if (collectionNetworkResourceCust != null && collectionInstCust != null) {
868 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
869 collectionNetworkResourceCust.getModelCustomizationUUID(), false);
870 resource.setVirtualLinkKey(Integer.toString(i));
871 resourceList.add(resource);
876 private CollectionNetworkResourceCustomization getCollectionNetworkResourceCustomization(
877 CollectionResourceCustomization collectionResourceCustomization, InstanceGroup instanceGroup) {
878 CollectionNetworkResourceCustomization collectionNetworkResourceCust = null;
879 for (CollectionNetworkResourceCustomization collectionNetworkTemp : instanceGroup
880 .getCollectionNetworkResourceCustomizations()) {
881 if (collectionNetworkTemp.getNetworkResourceCustomization().getModelCustomizationUUID()
882 .equalsIgnoreCase(collectionResourceCustomization.getModelCustomizationUUID())) {
883 collectionNetworkResourceCust = collectionNetworkTemp;
887 return collectionNetworkResourceCust;
890 private boolean collectionResourceCustomizationShouldNotBeProcessed(List<Resource> resourceList,
891 CollectionResourceCustomization collectionResourceCustomization) {
892 if (collectionResourceCustomization == null) {
893 logger.debug("No Network Collection Customization found");
896 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
897 collectionResourceCustomization.getModelCustomizationUUID(), false));
898 logger.debug("Found a network collection");
899 if (collectionResourceCustomization.getCollectionResource() == null) {
900 logger.debug("No Network Collection found. collectionResource is null");
903 if (collectionResourceCustomization.getCollectionResource().getInstanceGroup() == null) {
904 logger.debug("No Instance Group found for network collection.");
907 String toscaNodeType =
908 collectionResourceCustomization.getCollectionResource().getInstanceGroup().getToscaNodeType();
909 if (!toscaNodeTypeHasNetworkCollection(toscaNodeType)) {
910 logger.debug("Instance Group tosca node type does not contain NetworkCollection: {}", toscaNodeType);
916 private boolean interfaceNetworkQuantityIsAvailableInCollection(
917 CollectionResourceInstanceGroupCustomization collectionInstCust) {
918 return collectionInstCust != null && collectionInstCust.getSubInterfaceNetworkQuantity() != null;
921 private boolean toscaNodeTypeHasNetworkCollection(String toscaNodeType) {
922 return toscaNodeType != null && toscaNodeType.contains(NETWORKCOLLECTION);
925 private void traverseNetworkCollectionCustomization(List<Resource> resourceList,
926 org.onap.so.db.catalog.beans.Service service) {
927 if (isNetworkCollectionInTheResourceList(resourceList)) {
930 if (service.getNetworkCustomizations() == null) {
931 logger.debug("No networks were found on this service model");
934 for (int i = 0; i < service.getNetworkCustomizations().size(); i++) {
935 resourceList.add(new Resource(WorkflowType.NETWORK,
936 service.getNetworkCustomizations().get(i).getModelCustomizationUUID(), false));
940 private boolean isNetworkCollectionInTheResourceList(List<Resource> resourceList) {
941 return resourceList.stream().anyMatch(x -> WorkflowType.NETWORKCOLLECTION == x.getResourceType());
944 private boolean isVnfCustomizationsInTheService(org.onap.so.db.catalog.beans.Service service) {
945 return !(service.getVnfCustomizations() == null || service.getVnfCustomizations().isEmpty());
948 protected void traverseAAIService(DelegateExecution execution, List<Resource> resourceList, String resourceId,
949 List<Pair<WorkflowType, String>> aaiResourceIds) {
951 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(resourceId);
952 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
953 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
954 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
955 traverseServiceInstanceMSOVnfs(resourceList, aaiResourceIds, serviceInstanceMSO);
956 if (serviceInstanceMSO.getNetworks() != null) {
957 for (org.onap.so.bpmn.servicedecomposition.bbobjects.L3Network network : serviceInstanceMSO
959 aaiResourceIds.add(new Pair<>(WorkflowType.NETWORK, network.getNetworkId()));
960 resourceList.add(new Resource(WorkflowType.NETWORK, network.getNetworkId(), false));
963 if (serviceInstanceMSO.getCollection() != null) {
964 logger.debug("found networkcollection");
966 .add(new Pair<>(WorkflowType.NETWORKCOLLECTION, serviceInstanceMSO.getCollection().getId()));
967 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION,
968 serviceInstanceMSO.getCollection().getId(), false));
970 if (serviceInstanceMSO.getConfigurations() != null) {
971 for (Configuration config : serviceInstanceMSO.getConfigurations()) {
972 Optional<org.onap.aai.domain.yang.Configuration> aaiConfig =
973 aaiConfigurationResources.getConfiguration(config.getConfigurationId());
974 if (aaiConfig.isPresent() && aaiConfig.get().getRelationshipList() != null) {
975 for (Relationship relationship : aaiConfig.get().getRelationshipList().getRelationship()) {
976 if (relationship.getRelatedTo().contains("vnfc")
977 || relationship.getRelatedTo().contains("vpn-binding")) {
978 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.getConfigurationId()));
980 new Resource(WorkflowType.CONFIGURATION, config.getConfigurationId(), false));
987 } catch (Exception ex) {
988 logger.error("Exception in traverseAAIService", ex);
989 buildAndThrowException(execution,
990 "Could not find existing Service Instance or related Instances to execute the request on.");
994 private void traverseServiceInstanceMSOVnfs(List<Resource> resourceList,
995 List<Pair<WorkflowType, String>> aaiResourceIds,
996 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO) {
997 if (serviceInstanceMSO.getVnfs() == null) {
1000 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1001 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1002 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1003 traverseVnfModules(resourceList, aaiResourceIds, vnf);
1004 if (vnf.getVolumeGroups() != null) {
1005 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf.getVolumeGroups()) {
1006 aaiResourceIds.add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1007 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1013 private void traverseVnfModules(List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds,
1014 org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf) {
1015 if (vnf.getVfModules() == null) {
1018 for (VfModule vfModule : vnf.getVfModules()) {
1019 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1020 Resource resource = new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false);
1021 resource.setBaseVfModule(vfModule.getModelInfoVfModule().getIsBaseBoolean());
1022 resourceList.add(resource);
1026 private void traverseAAIVnf(DelegateExecution execution, List<Resource> resourceList, String serviceId,
1027 String vnfId, List<Pair<WorkflowType, String>> aaiResourceIds) {
1029 ServiceInstance serviceInstanceAAI = bbInputSetupUtils.getAAIServiceInstanceById(serviceId);
1030 org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance serviceInstanceMSO =
1031 bbInputSetup.getExistingServiceInstance(serviceInstanceAAI);
1032 resourceList.add(new Resource(WorkflowType.SERVICE, serviceInstanceMSO.getServiceInstanceId(), false));
1033 if (serviceInstanceMSO.getVnfs() != null) {
1034 for (org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf vnf : serviceInstanceMSO.getVnfs()) {
1035 if (vnf.getVnfId().equals(vnfId)) {
1036 aaiResourceIds.add(new Pair<>(WorkflowType.VNF, vnf.getVnfId()));
1037 resourceList.add(new Resource(WorkflowType.VNF, vnf.getVnfId(), false));
1038 if (vnf.getVfModules() != null) {
1039 for (VfModule vfModule : vnf.getVfModules()) {
1040 aaiResourceIds.add(new Pair<>(WorkflowType.VFMODULE, vfModule.getVfModuleId()));
1041 resourceList.add(new Resource(WorkflowType.VFMODULE, vfModule.getVfModuleId(), false));
1042 findConfigurationsInsideVfModule(execution, vnf.getVnfId(), vfModule.getVfModuleId(),
1043 resourceList, aaiResourceIds);
1046 if (vnf.getVolumeGroups() != null) {
1047 for (org.onap.so.bpmn.servicedecomposition.bbobjects.VolumeGroup volumeGroup : vnf
1048 .getVolumeGroups()) {
1050 .add(new Pair<>(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId()));
1052 new Resource(WorkflowType.VOLUMEGROUP, volumeGroup.getVolumeGroupId(), false));
1059 } catch (Exception ex) {
1060 logger.error("Exception in traverseAAIVnf", ex);
1061 buildAndThrowException(execution,
1062 "Could not find existing Vnf or related Instances to execute the request on.");
1066 private void findConfigurationsInsideVfModule(DelegateExecution execution, String vnfId, String vfModuleId,
1067 List<Resource> resourceList, List<Pair<WorkflowType, String>> aaiResourceIds) {
1069 org.onap.aai.domain.yang.VfModule aaiVfModule = bbInputSetupUtils.getAAIVfModule(vnfId, vfModuleId);
1070 AAIResultWrapper vfModuleWrapper = new AAIResultWrapper(
1071 new AAICommonObjectMapperProvider().getMapper().writeValueAsString(aaiVfModule));
1072 Optional<Relationships> relationshipsOp;
1073 relationshipsOp = vfModuleWrapper.getRelationships();
1074 if (relationshipsOp.isPresent()) {
1075 relationshipsOp = workflowActionUtils.extractRelationshipsVnfc(relationshipsOp.get());
1076 if (relationshipsOp.isPresent()) {
1077 Optional<Configuration> config =
1078 workflowActionUtils.extractRelationshipsConfiguration(relationshipsOp.get());
1079 if (config.isPresent()) {
1080 aaiResourceIds.add(new Pair<>(WorkflowType.CONFIGURATION, config.get().getConfigurationId()));
1082 new Resource(WorkflowType.CONFIGURATION, config.get().getConfigurationId(), false));
1086 } catch (Exception ex) {
1087 logger.error("Exception in findConfigurationsInsideVfModule", ex);
1088 buildAndThrowException(execution, "Failed to find Configuration object from the vfModule.");
1092 protected boolean traverseUserParamsService(DelegateExecution execution, List<Resource> resourceList,
1093 ServiceInstancesRequest sIRequest, String requestAction) throws IOException {
1094 boolean foundRelated = false;
1095 boolean foundVfModuleOrVG = false;
1096 String vnfCustomizationUUID = "";
1097 String vfModuleCustomizationUUID = "";
1098 if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
1099 List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
1100 for (Map<String, Object> params : userParams) {
1101 if (params.containsKey(USERPARAMSERVICE)) {
1102 ObjectMapper obj = new ObjectMapper();
1103 String input = obj.writeValueAsString(params.get(USERPARAMSERVICE));
1104 Service validate = obj.readValue(input, Service.class);
1106 new Resource(WorkflowType.SERVICE, validate.getModelInfo().getModelVersionId(), false));
1107 if (validate.getResources().getVnfs() != null) {
1108 for (Vnfs vnf : validate.getResources().getVnfs()) {
1109 resourceList.add(new Resource(WorkflowType.VNF,
1110 vnf.getModelInfo().getModelCustomizationId(), false));
1111 foundRelated = true;
1112 if (vnf.getModelInfo() != null && vnf.getModelInfo().getModelCustomizationUuid() != null) {
1113 vnfCustomizationUUID = vnf.getModelInfo().getModelCustomizationUuid();
1115 if (vnf.getVfModules() != null) {
1116 for (VfModules vfModule : vnf.getVfModules()) {
1117 VfModuleCustomization vfModuleCustomization =
1118 catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID(
1119 vfModule.getModelInfo().getModelCustomizationUuid());
1120 if (vfModuleCustomization != null) {
1122 if (vfModuleCustomization.getVfModule() != null
1123 && vfModuleCustomization.getVfModule().getVolumeHeatTemplate() != null
1124 && vfModuleCustomization.getVolumeHeatEnv() != null) {
1125 resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
1126 vfModuleCustomization.getModelCustomizationUUID(), false));
1127 foundRelated = true;
1128 foundVfModuleOrVG = true;
1131 if (vfModuleCustomization.getVfModule() != null
1132 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
1133 && vfModuleCustomization.getHeatEnvironment() != null) {
1134 foundRelated = true;
1135 foundVfModuleOrVG = true;
1136 Resource resource = new Resource(WorkflowType.VFMODULE,
1137 vfModuleCustomization.getModelCustomizationUUID(), false);
1138 resource.setBaseVfModule(
1139 vfModuleCustomization.getVfModule().getIsBase() != null
1140 && vfModuleCustomization.getVfModule().getIsBase());
1141 resourceList.add(resource);
1142 if (vfModule.getModelInfo() != null
1143 && vfModule.getModelInfo().getModelCustomizationUuid() != null) {
1144 vfModuleCustomizationUUID =
1145 vfModule.getModelInfo().getModelCustomizationUuid();
1147 if (!vnfCustomizationUUID.isEmpty()
1148 && !vfModuleCustomizationUUID.isEmpty()) {
1149 List<CvnfcConfigurationCustomization> configs =
1150 traverseCatalogDbForConfiguration(
1151 validate.getModelInfo().getModelVersionId(),
1152 vnfCustomizationUUID, vfModuleCustomizationUUID);
1153 for (CvnfcConfigurationCustomization config : configs) {
1154 Resource configResource = new Resource(WorkflowType.CONFIGURATION,
1155 config.getConfigurationResource().getModelUUID(), false);
1156 resource.setVnfCustomizationId(
1157 vnf.getModelInfo().getModelCustomizationId());
1158 resource.setVfModuleCustomizationId(
1159 vfModule.getModelInfo().getModelCustomizationId());
1160 resourceList.add(configResource);
1164 if (!foundVfModuleOrVG) {
1165 buildAndThrowException(execution,
1166 "Could not determine if vfModule was a vfModule or volume group. Heat template and Heat env are null");
1173 if (validate.getResources().getPnfs() != null) {
1174 for (Pnfs pnf : validate.getResources().getPnfs()) {
1175 resourceList.add(new Resource(WorkflowType.PNF,
1176 pnf.getModelInfo().getModelCustomizationId(), false));
1177 foundRelated = true;
1180 if (validate.getResources().getNetworks() != null) {
1181 for (Networks network : validate.getResources().getNetworks()) {
1182 resourceList.add(new Resource(WorkflowType.NETWORK,
1183 network.getModelInfo().getModelCustomizationId(), false));
1184 foundRelated = true;
1186 if (requestAction.equals(CREATEINSTANCE)) {
1187 String networkColCustId = queryCatalogDBforNetworkCollection(execution, sIRequest);
1188 if (networkColCustId != null) {
1189 resourceList.add(new Resource(WorkflowType.NETWORKCOLLECTION, networkColCustId, false));
1190 foundRelated = true;
1198 return foundRelated;
1201 protected List<CvnfcConfigurationCustomization> traverseCatalogDbForConfiguration(String serviceModelUUID,
1202 String vnfCustomizationUUID, String vfModuleCustomizationUUID) {
1203 List<CvnfcConfigurationCustomization> configurations = new ArrayList<>();
1205 List<CvnfcCustomization> cvnfcCustomizations = catalogDbClient.getCvnfcCustomization(serviceModelUUID,
1206 vnfCustomizationUUID, vfModuleCustomizationUUID);
1207 for (CvnfcCustomization cvnfc : cvnfcCustomizations) {
1208 for (CvnfcConfigurationCustomization customization : cvnfc.getCvnfcConfigurationCustomization()) {
1209 if (customization.getConfigurationResource().getToscaNodeType().contains(FABRIC_CONFIGURATION)) {
1210 configurations.add(customization);
1214 logger.debug("found {} fabric configuration(s)", configurations.size());
1215 return configurations;
1216 } catch (Exception ex) {
1217 logger.error("Error in finding configurations", ex);
1218 return configurations;
1222 protected String queryCatalogDBforNetworkCollection(DelegateExecution execution,
1223 ServiceInstancesRequest sIRequest) {
1224 org.onap.so.db.catalog.beans.Service service =
1225 catalogDbClient.getServiceByID(sIRequest.getRequestDetails().getModelInfo().getModelVersionId());
1226 if (service != null) {
1227 CollectionResourceCustomization networkCollection = this.findCatalogNetworkCollection(execution, service);
1228 if (networkCollection != null) {
1229 return networkCollection.getModelCustomizationUUID();
1235 protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
1236 return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
1239 protected Resource extractResourceIdAndTypeFromUri(String uri) {
1240 Pattern patt = Pattern.compile("[vV]\\d+.*?(?:(?:/(?<type>" + SUPPORTEDTYPES
1241 + ")(?:/(?<id>[^/]+))?)(?:/(?<action>[^/]+))?(?:/resume)?)?$");
1242 Matcher m = patt.matcher(uri);
1243 boolean generated = false;
1246 logger.debug("found match on {} : {} ", uri, m);
1247 String type = m.group("type");
1248 String id = m.group("id");
1249 String action = m.group("action");
1251 throw new IllegalArgumentException("Uri could not be parsed. No type found. " + uri);
1253 if (action == null) {
1254 if (type.equals(SERVICE_INSTANCES) && (id == null || "assign".equals(id))) {
1255 id = UUID.randomUUID().toString();
1257 } else if (type.equals(VF_MODULES) && "scaleOut".equals(id)) {
1258 id = UUID.randomUUID().toString();
1262 if (action.matches(SUPPORTEDTYPES)) {
1263 id = UUID.randomUUID().toString();
1268 return new Resource(WorkflowType.fromString(convertTypeFromPlural(type)), id, generated);
1270 throw new IllegalArgumentException("Uri could not be parsed: " + uri);
1274 protected String validateResourceIdInAAI(String generatedResourceId, WorkflowType type, String instanceName,
1275 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws Exception {
1277 if ("SERVICE".equalsIgnoreCase(type.toString())) {
1278 return validateServiceResourceIdInAAI(generatedResourceId, instanceName, reqDetails);
1279 } else if ("NETWORK".equalsIgnoreCase(type.toString())) {
1280 return validateNetworkResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1281 workflowResourceIds);
1282 } else if ("VNF".equalsIgnoreCase(type.toString())) {
1283 return validateVnfResourceIdInAAI(generatedResourceId, instanceName, reqDetails, workflowResourceIds);
1284 } else if ("VFMODULE".equalsIgnoreCase(type.toString())) {
1285 return validateVfModuleResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1286 workflowResourceIds);
1287 } else if ("VOLUMEGROUP".equalsIgnoreCase(type.toString())) {
1288 return validateVolumeGroupResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1289 workflowResourceIds);
1290 } else if ("CONFIGURATION".equalsIgnoreCase(type.toString())) {
1291 return validateConfigurationResourceIdInAAI(generatedResourceId, instanceName, reqDetails,
1292 workflowResourceIds);
1294 return generatedResourceId;
1295 } catch (DuplicateNameException dne) {
1297 } catch (Exception ex) {
1298 logger.error(WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI, ex);
1299 throw new IllegalStateException(
1300 WORKFLOW_ACTION_WAS_UNABLE_TO_VERIFY_IF_THE_INSTANCE_NAME_ALREADY_EXIST_IN_AAI);
1304 protected String convertTypeFromPlural(String type) {
1305 if (!type.matches(SUPPORTEDTYPES)) {
1308 if (type.equals(SERVICE_INSTANCES)) {
1311 return type.substring(0, 1).toUpperCase() + type.substring(1, type.length() - 1);
1316 protected List<ExecuteBuildingBlock> sortExecutionPathByObjectForVlanTagging(List<ExecuteBuildingBlock> orchFlows,
1317 String requestAction) {
1318 List<ExecuteBuildingBlock> sortedOrchFlows = new ArrayList<>();
1319 if (requestAction.equals(CREATEINSTANCE)) {
1320 for (ExecuteBuildingBlock ebb : orchFlows) {
1321 if (ebb.getBuildingBlock().getBpmnFlowName().equals("AssignNetworkBB")) {
1322 String key = ebb.getBuildingBlock().getKey();
1323 boolean isVirtualLink = Boolean.TRUE.equals(ebb.getBuildingBlock().isVirtualLink());
1324 String virtualLinkKey = ebb.getBuildingBlock().getVirtualLinkKey();
1325 sortedOrchFlows.add(ebb);
1326 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1327 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1328 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1329 sortedOrchFlows.add(ebb2);
1332 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1333 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1334 sortedOrchFlows.add(ebb2);
1338 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1339 if (!isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1340 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1341 sortedOrchFlows.add(ebb2);
1344 if (isVirtualLink && ebb2.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)
1345 && ebb2.getBuildingBlock().getVirtualLinkKey().equalsIgnoreCase(virtualLinkKey)) {
1346 sortedOrchFlows.add(ebb2);
1350 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals(CREATENETWORKBB)
1351 || ebb.getBuildingBlock().getBpmnFlowName().equals(ACTIVATENETWORKBB)) {
1353 } else if (!"".equals(ebb.getBuildingBlock().getBpmnFlowName())) {
1354 sortedOrchFlows.add(ebb);
1357 } else if (requestAction.equals("deleteInstance")) {
1358 for (ExecuteBuildingBlock ebb : orchFlows) {
1359 if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeactivateNetworkBB")) {
1360 sortedOrchFlows.add(ebb);
1361 String key = ebb.getBuildingBlock().getKey();
1362 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1363 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1364 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1365 sortedOrchFlows.add(ebb2);
1369 for (ExecuteBuildingBlock ebb2 : orchFlows) {
1370 if (ebb2.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")
1371 && ebb2.getBuildingBlock().getKey().equalsIgnoreCase(key)) {
1372 sortedOrchFlows.add(ebb2);
1376 } else if (ebb.getBuildingBlock().getBpmnFlowName().equals("DeleteNetworkBB")
1377 || ebb.getBuildingBlock().getBpmnFlowName().equals("UnassignNetworkBB")) {
1379 } else if (!ebb.getBuildingBlock().getBpmnFlowName().equals("")) {
1380 sortedOrchFlows.add(ebb);
1384 return sortedOrchFlows;
1387 private void addBuildingBlockToExecuteBBList(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
1388 WorkflowType workflowType, OrchestrationFlow orchFlow, String requestId, String apiVersion,
1389 String resourceId, String requestAction, String vnfType, WorkflowResourceIds workflowResourceIds,
1390 RequestDetails requestDetails, boolean isVirtualLink, boolean isConfiguration) {
1392 resourceList.stream().filter(resource -> resource.getResourceType().equals(workflowType))
1393 .forEach(resource -> flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource,
1394 apiVersion, resourceId, requestAction, false, vnfType, workflowResourceIds, requestDetails,
1395 isVirtualLink, resource.getVirtualLinkKey(), null, isConfiguration, null)));
1398 protected List<ExecuteBuildingBlock> buildExecuteBuildingBlockList(List<OrchestrationFlow> orchFlows,
1399 List<Resource> resourceList, String requestId, String apiVersion, String resourceId, String requestAction,
1400 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1401 boolean replaceVnf) {
1402 List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
1403 for (OrchestrationFlow orchFlow : orchFlows) {
1404 if (orchFlow.getFlowName().contains(SERVICE)) {
1406 workflowResourceIds.setServiceInstanceId(resourceId);
1408 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.SERVICE, orchFlow, requestId,
1409 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1411 } else if (orchFlow.getFlowName().contains(VNF) || (orchFlow.getFlowName().contains(CONTROLLER)
1412 && (VNF).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1413 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VNF, orchFlow, requestId,
1414 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1416 } else if (orchFlow.getFlowName().contains(PNF)) {
1417 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.PNF, orchFlow, requestId,
1418 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1420 } else if (orchFlow.getFlowName().contains(NETWORK)
1421 && !orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1422 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORK, orchFlow, requestId,
1423 apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails, false,
1425 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VIRTUAL_LINK, orchFlow,
1426 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1428 } else if (orchFlow.getFlowName().contains(VFMODULE) || (orchFlow.getFlowName().contains(CONTROLLER)
1429 && (VFMODULE).equalsIgnoreCase(orchFlow.getBpmnScope()))) {
1430 List<Resource> vfModuleResourcesSorted;
1431 if (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE)
1432 || requestAction.equals("activateInstance")) {
1433 vfModuleResourcesSorted = sortVfModulesByBaseFirst(resourceList.stream()
1434 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1436 vfModuleResourcesSorted = sortVfModulesByBaseLast(resourceList.stream()
1437 .filter(x -> WorkflowType.VFMODULE == x.getResourceType()).collect(Collectors.toList()));
1439 for (Resource resource : vfModuleResourcesSorted) {
1440 flowsToExecute.add(buildExecuteBuildingBlock(orchFlow, requestId, resource, apiVersion, resourceId,
1441 requestAction, false, vnfType, workflowResourceIds, requestDetails, false, null, null,
1444 } else if (orchFlow.getFlowName().contains(VOLUMEGROUP)) {
1445 if (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1446 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)) {
1447 logger.debug("Replacing workflow resource id by volume group id");
1448 resourceId = workflowResourceIds.getVolumeGroupId();
1450 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.VOLUMEGROUP, orchFlow,
1451 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1453 } else if (orchFlow.getFlowName().contains(NETWORKCOLLECTION)) {
1454 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.NETWORKCOLLECTION, orchFlow,
1455 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1457 } else if (orchFlow.getFlowName().contains(CONFIGURATION)) {
1458 addBuildingBlockToExecuteBBList(flowsToExecute, resourceList, WorkflowType.CONFIGURATION, orchFlow,
1459 requestId, apiVersion, resourceId, requestAction, vnfType, workflowResourceIds, requestDetails,
1463 .add(buildExecuteBuildingBlock(orchFlow, requestId, null, apiVersion, resourceId, requestAction,
1464 false, vnfType, workflowResourceIds, requestDetails, false, null, null, false, null));
1467 return flowsToExecute;
1470 protected ExecuteBuildingBlock buildExecuteBuildingBlock(OrchestrationFlow orchFlow, String requestId,
1471 Resource resource, String apiVersion, String resourceId, String requestAction, boolean aLaCarte,
1472 String vnfType, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
1473 boolean isVirtualLink, String virtualLinkKey, String vnfcName, boolean isConfiguration,
1474 ReplaceInstanceRelatedInformation replaceInfo) {
1476 BuildingBlock buildingBlock =
1477 new BuildingBlock().setBpmnFlowName(orchFlow.getFlowName()).setMsoId(UUID.randomUUID().toString())
1478 .setIsVirtualLink(isVirtualLink).setVirtualLinkKey(virtualLinkKey)
1479 .setKey(Optional.ofNullable(resource).map(Resource::getResourceId).orElse(""));
1480 Optional.ofNullable(orchFlow.getBpmnAction()).ifPresent(buildingBlock::setBpmnAction);
1481 Optional.ofNullable(orchFlow.getBpmnScope()).ifPresent(buildingBlock::setBpmnScope);
1482 String oldVolumeGroupName = "";
1483 if (replaceInfo != null) {
1484 oldVolumeGroupName = replaceInfo.getOldVolumeGroupName();
1486 if (resource != null
1487 && (orchFlow.getFlowName().contains(VOLUMEGROUP) && (requestAction.equalsIgnoreCase(REPLACEINSTANCE)
1488 || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS)))) {
1489 logger.debug("Setting resourceId to volume group id for volume group flow on replace");
1490 resourceId = workflowResourceIds.getVolumeGroupId();
1493 ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock().setApiVersion(apiVersion)
1494 .setaLaCarte(aLaCarte).setRequestAction(requestAction).setResourceId(resourceId).setVnfType(vnfType)
1495 .setWorkflowResourceIds(workflowResourceIds).setRequestId(requestId).setBuildingBlock(buildingBlock)
1496 .setRequestDetails(requestDetails).setOldVolumeGroupName(oldVolumeGroupName);
1498 if (resource != null && (isConfiguration || resource.getResourceType().equals(WorkflowType.CONFIGURATION))) {
1499 ConfigurationResourceKeys configurationResourceKeys = getConfigurationResourceKeys(resource, vnfcName);
1500 executeBuildingBlock.setConfigurationResourceKeys(configurationResourceKeys);
1502 return executeBuildingBlock;
1505 private ConfigurationResourceKeys getConfigurationResourceKeys(Resource resource, String vnfcName) {
1506 ConfigurationResourceKeys configurationResourceKeys = new ConfigurationResourceKeys();
1507 Optional.ofNullable(vnfcName).ifPresent(configurationResourceKeys::setVnfcName);
1508 configurationResourceKeys.setCvnfcCustomizationUUID(resource.getCvnfModuleCustomizationId());
1509 configurationResourceKeys.setVfModuleCustomizationUUID(resource.getVfModuleCustomizationId());
1510 configurationResourceKeys.setVnfResourceCustomizationUUID(resource.getVnfCustomizationId());
1511 return configurationResourceKeys;
1514 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1515 WorkflowType resourceName, boolean aLaCarte, String cloudOwner) {
1516 return this.queryNorthBoundRequestCatalogDb(execution, requestAction, resourceName, aLaCarte, cloudOwner, "");
1519 protected List<OrchestrationFlow> queryNorthBoundRequestCatalogDb(DelegateExecution execution, String requestAction,
1520 WorkflowType resourceName, boolean aLaCarte, String cloudOwner, String serviceType) {
1521 List<OrchestrationFlow> listToExecute = new ArrayList<>();
1522 NorthBoundRequest northBoundRequest;
1523 if (serviceType.equalsIgnoreCase(SERVICE_TYPE_TRANSPORT)
1524 || serviceType.equalsIgnoreCase(SERVICE_TYPE_BONDING)) {
1526 catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwnerAndServiceType(
1527 requestAction, resourceName.toString(), aLaCarte, cloudOwner, serviceType);
1529 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1530 requestAction, resourceName.toString(), aLaCarte, cloudOwner);
1532 if (northBoundRequest == null) {
1533 northBoundRequest = catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(
1534 requestAction, resourceName.toString(), aLaCarte, CLOUD_OWNER);
1536 if (northBoundRequest == null) {
1537 buildAndThrowException(execution, String.format("The request: %s %s %s is not supported by GR_API.",
1538 (aLaCarte ? "AlaCarte" : "Macro"), resourceName, requestAction));
1540 if (northBoundRequest.getIsToplevelflow() != null) {
1541 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, northBoundRequest.getIsToplevelflow());
1543 List<OrchestrationFlow> flows = northBoundRequest.getOrchestrationFlowList();
1545 flows = new ArrayList<>();
1546 for (OrchestrationFlow flow : flows) {
1547 if (!flow.getFlowName().contains("BB") && !flow.getFlowName().contains("Activity")) {
1548 List<OrchestrationFlow> macroQueryFlows =
1549 catalogDbClient.getOrchestrationFlowByAction(flow.getFlowName());
1550 listToExecute.addAll(macroQueryFlows);
1552 listToExecute.add(flow);
1556 return listToExecute;
1559 protected void buildAndThrowException(DelegateExecution execution, String msg, Exception ex) {
1560 logger.error(msg, ex);
1561 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg + ex.getMessage());
1562 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg + ex.getMessage());
1565 protected void buildAndThrowException(DelegateExecution execution, String msg) {
1567 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, msg);
1568 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, msg);
1571 public void handleRuntimeException(DelegateExecution execution) {
1572 StringBuilder wfeExpMsg = new StringBuilder("Runtime error ");
1573 String runtimeErrorMessage;
1575 String javaExpMsg = (String) execution.getVariable("BPMN_javaExpMsg");
1576 if (javaExpMsg != null && !javaExpMsg.isEmpty()) {
1577 wfeExpMsg.append(": ").append(javaExpMsg);
1579 runtimeErrorMessage = wfeExpMsg.toString();
1580 logger.error(runtimeErrorMessage);
1581 execution.setVariable(WORKFLOW_ACTION_ERROR_MESSAGE, runtimeErrorMessage);
1582 } catch (Exception e) {
1583 logger.error("Runtime error", e);
1584 // if runtime message was mulformed
1585 runtimeErrorMessage = "Runtime error";
1587 exceptionBuilder.buildAndThrowWorkflowException(execution, 7000, runtimeErrorMessage);
1590 protected boolean isUriResume(String uri) {
1591 return uri.endsWith("/resume");
1594 protected boolean isRequestMacroServiceResume(boolean aLaCarte, WorkflowType resourceType, String requestAction,
1595 String serviceInstanceId) {
1596 return (!aLaCarte && resourceType == WorkflowType.SERVICE
1597 && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE) || requestAction.equalsIgnoreCase(CREATEINSTANCE))
1598 && (serviceInstanceId != null && serviceInstanceId.trim().length() > 1)
1599 && (bbInputSetupUtils.getAAIServiceInstanceById(serviceInstanceId) != null));
1602 protected String validateServiceResourceIdInAAI(String generatedResourceId, String instanceName,
1603 RequestDetails reqDetails) throws DuplicateNameException {
1604 String globalCustomerId = reqDetails.getSubscriberInfo().getGlobalSubscriberId();
1605 String serviceType = reqDetails.getRequestParameters().getSubscriptionServiceType();
1606 if (instanceName != null) {
1607 Optional<ServiceInstance> serviceInstanceAAI =
1608 bbInputSetupUtils.getAAIServiceInstanceByName(globalCustomerId, serviceType, instanceName);
1609 if (serviceInstanceAAI.isPresent()) {
1610 if (serviceInstanceAAI.get().getModelVersionId()
1611 .equalsIgnoreCase(reqDetails.getModelInfo().getModelVersionId())) {
1612 return serviceInstanceAAI.get().getServiceInstanceId();
1614 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(NAME_EXISTS_WITH_DIFF_VERSION_ID,
1615 instanceName, reqDetails.getModelInfo().getModelVersionId()));
1618 ServiceInstances aaiServiceInstances =
1619 bbInputSetupUtils.getAAIServiceInstancesGloballyByName(instanceName);
1620 if (aaiServiceInstances != null) {
1621 if (aaiServiceInstances.getServiceInstance() != null
1622 && !aaiServiceInstances.getServiceInstance().isEmpty()) {
1623 if (aaiServiceInstances.getServiceInstance().size() > 1) {
1624 throw new DuplicateNameException(SERVICE_INSTANCE,
1625 String.format(NAME_EXISTS_MULTIPLE, instanceName));
1627 ServiceInstance si = aaiServiceInstances.getServiceInstance().stream().findFirst().get();
1628 Map<String, String> keys =
1629 bbInputSetupUtils.getURIKeysFromServiceInstance(si.getServiceInstanceId());
1631 throw new DuplicateNameException(SERVICE_INSTANCE, String.format(
1632 NAME_EXISTS_WITH_DIFF_COMBINATION, instanceName,
1633 keys.get(AAIFluentTypeBuilder.Types.CUSTOMER.getUriParams().globalCustomerId),
1635 AAIFluentTypeBuilder.Types.SERVICE_SUBSCRIPTION.getUriParams().serviceType),
1636 si.getModelVersionId()));
1642 return generatedResourceId;
1645 protected String validateNetworkResourceIdInAAI(String generatedResourceId, String instanceName,
1646 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds)
1647 throws DuplicateNameException, MultipleObjectsFoundException {
1648 Optional<L3Network> network = bbInputSetupUtils
1649 .getRelatedNetworkByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1650 if (network.isPresent()) {
1651 if (network.get().getModelCustomizationId()
1652 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1653 return network.get().getNetworkId();
1655 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1656 instanceName, network.get().getModelCustomizationId()));
1659 if (bbInputSetupUtils.existsAAINetworksGloballyByName(instanceName)) {
1660 throw new DuplicateNameException("l3Network", String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName,
1661 workflowResourceIds.getServiceInstanceId()));
1663 return generatedResourceId;
1666 protected String validateVnfResourceIdInAAI(String generatedResourceId, String instanceName,
1667 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1668 Optional<GenericVnf> vnf = bbInputSetupUtils
1669 .getRelatedVnfByNameFromServiceInstance(workflowResourceIds.getServiceInstanceId(), instanceName);
1670 if (vnf.isPresent()) {
1671 if (vnf.get().getModelCustomizationId()
1672 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1673 return vnf.get().getVnfId();
1675 throw new DuplicateNameException("generic-vnf", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1676 instanceName, vnf.get().getModelCustomizationId()));
1679 GenericVnfs vnfs = bbInputSetupUtils.getAAIVnfsGloballyByName(instanceName);
1681 throw new DuplicateNameException("generic-vnf",
1682 String.format(NAME_EXISTS_WITH_DIFF_PARENT, instanceName, vnfs.getGenericVnf().get(0).getVnfId()));
1684 return generatedResourceId;
1687 protected String validateVfModuleResourceIdInAAI(String generatedResourceId, String instanceName,
1688 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1689 GenericVnf vnf = bbInputSetupUtils.getAAIGenericVnf(workflowResourceIds.getVnfId());
1690 if (vnf != null && vnf.getVfModules() != null) {
1691 for (org.onap.aai.domain.yang.VfModule vfModule : vnf.getVfModules().getVfModule()) {
1692 if (vfModule.getVfModuleName().equalsIgnoreCase(instanceName)) {
1693 if (vfModule.getModelCustomizationId()
1694 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1695 return vfModule.getVfModuleId();
1697 throw new DuplicateNameException("vfModule",
1698 String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID, instanceName,
1699 reqDetails.getModelInfo().getModelCustomizationId()));
1704 if (bbInputSetupUtils.existsAAIVfModuleGloballyByName(instanceName)) {
1705 throw new DuplicateNameException("vfModule", instanceName);
1707 return generatedResourceId;
1710 protected String validateVolumeGroupResourceIdInAAI(String generatedResourceId, String instanceName,
1711 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1712 Optional<VolumeGroup> volumeGroup =
1713 bbInputSetupUtils.getRelatedVolumeGroupByNameFromVnf(workflowResourceIds.getVnfId(), instanceName);
1714 if (volumeGroup.isPresent()) {
1715 if (volumeGroup.get().getVfModuleModelCustomizationId()
1716 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1717 return volumeGroup.get().getVolumeGroupId();
1719 throw new DuplicateNameException("volumeGroup", volumeGroup.get().getVolumeGroupName());
1722 if (bbInputSetupUtils.existsAAIVolumeGroupGloballyByName(instanceName)) {
1723 throw new DuplicateNameException("volumeGroup", instanceName);
1725 return generatedResourceId;
1728 protected String validateConfigurationResourceIdInAAI(String generatedResourceId, String instanceName,
1729 RequestDetails reqDetails, WorkflowResourceIds workflowResourceIds) throws DuplicateNameException {
1730 Optional<org.onap.aai.domain.yang.Configuration> configuration =
1731 bbInputSetupUtils.getRelatedConfigurationByNameFromServiceInstance(
1732 workflowResourceIds.getServiceInstanceId(), instanceName);
1733 if (configuration.isPresent()) {
1734 if (configuration.get().getModelCustomizationId()
1735 .equalsIgnoreCase(reqDetails.getModelInfo().getModelCustomizationId())) {
1736 return configuration.get().getConfigurationId();
1738 throw new DuplicateNameException("configuration", String.format(NAME_EXISTS_WITH_DIFF_CUSTOMIZATION_ID,
1739 instanceName, configuration.get().getConfigurationId()));
1742 if (bbInputSetupUtils.existsAAIConfigurationGloballyByName(instanceName)) {
1743 throw new DuplicateNameException("configuration", instanceName);
1745 return generatedResourceId;
1748 private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
1749 WorkflowType resourceType) {
1750 execution.setVariable("sentSyncResponse", false);
1751 execution.setVariable("homing", false);
1752 execution.setVariable("calledHoming", false);
1753 execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
1754 execution.setVariable("suppressRollback", suppressRollback);
1755 execution.setVariable("resourceId", resourceId);
1756 execution.setVariable("resourceType", resourceType);
1757 execution.setVariable("resourceName", resourceType.toString());
1760 private Resource getResource(BBInputSetupUtils bbInputSetupUtils, boolean isResume, boolean alaCarte, String uri,
1762 if (!alaCarte && isResume) {
1763 logger.debug("replacing URI {}", uri);
1764 uri = bbInputSetupUtils.loadOriginalInfraActiveRequestById(requestId).getRequestUrl();
1765 logger.debug("for RESUME with original value {}", uri);
1767 return extractResourceIdAndTypeFromUri(uri);
1770 private String getResourceId(Resource resource, String requestAction, RequestDetails requestDetails,
1771 WorkflowResourceIds workflowResourceIds) throws Exception {
1772 if (resource.isGenerated() && requestAction.equalsIgnoreCase("createInstance")
1773 && requestDetails.getRequestInfo().getInstanceName() != null) {
1774 return validateResourceIdInAAI(resource.getResourceId(), resource.getResourceType(),
1775 requestDetails.getRequestInfo().getInstanceName(), requestDetails, workflowResourceIds);
1777 return resource.getResourceId();
1781 private String getServiceInstanceId(DelegateExecution execution, String resourceId, WorkflowType resourceType) {
1782 String serviceInstanceId = (String) execution.getVariable("serviceInstanceId");
1783 if ((serviceInstanceId == null || serviceInstanceId.isEmpty()) && WorkflowType.SERVICE.equals(resourceType)) {
1784 serviceInstanceId = resourceId;
1786 return serviceInstanceId;